Files
justin 9b03bb57a8
CI / test (push) Successful in 17s
CI / build-push (push) Successful in 6s
docs(README): document include_expired on the latest snapshot (#3)
2026-06-08 22:36:18 -04:00

5.1 KiB

ag-bids-mcp

Model Context Protocol server exposing live + historical commodity price data collected by ag-monitor. 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."
  • "How is basis moving overall this week?"
  • "What's the July corn futures price and how far has it moved since the open?"
  • "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, /futures, /best, /inputs, /sources, /deliveries, /price-trend, /price-series, /price-geographies, /input-cost-trend, /input-cost-series, /input-cost-geographies. See the ag-monitor source 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)

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:

{
  "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. 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, zip?, lat?, lng?, radius_miles?) Where to sell corn/soy/wheat for this month's delivery. Optional location (zip or lat/lng + radius_miles, default 50) restricts to nearby elevators and shows distance; out-of-range returns the nearest-source hint
futures_quote(commodity, delivery?) CBOT futures price + change since open + change on the day. With a delivery month it resolves the listed contract; without it, the continuous nearby
current_lime_price() Latest lime quotes across all manual-entry sources
current_input_price(product?) MAP / Potash / Lime — all three or one (local DTN dealer feed)
price_trend(commodity, geo?, years?) USDA NASS monthly price received ($/bu) + MoM/YoY change + seasonal context. geo = US or a state (corn back to 1908)
price_series(commodity, geo?, start_year?, end_year?) Raw monthly price-received series for charting
input_cost_trend(item, geo?, years?) Real input cost + change. item = diesel (U.S. $/gal, weekly, EIA) or a fertilizer $/ton (urea/uan/anhydrous/dap/map/potash, monthly, USDA AgTransport); geo selects the fertilizer region (default Cornbelt)
input_cost_series(item, geo?) Raw historical series for an input cost (diesel $/gal or fertilizer $/ton, region-selectable)
latest_prices(commodity?, source?, delivery?, kind?, zip?, lat?, lng?, radius_miles?, include_expired?) Live snapshot table; every filter optional (kind = grain/fertilizer). Current + future delivery months only by default; pass include_expired=true for past months (use only on an explicit historical request). Location filter (zip or lat/lng + radius_miles) keeps nearby sources, nearest-first, with distance
price_history(commodity?, source?, delivery?, days?) Time series per (elevator, crop, delivery); every filter optional — omit commodity to span all crops. Shows bid + basis trend + futures
basis_movement(commodity?, source?, delivery?, days?) Aggregated basis trend, one headline line per crop (the cheap overview)
basis_detail(commodity?, source?, delivery?, days?) Per-(elevator, crop, delivery) basis first→last drill-down
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

For the full per-release detail (signatures, conventions, example question → call mappings), see CHANGELOG.md.

Grain-marketing prompt library for the downstream Ag Advisor (planning + monitoring, with the tools each prompt uses): examples/ag-advisor-prompts.md.