# ag-bids-mcp Model Context Protocol server exposing live + historical commodity price data collected by [ag-monitor](https://git.jpaul.io/justin/ag-bids). Sits behind the user's MetaMCP gateway at `https://mcp.jpaul.io/metamcp/ag-bids/mcp`. ## What it does Lets an LLM client (Claude Desktop, OpenWebUI, anything that speaks MCP) ask plain-English questions like: - "What's the best place to sell corn today?" - "What's the current price of lime?" - "Show me the corn basis trend at Andersons Greenville over the last 30 days." - "Which sources are stale or failing?" ## How it talks to data All data is read from ag-monitor over HTTPS: ``` ag-bids-mcp ── X-API-Key ─► https://agbids.paul.farm/api/data/* ``` Endpoints used: `/api/data/latest`, `/history`, `/best`, `/inputs`, `/sources`, `/deliveries`. See the [ag-monitor source](https://git.jpaul.io/justin/ag-bids) for the contract. ## Authentication **No in-container auth.** The MCP's port 8000 is never exposed outside the private `mcp-servers_mcp` Docker network on `.0.2`. The only client that can reach it is MetaMCP, and MetaMCP enforces auth at the gateway → client edge (bearer token / OAuth in its UI). This matches the zerto-docs-mcp pattern. ## Local dev (stdio) ```bash python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt cp .env.example .env # fill in AG_BIDS_API_KEY + AG_BIDS_MCP_USER/PASS MCP_TRANSPORT=stdio python -m ag_bids_mcp.server ``` Wire into Claude Desktop's `claude_desktop_config.json`: ```json { "mcpServers": { "ag-bids": { "command": "/path/to/venv/bin/python", "args": ["-m", "ag_bids_mcp.server"], "env": { "MCP_TRANSPORT": "stdio", "AG_BIDS_API_URL": "https://agbids.paul.farm", "AG_BIDS_API_KEY": "..." } } } } ``` ## Deploy (MetaMCP host) See [deploy/README.md](deploy/README.md). Container image is pulled from `git.jpaul.io/justin/ag-bids-mcp:latest`; Watchtower on the MetaMCP host auto-updates it every 5 minutes. ## Tools exposed | Tool | Returns | |---|---| | `best_local_bid(commodity)` | Where to sell `corn`, `soy`, or `wheat` for this month's delivery — markdown one-liner + table | | `current_lime_price()` | Latest lime quotes across all manual-entry sources | | `current_input_price(product?)` | MAP / Potash / Lime — all three or one | | `latest_prices(commodity?, source?, delivery?)` | Snapshot table, optionally filtered | | `price_history(commodity, source?, delivery?, days?)` | Compact time series | | `list_sources()` | Active scrapers + last-success timestamps | | `list_commodities()` | corn, soy, wheat, map, potash, lime | | `list_deliveries(commodity)` | Posted delivery labels, chronological | | `source_health()` | Stale / failing / healthy summary | | `todays_summary()` | Same shape as the morning brief snapshot |