# Deploying `ag-bids-mcp` behind MetaMCP This runs on the **MetaMCP host (192.168.0.2)** alongside `zerto-docs-mcp`. It joins the same `mcp` Docker network so MetaMCP can proxy to it by container DNS name (`http://ag-bids-mcp:8000/mcp`). ## One-time setup (on 192.168.0.2) ### 1. Add env vars Edit `/home/justin/zerto-docs-rag/deploy/.env`: ```ini # Copy this from ag-monitor's .env on 192.168.0.126 (the BRIEF_API_KEY value). # Same key powers /api/data/* and /api/brief/*. AG_BIDS_API_KEY= # Credentials MetaMCP will send to the MCP via Basic auth. Generate two # random values — they're not user-facing, only MetaMCP knows them. AG_BIDS_MCP_USER=agbids-svc AG_BIDS_MCP_PASS= ``` ### 2. Paste the service block into compose Open `/home/justin/zerto-docs-rag/deploy/docker-compose.yml` and append the `ag-bids-mcp:` block from [docker-compose.snippet.yml](docker-compose.snippet.yml) inside `services:`, alongside `zerto-docs-mcp:`. Keep the same indentation (2 spaces). ### 3. Build + push the image On any dev machine with `docker` and the Gitea registry login: ```bash cd ~/github/ag-bids-mcp docker login git.jpaul.io # use your Gitea PAT docker build -t git.jpaul.io/justin/ag-bids-mcp:latest . docker push git.jpaul.io/justin/ag-bids-mcp:latest ``` ### 4. Start the container ```bash cd /home/justin/zerto-docs-rag/deploy docker compose pull ag-bids-mcp docker compose up -d ag-bids-mcp docker compose logs -f ag-bids-mcp # confirm "starting ag-bids MCP on streamable-http://0.0.0.0:8000 (Basic auth enforced)" ``` Watchtower (already running on the host) will auto-pull updates every 5 minutes from this point forward. ### 5. Register the namespace in MetaMCP In the MetaMCP web UI at `https://mcp.jpaul.io`: 1. **Create namespace** → name: `ag-bids` 2. **Add upstream MCP server** to that namespace: - **Transport:** Streamable HTTP - **URL:** `http://ag-bids-mcp:8000/mcp` - **Authentication:** Basic - **Username:** matches `AG_BIDS_MCP_USER` - **Password:** matches `AG_BIDS_MCP_PASS` 3. Save. Public endpoint becomes: **`https://mcp.jpaul.io/metamcp/ag-bids/mcp`** ### 6. Smoke test from the LAN ```bash # 401 without creds curl -i http://192.168.0.2:8000/mcp 2>&1 | head -3 # 200 with creds (Initialize handshake will succeed; the MCP doesn't have # a plain GET, so a curl probe just confirms auth) curl -i -u "$AG_BIDS_MCP_USER:$AG_BIDS_MCP_PASS" http://192.168.0.2:8000/mcp 2>&1 | head -3 ``` Then in a real MCP client (Claude Desktop / OpenWebUI / etc.) configured against `https://mcp.jpaul.io/metamcp/ag-bids/mcp`, try: - **"What's the best place to sell corn today?"** → calls `best_local_bid("corn")` - **"What's the current price of lime?"** → calls `current_lime_price()` - **"Are any sources down?"** → calls `source_health()` ## Rotating credentials To rotate the Basic password: change `AG_BIDS_MCP_PASS` in the `.env` on 192.168.0.2 → `docker compose up -d ag-bids-mcp` to restart with the new value → update the MetaMCP namespace's upstream Basic password to match. To rotate the upstream API key: change `BRIEF_API_KEY` in ag-monitor's `.env` on 192.168.0.126 + restart `api` there, then update `AG_BIDS_API_KEY` on 192.168.0.2 + restart `ag-bids-mcp`. ## Observability - Per-tool-call usage logs: `/home/justin/zerto-docs-rag/deploy/ag-bids-mcp-logs/usage-YYYY-MM-DD.jsonl` - Container stdout: `docker compose logs ag-bids-mcp` - Successful auth → no log line; failed auth → INFO line with the offending path