Tools reference
Tools exposed by the WeatherOptics MCP server, their inputs, what they return, and how the model is expected to use them.
get_impact_forecast Beta
Assess weather risk for one or many places over the next 7 days. The
primary tool. Returns the peak WeatherOptics index per location and when
each peak occurs, with canonical band + verbatim blurb per index. Also
answers "is there wildfire spread risk at/near X?" — a 0–10
wildfire_spread score at the point (opt-in index, with the
active fire's name).
When the model should call it
- The user has a location, address, or list/file of sites/assets/stores/warehouses.
- The user wants to know which are at risk, when bad weather hits, or how severe.
Inputs
locations[]-
Array of
{ label, latitude, longitude },{ label, zip }, or{ label, place }—placeis a free-text name/address resolved server-side via WeatherOptics geocoding (the match is echoed inresolved_place).labelis required — use the asset name/ID from the user's data, echoed back verbatim; never fabricated. indices-
Optional. Comma-separated subset of
flood, road, life_property, disruption, power, wildfire_spread. Defaults to the five standard indices;wildfire_spreadis opt-in (e.g. "is there wildfire spread risk at X?" →wildfire_spread). hours- Optional. Forecast window, 1–168 hours. Defaults to 168 (7 days).
Output
For each location:
overall— worst band across all returned indices.peaks[]— per-index{ index, peak, at, band, blurb, wildfire_name? }.bandis one of low / moderate / high / extreme, computed from the rounded 0–10 value (0–3 low, 4–6 moderate, 7–8 high, 9–10 extreme).wildfire_spreaduses its own cuts, matching the portal: 0–2 low, 3–4 moderate, 5–6 high, 7+ extreme.blurbis the canonical WeatherOptics description for that integer value, served from/impact/blurbs.wildfire_nameis present on thewildfire_spreadpeak only when an active fire's spread reaches the point; a spread peak of 0 with no name means no active fire reaches it (a real zero, not missing data).error— present when this location specifically failed.
Top-level: requested / succeeded / failed counts plus a top-level
warning string when any location errored.
Reliability
- One
/impact/forecast/hourlycall per location (fan-out), with retry+backoff on 429/5xx and concurrency capped at 4. Whenwildfire_spreadis requested, one additional/impact/wildfirecall per location (same retry/concurrency; 144-hour horizon), joined on the hour. - Lat/lon range-validated up front (catches swapped or malformed coordinates).
- If any location fails, the tool result is marked
isError: trueso the failure can't masquerade as low-risk data.
Rules the model must follow
- Use returned
label,band,overall, andblurbvalues verbatim. Never re-derive severity from raw numbers; never reword blurbs. - If any location has an
error, surface it as UNKNOWN — never treat missing data as low risk.
Indices returned
- flood — flooding risk
- road — driving / road-conditions risk
- life_property — danger to life and property
- disruption — business disruption (requires plan entitlement on the token)
- power — power-outage risk
- wildfire_spread — opt-in. Risk that an active fire's spread
reaches the point, with the fire's
wildfire_name. Requires the wildfire permission (a missing grant returns the standard permission-denied message, not an empty result).
temp_seasonality_score
anomaly score, speed_reduction fraction) are deliberately excluded —
mixing scales produced misleading severity bands during prototyping.
get_weather_forecast Beta
Raw WeatherOptics weather variables (temperature, precipitation, wind,
humidity, heat index, etc.) at one or many locations over the next 7 days.
For plain non-risk questions like "will it rain in Chicago Thursday?"
or "how hot next week?". For weather-risk questions (road, flood,
power outage), use get_impact_forecast instead.
Inputs
locations[]- Array of
{ label, latitude, longitude },{ label, zip }, or{ label, place }(free-text name resolved server-side, echoed inresolved_place).labelis required and echoed back verbatim. variables- Optional subset of hourly variables. Default: temperature, heat_index, wind_speed, wind_gust, total_precipitation, rainfall_rate, snowfall_rate, relative_humidity.
hours- Max hourly rows per location (1–336). Defaults to 168 (7 days).
Output
For each location:
hourly[]— one row per hour, filtered to the requested variables. Each row carriestime_iso,local_time_iso, and the numeric/boolean values.daily[]— full daily summaries (temperature_high/low, total_precipitation, average_wind_speed, hours_with_rain/snow/sleet, max_relative_humidity, max_heat_index, etc.). Always returned; small enough to embed.error— present when this specific location failed.
Top-level: requested / succeeded / failed plus a warning string when anything failed. isError: true on any failure.
Backing service
Calls GET /weather/forecast on the WeatherOptics api-server. Requires the Standard Weather API permission on the token.
get_impact_series Beta
Return a rendered time-series chart (as a QuickChart image URL) showing
a WeatherOptics impact index at a single location over the forecast window.
The chat client embeds the returned chart_url as an image
inline; the raw points come along so the model can narrate
specific peaks without re-fetching.
Inputs
location- Single
{ label, latitude, longitude },{ label, zip }, or{ label, place }(resolved server-side, echoed inresolved_place).labelrequired, echoed verbatim. index- One of
flood,road,life_property,disruption,power,wildfire_spread. All 0–10 scale.wildfire_spreadcomes from/impact/wildfire(144-hour horizon; wildfire permission) — a series of zeros means no active fire's spread reaches the point. hours- Forecast window (6–168). Defaults to 168 (7 days).
granularityhourly(default) returns one point per hour.dailycollapses to one point per local calendar day keeping the peak — cleaner for a 5–7 day view.
Output
{ label, series, granularity, chart_url, peak: { value, at }, points: [{ time_iso, local_time_iso, value }, ...] }
Response also carries a second text content block with a markdown image link () — Claude renders it inline; ChatGPT ignores it and charts points natively.
Y-axis is pinned to 0–10 so severity context is consistent across charts. Legend hidden (title carries the label).
get_weather_series Beta
Return a rendered time-series chart (as a QuickChart image URL) showing a raw WeatherOptics weather variable at a single location over the forecast window. Same idea as the impact chart, but for plain values (temperature, precipitation, wind, humidity, etc.).
Inputs
location- Single
{ label, latitude, longitude },{ label, zip }, or{ label, place }(resolved server-side, echoed inresolved_place).labelrequired, echoed verbatim. variable- One of
temperature,heat_index,wind_speed,wind_gust,total_precipitation,rainfall_rate,snowfall_rate,rain_accumulation,snow_accumulation,relative_humidity,visibility. hours- Forecast window (6–168). Defaults to 168 (7 days).
granularityhourly(default) returns one point per hour.dailycollapses to one point per local calendar day keeping the peak — cleaner for a 5–7 day view.
Output
{ label, series, granularity, chart_url, peak: { value, at }, points: [{ time_iso, local_time_iso, value }, ...] }
Response also carries a second text content block with a markdown image link () — Claude renders it inline; ChatGPT ignores it and charts points natively.
Y-axis auto-fits to the data range; axis label includes units.
aggregate_weather_data Beta
One statistic — max, min, avg,
sum, or count — computed server-side over the hourly
forecast at one or many locations, for either a weather variable
or a 0–10 impact index, with an optional conditional filter.
Answers "how much rain at the Chicago yard over the next 48h?",
"peak road risk across my terminals this week?", or
"how many hours below freezing with precipitation at Denver?"
without the model reading 168-row series and doing arithmetic by eye.
Inputs
locations[]- Same shape as
get_weather_forecast:{ label, latitude, longitude },{ label, zip }, or{ label, place }(resolved server-side, echoed inresolved_place).labelis required, echoed verbatim. field- Any hourly weather variable (
temperature,wind_gust,total_precipitation,snow_flag, …) or impact index (road,flood,life_property,disruption,power,wildfire_spread). Rates are per-hour inches (sum for a window total);*_accumulationfields are running totals that reset daily (usemax); flags are 1/0. operatormax/minreturn the value plus the local hour it occurs.sumis meaningful for per-hour rates and flags; on other fields it still returns the arithmetic sum but with a warning.count= hours wherefieldis non-zero / flag true and the filter holds (filter onfielditself → simply the hours matching the filter).hours- Forecast window from now, 1–168. Defaults to 168 (7 days).
filter_field/filter_operator/filter_value- Optional, all three together. Restricts the statistic to hours where the filter field (same as
fieldor any other, weather or impact) islt / lte / gt / gte / eqthe value, in that field's units. Mixing families (weather field, impact filter) is fine — each family is fetched once and joined on the hour.
Output
Per location:
value(+unit) —nullwhen no hour qualified (explained inwarning).at— max/min only: local ISO time (with UTC offset) of the hour holding the value.hours_considered/hours_matching_filter— coverage of the computation.band+blurb— impact fields, max/min/avg only: canonical band for the rounded value and the verbatim/impact/blurbswording.error— present when this specific location failed (including an index the token's plan does not include — the upstream API omits it silently; the tool does not).
Top-level summary — the cross-location roll-up: max/min name the location_label (and at) holding the value; sum and count total across locations; avg pools every qualifying hour. Plus requested / succeeded / failed and a warning string; isError: true whenever any location failed.
Backing service
Reuses the chart tools' series path: GET /weather/forecast for weather variables and GET /impact/forecast/hourly for indices and GET /impact/wildfire for wildfire_spread (one call per location per family, concurrency capped at 4, retry on 429/5xx). Requires the weather, ratings, or wildfire permission — whichever the chosen field needs. Forecast window only; historical aggregation is deferred.
get_rightroute_forecast Beta
Weather-adjusted route forecast via the RightRoute API: travel time, arrival window, expected slowdown percentage, plus per-route weather / impact / temperature narratives and wildfire impact (when the token has the wildfire permission; degrades gracefully with a warning otherwise).
Inputs
origin/destination{ label, latitude, longitude }or{ label, place }— a free-textplacename is resolved server-side via WeatherOptics geocoding and echoed in the point'sresolved_place. Unresolvable names fail loudly (no silent fallback).departure_time- ISO 8601 with timezone, or
"now"(default). Past times are fully supported: departures more than 24h ago automatically use the historical reconstruction (mode: "historical"— wildfire and live alerts are not assessed there; constraints come back in the result'snote). waypoints/vehicle_type- Optional stops in order;
car(default) ortruck. include_route_polyline- Opt-in (default false). Adds
route_polylineto the result: the true route geometry downsampled to ≤200 points with per-point worst-hazard values — made to be passed straight intoget_tile_mapto render the route, hazard-colored, over a weather layer. Request it only when the user wants a map/visual of the route.
Output
hazard_callouts[] lifts elevated risk indices along the route
(wildfire spread/conditions, flood, road, …) to the top level with canonical
blurbs — a 0% slowdown does not mean no weather risk; an
active wildfire near the route appears only here.
overall_hazard_level is the canonical severity of the whole trip
(computed server-side from the worst callout); official_guidance
(moderate+ only) names official sources to also consult; and
presentation_guidance carries per-result reporting notes for these
fields. The full RightRoute response is under raw.
get_severe_events_near Beta
Severe weather near a location: SevereCast (next-hour hail / tornado /
damaging-wind cells, CONUS-only), storms + cyclones (hurricanes, winter
storms, days out), live lightning, active US wildfire incidents, and
official government weather alerts (US NWS + Canada + Mexico
pass-through). Incidents and alerts only — it has no 0–10 spread score;
"is there wildfire spread risk at X?" is
get_impact_forecast with indices wildfire_spread.
Inputs
location{ label, latitude, longitude }or{ label, place }(resolved server-side; zip is not accepted by the events feed).radius_miles- Optional. With a radius, events intersecting the surrounding box are returned; without, only events covering the exact point.
event_types- Defaults to
severe_cast, storms, cyclones, nws_alerts. Addlightning,storm_reports, orus_wildfires(active US wildfire incidents) explicitly.
Output
Events normalized to { source, event_type, severity, headline, starts_at,
ends_at, distance_miles, properties }, sorted closest-first, capped at the
50 closest (with a loud warning listing the total). Requires the
events and weather_alerts permissions for full coverage.
get_tile_map Beta
Render a map image of a WeatherOptics tile layer (road, flood, wind, radar, …) or the polygon-only wildfire layer over a location, region, or route. Composited server-side (Google basemap + WO overlay) by the tile server; in MCP Apps-capable clients (ChatGPT developer mode) the map renders inline in the chat.
Inputs
location+radius_miles{ label, latitude, longitude }or{ label, place }(resolved server-side) with a 1–500 mi radius (default 40).bbox- Named
{ west, south, east, north }for state/CONUS-scale views. route_polyline- The array from
get_rightroute_forecast(include_route_polyline: true), passed unchanged: auto-frames the map and draws the route hazard-colored (canonical band colors) with origin/destination markers. Colors reflect conditions at the time the driver reaches each point. Route maps show basemap + route only — no weather tile layer (layer/animateare ignored), since a fixed-hour layer under a multi-hour drive misrepresents timing. animate- Forecast layers animate the next 96h.
radaris observed data and loops the past 30 minutes; there is no future radar layer. layer: wildfire- Polygons, not tiles — there is no wildfire raster (both the
wildfire_spreadandwildfire_conditionstilesets are deprecated and are never requested). Basemap + active fire boundaries (NIFC perimeters: name, acres, percent contained, updated time) + the current wildfire-spread polygons (the v2 product, one ring per 0–10 spread level around each fire), from oneGET /events/current?event_types=us_wildfires,us_wildfire_spreadscall for the map's bbox. The polygons are widget-only: they travel in the tool result's_meta(_meta.overlays, one GeoJSON FeatureCollection at full NIFC fidelity, coordinates rounded to 5 dp; each feature'skindisboundaryorspread, and each keeps the feed's canonicalfill/fill-opacity/stroke, which the widget draws from — the same props the portal renders;_meta.overlay_palette.wildfire_spreadis the canonical 0–10 palette from/impact/blurbsfor the legend). MCP Apps hosts forward_metato the map iframe but keep it out of the model's context, so a 360 KB perimeter never enters the conversation. What the model sees isfires— one row per fire withname,acres,percent_contained,updated_isoandmax_spread_index(the highest 0–10 ring present) — plus the names innote. At most 30 polygons per kind (highest spread index / largest fires kept) with awarningwhen truncated; the layer is always interactive (the widget auto-frames the view to the fire polygons; the requested radius/bbox is the framing only when there are none), andimage_urlis empty (no static fallback). Requires the wildfire_tiles permission (the feed's gate). For the per-point 0–10 score useget_impact_forecastwithwildfire_spread.
image_url embeds the caller's token — treat it as
sensitive.
find_coordinates_for_place Beta
Look up candidate coordinates for a place name, address, city, or landmark (e.g. "Richmond, VA" or "1600 Pennsylvania Ave"). Wraps the existing WeatherOptics geocoding service.
When the model should call it
- You only have a free-text place description and don't already have reliable coordinates.
- Call this before
get_impact_forecast, pick the best match, and pass{label, latitude, longitude}into the forecast tool. - If multiple matches look plausible, ask the user to confirm rather than guessing.
Inputs
query- The place name, address, city, or landmark to look up.
Output
{
"query": "Richmond, VA",
"matches": [
{ "name": "Richmond, VA, USA", "latitude": 37.5407, "longitude": -77.4360 }
]
}
Backing service
Calls POST /geocoding/location_suggestions on the WeatherOptics
api-server (the same endpoint the business portal uses for address
autocomplete). Same per-request token auth as the rest of the MCP. No
third-party provider configuration needed.
alternate_permission.
search_locations Beta
Search the user's saved locations in WeatherOptics (their "locations"
list — the same set that powers the portal). Each record carries lat/lon ready
to feed into get_impact_forecast.
When the model should call it
- User asks about their places — "my Chicago locations", "my locations in Texas", or just "my locations".
Inputs
query- Optional case-insensitive substring filter on the record name. Omit to list the most recently created.
limit- Max records to return (1–50). Defaults to 25.
Output
{
"query": "Chicago",
"count": 1,
"records": [
{ "id": 42, "name": "Chicago Depot", "latitude": 41.88, "longitude": -87.63,
"group_ids": [3, 7] }
]
}
Backing service
Calls GET /cities.json on the WeatherOptics api-server. Pagination via limit; results filtered server-side when query is set.
search_vehicles Beta
Search the user's vehicles / fleet assets in WeatherOptics. Each record carries
the vehicle's current lat/lon ready to feed into get_impact_forecast.
alternate_permission change lands.
When the model should call it
- User asks about their trucks/fleet — "my fleet", "my Dallas trucks", "vehicle V-103".
Inputs
query- Optional. Server-side filter on the vehicle's
external_id. Omit to list the most recently created vehicles. limit- Max records to return (1–50). Defaults to 25.
Output
{
"query": "V-103",
"count": 1,
"records": [
{ "id": 18, "name": "Truck 103", "external_id": "V-103",
"latitude": 32.78, "longitude": -96.79, "group_ids": [9] }
]
}
Backing service
Calls GET /vehicles.json on the WeatherOptics api-server.
search_routes Beta
Search the user's saved routes and recurring lanes in WeatherOptics (the
routes list that powers RightRoute in the portal). Each record carries
origin/destination labels + coordinates and the scheduled
departure_time — everything a follow-up
get_rightroute_forecast call needs.
routes:read) permission on the
connection; without it the tool returns the standard in-band
permission-denied message rather than an empty list.
When the model should call it
- User asks about their routes/lanes/loads — "my routes", "my Dallas to Memphis lane", "route R-1042", "my load LOAD-1001", "which of my routes leave tomorrow?". A saved route named by the user is looked up here first so the forecast uses its stored origin/destination/waypoints/departure.
- NOT for conditions or delays on a route — that's
get_rightroute_forecast, fed with the coordinates this tool returns. - NOT for saved point locations (
search_locations) or vehicles (search_vehicles).
Inputs
query- Optional case-insensitive filter matched against route name, origin/destination labels, and
external_id. Omit to list the most recently created routes. limit- Max routes to return (1–50). Defaults to 25.
Output
{
"query": "memphis",
"count": 1,
"routes": [
{ "id": 9021, "name": "Dallas → Memphis",
"origin": { "label": "Dallas Yard", "latitude": 32.78, "longitude": -96.79 },
"destination": { "label": "Memphis DC", "latitude": 35.15, "longitude": -90.05 },
"departure_time": "2026-09-02T13:00:00.000Z",
"status": "unstarted", "vehicle_id": 18, "vehicle_type": "truck",
"recurring_cron": "0 8 * * 1", "group_ids": [4] }
]
}
A warning field is set when the result may be incomplete —
more routes matched than limit allows, or the search did not
cover every saved route (see below).
Backing service
Calls GET /routes.json on the WeatherOptics api-server with
exclude=latest_rightroute_response, so the heavy RightRoute
response blobs never leave the server — this tool returns route identity and
schedule only. Until the api-server exposes a query param on
the routes index (api-server #398), the filter is applied by the MCP server
over the 200 most recently created routes, and a warning flags
when that window may have missed older matches.