chore(opax-mcp): document public MCP deployment

This commit is contained in:
Chris Christiansen 2026-09-05 18:42:52 +00:00
parent 14d61b131f
commit 592944041f
7 changed files with 51 additions and 3 deletions

9
.dockerignore Normal file
View File

@ -0,0 +1,9 @@
spire-1.15.3/data
.venv
.venv-flake8
__pycache__
*.pyc
*.pyo
*.pyd
.pytest_cache
.coverage

8
.gitignore vendored
View File

@ -11,6 +11,14 @@ dist/
# Virtual environments # Virtual environments
.venv/ .venv/
.venv-flake8/
opax-mcp/tmp_venv/
spire-1.15.3/
__pycache__/
*.py[cod]
.env.*
erver.py fix
h to use --no-cache and correct secret mount
venv/ venv/
env/ env/
.env .env

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV PORT=8080
ENV PYTHONUNBUFFERED=1
EXPOSE 8080
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

7
cloudbuild.opax-mcp.yaml Normal file
View File

@ -0,0 +1,7 @@
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest', './opax-mcp']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest']
images:
- 'us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest'

View File

@ -18,7 +18,7 @@ echo "=== 3. Push image ==="
docker push "${FULL_IMAGE}" docker push "${FULL_IMAGE}"
echo "=== 4. Deploy with pre-built image ===" echo "=== 4. Deploy with pre-built image ==="
gcloud run deploy "${SERVICE}" --image="${FULL_IMAGE}" --region="${REGION}" --service-account="jason-vauger@${PROJECT}.iam.gserviceaccount.com" --set-secrets="MCPSECRET=mcp-server-key:latest" --no-allow-unauthenticated --port=8080 --memory=512Mi --cpu=1 --min-instances=0 --max-instances=2 --quiet gcloud run deploy "${SERVICE}" --image="${FULL_IMAGE}" --region="${REGION}" --service-account="jason-vauger@${PROJECT}.iam.gserviceaccount.com" --set-secrets="MCPSECRET=mcp-server-key:latest" --allow-unauthenticated --port=8080 --memory=512Mi --cpu=1 --min-instances=0 --max-instances=2 --quiet
echo "=== 5. Verify ===" echo "=== 5. Verify ==="
SVC_URL=$(gcloud run services describe "${SERVICE}" --region="${REGION}" --format='value(status.url)') SVC_URL=$(gcloud run services describe "${SERVICE}" --region="${REGION}" --format='value(status.url)')

View File

@ -76,6 +76,11 @@ spec:
secretKeyRef: secretKeyRef:
key: latest key: latest
name: TWILIO_FROM_NUMBER name: TWILIO_FROM_NUMBER
- name: MCPSECRET
valueFrom:
secretKeyRef:
key: latest
name: mcp-server-key
image: us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest image: us-central1-docker.pkg.dev/propane-will-491900-m5/osvauco-repo/opax-mcp:latest
name: opax-mcp-1 name: opax-mcp-1
ports: ports:

View File

@ -66,6 +66,12 @@ logger.info(f"OLLAMA_BASE_URL: {OLLAMA_BASE_URL}")
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
async def _verify_auth(request: Request) -> None: async def _verify_auth(request: Request) -> None:
logger.info(
"MCP auth attempt: has_api_key=%s has_x_mcp_secret=%s has_bearer=%s",
bool(request.headers.get("api-key")),
bool(request.headers.get("X-MCP-Secret")),
request.headers.get("Authorization", "").startswith("Bearer "),
)
secret = os.getenv("MCPSECRET") or os.getenv("MCP_SECRET", "") secret = os.getenv("MCPSECRET") or os.getenv("MCP_SECRET", "")
secret = secret.strip() secret = secret.strip()
if not secret: if not secret:
@ -81,8 +87,6 @@ async def _verify_auth(request: Request) -> None:
if auth_header.startswith("Bearer "): if auth_header.startswith("Bearer "):
token = auth_header[7:] token = auth_header[7:]
print(f"DEBUG: token={repr(token)} secret={repr(secret)} match={token==secret if token and secret else False}")
if not token or token != secret: if not token or token != secret:
raise HTTPException(status_code=401, detail="Invalid or missing API key") raise HTTPException(status_code=401, detail="Invalid or missing API key")
def _agent_headers() -> dict: def _agent_headers() -> dict: