Files
ag-bids-mcp/deploy
justin 875a190983 Initial commit: ag-bids MCP server
Exposes live + historical ag-bids commodity data (from the ag-monitor
service at agbids.paul.farm) as MCP tools, sitting behind MetaMCP at
https://mcp.jpaul.io/metamcp/ag-bids/mcp.

Pattern mirrors zerto-docs-rag with one addition: HTTP Basic auth in
front of the streamable-HTTP transport so namespace guessers can't reach
the tools. Stdio transport is unaffected (used by local Claude Desktop
dev).

Tools (markdown returns, ~15 LOC each):
  best_local_bid(commodity)       — where to sell corn/soy/wheat today,
                                    for the current calendar month only
  current_lime_price()            — latest lime quotes ($/ton)
  current_input_price(product?)   — MAP / Potash / Lime
  latest_prices(...)              — filtered snapshot
  price_history(...)              — per-(source,delivery) trend
  list_sources / list_commodities / list_deliveries
  source_health()                 — healthy / stale / down buckets
  todays_summary()                — same shape as morning brief snapshot

Data path: ag-bids-mcp -> X-API-Key -> /api/data/* on ag-monitor
(reuses BRIEF_API_KEY).

Tests: 24 covering the httpx client, markdown formatters, HTTP Basic
middleware (401/200), and JSONL usage logging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:37:46 -04:00
..
2026-05-20 11:37:46 -04:00

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:

# 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=<paste>

# 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=<generate: python -c "import secrets; print(secrets.token_urlsafe(32))">

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 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:

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

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

# 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