New futures_quote(commodity, delivery?) tool wraps the new /api/data/futures endpoint: reports latest price, today's session open, prior settle, and both moves (since open and on the day). With a delivery month it resolves the listed contract; without it, the continuous nearby. Adds client.futures(), fmt_futures(), tests, and a CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
Changelog
Notes for clients/agents that consume the ag-bids MCP tools and the underlying
ag-monitor /api/data/* HTTP API. Newest first.
2026-05-29 — Futures price + change tool
New MCP tool
futures_quote(commodity, delivery?)— CBOT futures price and change for a grain. Reports the latest price, today's session open, the prior day's close, and both moves: change since open and change on the day (vs the previous settle). Withdelivery(e.g."Jul 2026") it resolves the listed contract that month prices against (e.g.ZCN26); without it, the continuous nearby.
API changes (ag-monitor)
GET /api/data/futures?commodity=<grain>&delivery=<label?>— new endpoint. Returns{ commodity, delivery, contract, symbol, quote }wherequoteis{ settle_date, open_cents, last_cents, prev_close_cents, change_since_open_cents, change_on_day_cents, fetched_at }(ornullif no data yet for that contract).commoditymust becorn/soy/wheat.futures_quotestable gained anopen_centscolumn; the futures scraper now stores the session Open alongside the close. Rows captured before this change haveopen_cents = NULL, sochange_since_open_centsisnullfor those until the next session is scraped.- Futures now also pull at :30 during the CBOT day session (on top of the
hourly :00), so
lastand the changes track the session every ~30 min.
Example questions → tool calls
| Ask | Call |
|---|---|
| Corn Jul futures and how far it's moved today | futures_quote(commodity="corn", delivery="Jul 2026") |
| Soy nearby futures, change on the day | futures_quote(commodity="soy") |
2026-05-29 — Flexible history + basis movement
New MCP tools
-
basis_movement(commodity?, source?, delivery?, days=30)— aggregated basis trend, one headline line per crop. Averages every matching (elevator × delivery) series toavg basis first → lastover the window and reports how far it moved. This is the cheap "how is basis moving overall" view. All filters optional;commodity(if given) must becorn/soy/wheat.- Positive move = cash strengthened vs futures (basis up); negative = weaker.
- Aggregation is intentional: divergent elevators can net to "flat". When the
aggregate looks flat or surprising, call
basis_detailto see per-elevator splits.
-
basis_detail(commodity?, source?, delivery?, days=30)— the drill-down forbasis_movement. One row per (elevator, crop, delivery) series with basisfirst → lastand the move. Same optional filters.
Both tools do the aggregation server-side (in the MCP) and return compact
markdown — they do not dump every raw sample — to keep token usage low. Pattern:
call basis_movement first, then basis_detail (optionally filtered) only when
you need the breakdown.
Changed MCP tools
-
price_history—commodityis now optional (was required). Omit it to span every crop. Output now groups by (elevator, crop, delivery), surfaces basis first → last in each series summary, and adds a Futures column to the raw points table. Every filter (commodity,source,delivery,days) is optional and AND'd — pivot per elevator, per crop, per delivery, or any combination.- Raw per-row points are still only included when the window has ≤ ~60 samples; wider queries return the per-series summaries only.
-
latest_prices— added thekindfilter (grain|fertilizer) for parity with the API.commodity,source,delivery,kindall optional.
API changes (ag-monitor)
GET /api/data/history—commodityquery param is now optional. When omitted, returns history across all crops.source_id,delivery, anddays(1–730, default 30) remain optional. Response shape is unchanged:{ "commodity": <str|null>, "days": <int>, "rows": [...] }. Each row carriesfetched_at, source_id, source_name, commodity, delivery, bid_cents, basis_cents, futures_centsso callers can pivot client-side.GET /api/data/latestalready supported optionalcommodity,source,delivery,kind— unchanged.
Conventions / gotchas
- All money fields are integer cents.
bid_cents/futures_centsrender as$/bu(4 dp) for grain and$/ton(2 dp) for fertilizer;basis_centsrenders as a signed dollar value (2 dp), e.g.-0.14. - Basis is only meaningful for grain — the basis tools skip non-grain rows and any series with no basis on file.
sourcefiltering is by exact elevator display name (e.g."Mercer Landmark — Minster"). Uselist_sourcesto get exact names.
Example questions → tool calls
| Ask | Call |
|---|---|
| Basis movement overall, last 7 days | basis_movement(days=7) |
| Corn basis movement across all elevators | basis_movement(commodity="corn") |
| Basis movement at one elevator | basis_movement(source="Mercer Landmark — Minster") |
| Per-elevator basis breakdown for corn | basis_detail(commodity="corn") |
| Last 7 days of history from elevator X for corn | price_history(commodity="corn", source="…", days=7) |
| All-crop price history at one elevator | price_history(source="…") |
| Latest grain bids only | latest_prices(kind="grain") |