Real input price + WoW/YoY change + seasonal for diesel ($/gal). Formatters now handle the item/label payload shape. Changelog updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.6 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-30 — Grain price-received trends (real $ + change + seasonal)
New national/seasonal reference layer (USDA NASS, corn back to 1908) — the macro benchmark to compare local cash bids against. Real prices and the change, not an index.
New MCP tools
price_trend(commodity, geo="US", years=10)— monthly price received by farmers ($/bu) with the move: latest real price, month-over-month and year-over-year change ($ and %), and seasonal context (percentile vs the same month over the last N years, normal, and range).geoisUSor any 2-letter state. Conclusions, not rows.price_series(commodity, geo="US", start_year?, end_year?)— raw monthly series ($/bu) for charting/drill-down (defaults to the recent window).
API
GET /api/data/price-trend?commodity=&geo=&years=— computed trend (cents +change_cents/change_pct/yoy_*+seasonal).GET /api/data/price-series?commodity=&geo=&start_year=&end_year=— raw series.GET /api/data/price-geographies?commodity=— which geos (US + states) exist.
All grain: corn/soy/wheat, all 50 states + US.
Input-cost tools (real $ + change)
input_cost_trend(item, years=10)— real input price with the move. Currentlyitem="diesel"(EIA U.S. retail $/gal, weekly, back to 1994): latest price + week-over-week and year-over-year change + seasonal percentile/range. (For current fertilizer $/ton,current_input_price(DTN) still applies; more inputs extend this same tool.)input_cost_series(item)— raw historical series for an input.- API:
GET /api/data/input-cost-trend?item=&years=,GET /api/data/input-cost-series?item=.
USDA stopped publishing dollar input prices in 2014, so these use real-dollar sources (EIA) rather than an index.
2026-05-30 — Source geo + many more locations
Per-source geo (API + MCP)
GET /api/data/sourcesnow returns location geo on every source:city, state, zip, county, latitude, longitude(any may benull). The AgriCharts-fed elevators carry exact coordinates; smaller sites carry city/state/zip.- MCP
list_sourcesgained a Location column (City, ST ZIP).source_healthis unchanged in shape. - Sources that are national or non-physical (CBOT futures, USDA AMS, DTN
fertilizer, hedge-to-arrive / "Direct" bid buckets) legitimately have
nullgeo. ~43 of ~51 sources are geo-tagged.
Many more elevator locations
These flow through every data tool/endpoint automatically (latest, history,
best, basis_movement/basis_detail, sources, deliveries). No tool
signatures changed — just far more sources, all named "<Co-op> — <Location>":
- Heritage Cooperative — new co-op, 23 central/eastern-Ohio locations (corn/soy/wheat).
- Mercer Landmark — expanded from 2 to all ~16 locations. Note: the two
old source names were renamed for continuity —
"Mercer Landmark — St Henry"→"Mercer Landmark — MPS St Henry","Mercer Landmark — Minster"→"Mercer Landmark — Heartland Minster". - Bambauer — now both locations incl. Pemberton
(
"Bambauer — Jackson Center / New Knoxville","Bambauer — Pemberton"); the old"Bambauer Jackson Center / New Knoxville, OH"source was renamed to the first of those.
If you cache source names, refresh them — several changed and many were added.
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") |