Skip to content
Docs navigation

Tool Reference

All 36 tools of the SmarterWeather MCP Server, in 11 toolsets.

The root (https://mcp.smarterweather.com) serves core + catalog (14 tools). /x/{ids} takes a comma list of toolset ids (keep the root's to widen it, for example /x/core,catalog,planning), and /x/all serves all 36; see Connecting a toolset. Full JSON Schemas, output schemas included: /.well-known/mcp-tools.json.

Tools that take view default to concise; each tool's view row says what detailed adds (detail_level is its deprecated alias). Credits are per call with an API key. Without a key, the tools marked free without a key cost nothing and every other call pays per call with x402.

core start here

On the root (/), and on every /x path that keeps the root

search_locationscore1 credit per call with an API key; free without a key

Resolve a place to ranked candidates with lat/lon: city ("Denver"), "city, ST", ZIP ("50219"), or partial input with fuzzy=true ("bost" -> Boston); venues and addresses where enabled. Rows carry type place|zip|address|poi; pass a row's lat/lon to weather tools. matched_via: "autosuggest" marks rows found after the exact match missed; partial means a section timed out. Weather tools take location directly, venues included -- use this to disambiguate ("which Springfield?") or present choices.

ParameterTypeRequiredDescription
querystring 1-200 charsYesPlace query: city, "city, state", ZIP, partial text, or venue/address where enabled.
fuzzyboolean, default falseNoAutosuggest mode for partial/misspelled input. Default false (exact search).
limitinteger 1-10, default 5NoMaximum candidates to return (1-10). Default 5.
near_latnumber -90 to 90NoRank venues/addresses near this point; pair with near_lon.
near_lonnumber -180 to 180No

Returns: query, candidates, partial

Input examples

{
  "query": "Springfield"
}
{
  "query": "bost",
  "fuzzy": true,
  "limit": 3
}
{
  "query": "50219"
}
get_forecastcore1 credit per call with an API key

Complete weather overview for a location: current conditions, daily forecast (SPC threats, severity; view "detailed" adds CAPE, UV, full day/night periods), active alerts, and outlooks in one call. Pre-aggregated across NBM, HRRR, GFS, RTMA, and SPC and unit-converted server-side. Primary weather tool; reach for lower-level tools only when you need raw observations or a specific dataset. Times are UTC ISO 8601; quote daily[].astro.local to users, not UTC. If forecast.location.timezone_resolved is false, zone unknown: state times as UTC, never as local. Accepts a place name directly. Examples: {"location": "Denver"} or {"location": "Portland, OR", "days": 5} or {"lat": 41.4, "lon": -92.9}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
daysinteger 1-14, default 10NoNumber of forecast days (1-14). Default 10.
units"imperial" | "metric" | "si", default "imperial"NoUnit system for all values in the request and response: imperial (°F, mph, inches), metric (°C, km/h, mm), or si (K, m/s, mm). Defaults to imperial.
includestring, default "current,daily,alerts,outlooks"NoComma-separated sections: current, daily, hourly, alerts, outlooks. Default "current,daily,alerts,outlooks". Use get_hourly_forecast for hourly detail.
view"concise" | "detailed"Noconcise (default; REST's is detailed), ~5-10KB: daily has day_precip_probability / night_precip_probability (precip_probability is their max). detailed, ~12-20KB: adds CAPE, UV, full day/night periods, extra hourly fields.
detail_level"standard" | "detailed"NoDeprecated alias of view.

One of: location, or lat + lon

Returns: location, units, forecast, data_status, widget

get_hourly_forecastcore1 credit per call with an API key

Blended hourly forecast: temperature, feels-like, humidity, wind, precipitation probability/amount, conditions, and icon per hour. Snapped to the current hour so hourly[0] is "now". Timestamps are UTC ISO 8601; convert to the local timezone before presenting. Ask for the days you need up front -- one call with days: 4 beats four calls. ALWAYS check hourly_coverage before answering about a specific hour: it reports first_time and last_time (the window the rows actually span), sample_interval_hours (past the first day rows are every 2-3h, not every hour), and truncated: true when upstream returned less than you asked for. If the hour the user cares about is after last_time, say the forecast does not reach that far yet rather than answering from the nearest row you do have. For one stretch of time ask for that stretch with hours_from/hours_to: it comes back hour by hour even where the full range would be sampled. Accepts a place name or coordinates. Examples: {"location": "Portland, OR", "days": 2} or {"lat": 41.88, "lon": -87.63, "hours_from": 36, "hours_to": 48}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
daysinteger 1-7, default 2NoDays of hourly data (1-7). Default 2. Widened when hours_to reaches further.
hours_frominteger 0-168NoWindow start, in hours from now (0 = the current hour).
hours_tointeger 1-168NoWindow end, in hours from now, exclusive. 36 to 48 is hours 36-47.
units"imperial" | "metric" | "si", default "imperial"NoUnit system for all values in the request and response: imperial (°F, mph, inches), metric (°C, km/h, mm), or si (K, m/s, mm). Defaults to imperial.
view"concise" | "detailed"Noconcise (default) samples past 24h; detailed adds CAPE, ceiling, UV, gust and thunderstorm probability for 48h.
detail_level"standard" | "detailed"NoDeprecated alias of view.

One of: location, or lat + lon

Returns: location, units, forecast, data_status, widget

get_current_conditionscore1 credit per call with an API key

Current weather right now at a location from two independent sources in one call: the RTMA gridded analysis (exact-point values, updated sub-hourly) and the nearest METAR station observation (ground truth with raw METAR, flight category). Use the analysis for point-accurate values and the station for verification. Analysis fields: temperature_2m, dew_point_2m, relative_humidity_2m (derived here from temperature and dew point; listed in analysis.derived), wind_speed_10m, wind_direction_10m, wind_gusts_10m, surface_pressure (station pressure at ground level, not sea-level pressure), visibility, cloud_cover, cloud_ceiling. Analysis values are SI by default; pass units "imperial" or "metric" to convert them (labels in analysis.unit_labels; get_forecast defaults to imperial). nearest_station is the station's own report, unconverted. For a forecast, use get_forecast. Example: {"location": "Pella, IA"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
units"imperial" | "metric" | "si", default "si"NoUnit system for the analysis values: si (default; K, m/s, Pa, m, as RTMA serves them), imperial (°F, mph, inHg, mi, ft) or metric (°C, km/h, hPa, km, m). Unlike get_forecast, which defaults to imperial. Does not apply to nearest_station.

One of: location, or lat + lon

Returns: location, units, analysis, nearest_station

get_alertscore1 credit per call with an API key

NWS watches, warnings, advisories. Point (city/ZIP/lat+lon): containing polygons. BBox or US state/DC/CONUS (codes, full names, US/national): intersecting polygons. A city miss is not a statewide all-clear — query the state or a bbox; never say regional inventory is impossible. NY/WA and "New York State"/"Washington State" are states; "New York"/"Washington" stay cities. Omit at for now; at (ISO-8601 UTC) is the snapshot then. Empty = all-clear or purged (~24h). alert_id = detail+geometry, ignores at. Ex: {"location":"WI","events":["Tornado Warning"]}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
bboxobjectNoBounding box {west,south,east,north}. Skips geocoding; intersecting polygons.
bbox.westnumber -180 to 180YesWestern edge, longitude in decimal degrees.
bbox.southnumber -90 to 90YesSouthern edge, latitude in decimal degrees.
bbox.eastnumber -180 to 180YesEastern edge, longitude in decimal degrees.
bbox.northnumber -90 to 90YesNorthern edge, latitude in decimal degrees.
eventsstring[]NoOptional event-name filter, e.g. ["Tornado Warning"].
alert_idstringNoAlert identifier for detail mode. When set, location is ignored.
atstringNoISO-8601 UTC past instant for the in-effect snapshot. Ignored with alert_id.

One of: location, or lat + lon, or bbox, or alert_id

Returns: location, alert_id, alerts, alert, valid_time, widget

get_observed_precipitationcore1 credit per call with an API key

How much rain fell: observed precipitation totals at a location. Use for "did it rain", "how much rain fell", "rain in the last 24 hours / since yesterday". Source: MRMS MultiSensor QPE Pass2 (radar bias-corrected to rain gauges) over 1/3/6/24/48/72 h windows (CONUS; 1 h only in Alaska and Hawaii). Values have about 2 mm (0.08 in) resolution, so 0 means under about 1 mm; data runs about an hour behind real time. Pass at (within 33 h) for totals ending at a past time (newest frame up to 3 h before it). With include_nowcast (default) it also returns a next-hour radar nowcast (CONUS): peak intensity (light/moderate/heavy), type and start time, not an amount. Forecast totals past the next hour: get_period_totals (planning); station reports: get_observations (observed).

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
windows("1h" | "3h" | "6h" | "24h" | "48h" | "72h")[], 1-6 items, default ["1h","24h"]NoAccumulation windows ending at the latest frame (or at at).
units"imperial" | "metric" | "si", default "imperial"NoUnit system for all values in the request and response: imperial (°F, mph, inches), metric (°C, km/h, mm), or si (K, m/s, mm). Defaults to imperial.
atstring (date-time)NoRFC3339 end time within the last 33 h. Default: latest.
include_nowcastboolean, default trueNoNext-hour radar nowcast (CONUS; ignored with at).

One of: location, or lat + lon

Returns: location, units, as_of, windows, quantization_step, nowcast, derived, notes, _sources, data_status

Input examples

{
  "location": "Chicago, IL",
  "windows": [
    "24h"
  ]
}
{
  "lat": 41.89,
  "lon": -87.65,
  "windows": [
    "1h",
    "6h"
  ],
  "at": "2026-09-30T12:00:00Z"
}
get_forecast_distributioncore1.5 credits per call with an API key

NBM probabilistic guidance for one weather aspect: percentiles (p10-p90), exceedance probabilities and ensemble spread. Use this for any question about odds, ranges, potential or confidence ("how much could we get", "range of possible highs", "how sure is this") -- a deterministic forecast value cannot answer one. Reading the percentiles: p50 is the most likely outcome, p90 is the reasonable worst case when the risk is the high end (snow totals, wind, rainfall), and p10 when the risk is the low end (cold, visibility, ceiling). A single percentile is not the forecast -- report the likely value with the tail that matters, and label which is which. Aspects: precip (PoP, QPF + percentiles), snow (accumulation percentiles, >1/2/4in probabilities, snow level, snow-type probability), ice (ice accretion, freezing-rain / ice-pellet probabilities), temperature (daily high/low p10/p50/p90: the NBM value -/+ 1.28 stddev; hourly temp + stddev), wind (speed/gust percentiles), severe (thunderstorm probability plus NBM CWASP, a severe-environment index, both in percent: severe_weather_prob_p50 is the median CWASP value and severe_weather_prob_above_75 the probability CWASP exceeds 75; NBM has no tornado, hail or damaging-wind odds; SPC's: get_outlooks (guidance) hazard=severe), aviation (LIFR/IFR/MVFR visibility + ceiling odds), confidence (ensemble stddev; low = settled, high = details still in play). Labels in unit_labels. Example: {"location": "Denver", "aspect": "snow", "hours": 72}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
aspect"precip" | "snow" | "ice" | "temperature" | "wind" | "severe" | "aviation" | "confidence"YesDistribution family (see description).
hoursinteger 1-264NoForecast hours; default 48-72 by aspect.
units"imperial" | "metric" | "si", default "imperial"Noimperial (default: °F, mph, in), metric, or si (NBM native: K, m/s, mm).

One of: location, or lat + lon

Returns: location, aspect, hours, units, series, daily

search_catalogcoreFree

Find which dataset answers a weather question when no dedicated tool fits: ranks the data catalog (model grids, radar, satellite, outlooks, observations) by the question's words and returns the best datasets with variable, units, cadence, a one-line why and the exact call (tool and arguments) to run next. Pass lat/lon, or domain, to keep only datasets covering the place; without one, Alaska/Hawaii twins fold into the CONUS dataset. Calls are ready for "now"; for a past time set time_start/time_end (or at where the tool supports it). Free; no network call.

ParameterTypeRequiredDescription
querystring 2-200 charsYesThe question or keywords, in the user's words.
latnumber -90 to 90NoLatitude of the place (with lon).
lonnumber -180 to 180NoLongitude of the place (with lat).
domain"conus" | "alaska" | "hawaii" | "carib" | "global"NoCoverage filter when there is no point; not with lat/lon.
kind"grid" | "snapshot" | "feature" | "text"NoOnly this dataset kind.
familystring <= 40 charsNoOnly this source family (e.g. "nbm", "mrms").
limitinteger 1-10, default 5NoHits to return (1-10, default 5).

Returns: query, domain, note, hits

Input examples

{
  "query": "how much rain fell in the last day",
  "lat": 39.74,
  "lon": -104.99,
  "limit": 3
}

catalog raw data, freshness

On the root (/), and on every /x path that keeps the root

list_datasetscatalogFree

Discover the datasets (model grids, analyses, observations) available at a location, keyed by dataset_id, with per-dataset freshness where tracked (latest model run as latest_run, latest_time, data_age_seconds, freshness_status). Only datasets covering the point are listed: its domain (CONUS/Alaska/Hawaii) plus global grids and the GOES full disks that see it. Use this to find dataset_id values for query_dataset, or to check whether data is current. Variables, units and standard names come from describe_dataset. Example: {"location": "Anchorage, AK"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
include_freshnessboolean, default trueNoInclude latest model run and data age where tracked. Default true.

One of: location, or lat + lon

Returns: location, domain, datasets, freshness

describe_datasetcatalogFree

Variables available in a dataset, with standard names, units, descriptions, and the time range of available data. Use before query_dataset to discover valid variable names. Example: {"dataset_id": "nbm_conus"}.

ParameterTypeRequiredDescription
dataset_idstring 1-80 charsYesPipeline dataset identifier (e.g. "nbm_conus", "mrms_reflectivity_conus"). Discover valid values with list_datasets; inspect variables with describe_dataset.

Returns: dataset_id, detail, attribution

query_datasetcatalog1 credit per call with an API key

Raw time series from a specific dataset for specific variables at a point. Power-user access to any gridded product (NBM, HRRR, RRFS, GFS, RTMA, MRMS, air quality, ...). Time modes: hours (next N hours, default 24), time_start+time_end (explicit ISO-8601 window), or latest=true (single most-recent value). reference_time pins a specific model run, and each returned series reports the run that served it (reference_time, or reference_times when a series mixes runs) — check it before comparing two runs, since a run older than about 48 hours may no longer be available. For blended forecasts use get_forecast instead. Examples: {"location": "Denver", "dataset_id": "rrfs_surface", "variables": ["temperature_2m"], "hours": 18} or {"lat": 41.4, "lon": -92.9, "dataset_id": "rtma_conus", "variables": ["temperature_2m"], "latest": true}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
dataset_idstring 1-80 charsNoDataset to query. Default: the NBM dataset for the location domain (nbm_conus/nbm_alaska/nbm_hawaii). Discover options with list_datasets.
variablesstring[], 1-20 itemsYesStandard variable names (e.g. temperature_2m, precipitation). Discover with describe_dataset.
hoursinteger 1-264NoForecast/lookahead hours from now (1-264). Default 24 when no other time mode set.
time_startstringNoISO 8601 window start (with time_end).
time_endstringNoISO 8601 window end (with time_start).
latestboolean, default falseNoReturn only the most recent value (analysis datasets like RTMA/MRMS).
reference_timestringNoPin a specific model run (ISO 8601). Default: latest run.

One of: location, or lat + lon

Returns: location, series, attribution

get_platform_statuscatalogFree

Current data-freshness status of the weather platform: overall state, per-source states (ok / degraded / outage / no_signal), open incidents with cause attribution (provider outage vs internal processing delay), and active provider advisories. Use this when a user asks whether data is current, when other tools return surprisingly stale data, or before presenting time-critical weather. If a source is degraded or in outage, tell the user their data may be stale rather than presenting it as live. No inputs. Refreshed about every 5 minutes.

ParameterTypeRequiredDescription
include_okboolean, default falseNotrue: list every monitored source including healthy ones. false (default): only sources that are not ok, keeping the response compact.

Returns: overall, generated_at, sources, advisories, note

get_time_contextcatalog1 credit per call with an API key

Complete temporal context for a location: local time, timezone, 14-day calendar with day names and Today/Tomorrow offsets, sunrise/sunset/solar times (from the weather pipeline's astro product), and moon phase. Use whenever you need to reason about dates, times, or daylight for a location -- including "what time is sunset?", "is it dark there now?", or "what day of the week is the 4th-day forecast?". If current_time.timezone_resolved is false, zone unknown: state times as UTC, never as local. Accepts a place name directly. Example: {"location": "Seattle"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).

One of: location, or lat + lon

Returns: location, current_time, daylight, moon, calendar

reverse_geocodecatalog1 credit per call with an API key; free without a key

Resolve coordinates to a human-readable place (city, state, county, timezone). Use when you have lat/lon but need a display name or the local timezone. Example: {"lat": 39.74, "lon": -104.99} -> Denver, Colorado, America/Denver.

ParameterTypeRequiredDescription
latnumber -90 to 90YesLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180YesLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).

Returns: lat, lon, place

planning comparisons, windows, totals

Add it to the root with /x/core,catalog,planning

compare_locationsplanning1.5 credits per call with an API key

Compare forecast variables across multiple locations side-by-side in one batched call. Returns a distilled per-location series matrix for direct comparison -- prefer this over N sequential forecast calls. Locations accept place names directly. Example: {"locations": [{"location": "Denver"}, {"location": "Boulder, CO"}], "variables": ["temperature_2m", "precipitation_probability"], "hours": 48}.

ParameterTypeRequiredDescription
locationsobject[], 2-10 itemsYesLocations to compare (2-10). Each takes location OR lat/lon, optional label.
locations[].locationstringNoPlace name, ZIP, or "lat,lon" (e.g. "Denver", "Boulder, CO").
locations[].latnumber -90 to 90No
locations[].lonnumber -180 to 180No
locations[].labelstringNoOptional display label (e.g. "Denver warehouse").
variablesstring[], 1-10 itemsYesStandard variable names (e.g. temperature_2m, precipitation).
hoursinteger 1-168, default 24NoForecast hours. Default 24.
dataset_idstring 1-80 charsNoDataset override. Default: auto-resolved NBM per location.

Returns: variables, hours, comparisons, errors, attribution

find_best_windowplanning2 credits per call with an API key

Find the optimal time window for an activity based on weather criteria. Scans the forecast and returns daylight-aware periods matching all conditions. Criteria are expressed in the selected units system (default imperial: °F, mph, miles, feet). Example: {"location": "Boulder, CO", "criteria": {"min_temperature": 55, "max_wind_speed": 15, "max_precipitation_probability": 20}, "hours": 72, "activity_duration_hours": 3}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
units"imperial" | "metric" | "si", default "imperial"NoUnit system for all values in the request and response: imperial (°F, mph, inches), metric (°C, km/h, mm), or si (K, m/s, mm). Defaults to imperial.
criteriaobjectYesWeather criteria defining acceptable conditions (all optional).
criteria.max_precipitation_probabilitynumber 0-100NoMaximum acceptable precipitation probability (0-100%).
criteria.min_temperaturenumberNoMinimum temperature in the selected units (°F / °C / K).
criteria.max_temperaturenumberNoMaximum temperature in the selected units (°F / °C / K).
criteria.max_wind_speednumberNoMaximum sustained wind in the selected units (mph / km/h / m/s).
criteria.max_wind_gustnumberNoMaximum wind gust in the selected units (mph / km/h / m/s).
criteria.min_visibilitynumberNoMinimum visibility in the selected units (miles / km / m).
criteria.min_ceilingnumberNoMinimum cloud ceiling in the selected units (feet / m / m).
hoursinteger 1-168, default 72NoHours to search. Default 72.
activity_duration_hoursinteger 1-24, default 2NoMinimum consecutive hours meeting criteria. Default 2.
daylight_onlyboolean, default trueNoOnly consider daylight hours (sunrise to sunset). Default true.
activitystring <= 200 charsNoFree-form activity to rate the windows for (e.g. "afternoon golf"). Accepted even when rating is off so clients can send it.

One of: location, or lat + lon

Returns: location, units, windows, criteria_applied, daylight_only, daylight_filter, activity_duration_hours, sun_times, message

Input examples

{
  "location": "Boulder, CO",
  "criteria": {
    "min_temperature": 55,
    "max_wind_speed": 15,
    "max_precipitation_probability": 20
  },
  "hours": 72,
  "activity_duration_hours": 3
}
{
  "location": "Girdwood, AK",
  "criteria": {
    "max_precipitation_probability": 30
  },
  "daylight_only": true
}
get_period_totalsplanning2.5 credits per call with an API key

Aggregate a weather variable over one or more time periods. Returns server-computed totals, maxima, minima, or averages per period. Period start/end times should use the user's local timezone boundaries (not UTC midnight). Response includes the converted value and unit per period. Period-ending totals (1 h rain/snow, 6 h buckets, MRMS QPE) sum windows ending in (start, end]. period_total variables need periods on their bucket grid (UTC-aligned for 3 h/6 h buckets such as precipitation_6h; hourly totals fit any hour); off-grid periods error naming the grid. Past the data: partial: true, frames_used/frames_expected, covered_start/covered_end. Ideal for questions like "total rainfall today and tomorrow" or "peak wind speed this weekend". For rain that already fell, use get_observed_precipitation. Accepts a place name directly. Example: {"location": "Portland, OR", "variable": "precipitation", "aggregation": "sum", "periods": [{"start": "2026-07-08T07:00:00Z", "end": "2026-07-09T07:00:00Z", "label": "Today"}]}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
variablestringYesStandard variable name (e.g. precipitation, snowfall, temperature_2m, wind_speed_10m, cape).
aggregation"sum" | "max" | "min" | "avg", default "sum"NoAggregation function. Default sum. Use sum for precipitation/snowfall, max for temperature/wind, min for low temperatures, avg for humidity/cloud cover.
periodsobject[], 1-14 itemsYesTime periods to aggregate over (1-14).
periods[].startstringYesISO 8601 start time
periods[].endstringYesISO 8601 end time
periods[].labelstringNoHuman label, e.g. "Today", "Tomorrow"
units"imperial" | "metric" | "si", default "imperial"NoUnit system for all values in the request and response: imperial (°F, mph, inches), metric (°C, km/h, mm), or si (K, m/s, mm). Defaults to imperial.
dataset_idstring 1-80 charsNoDataset override. Default: auto-resolved NBM for the location.

One of: location, or lat + lon

Returns: location, variable, aggregation, periods, message, attribution

get_air_qualityplanning1 credit per call with an API key

AirNow air quality at a location (CONUS): current overall AQI plus per-pollutant detail (PM2.5, ozone, PM10 concentrations) and the AirNow AQI forecast. AQI scale: 0-50 good, 51-100 moderate, 101-150 unhealthy for sensitive groups, 151-200 unhealthy, 201-300 very unhealthy, 301+ hazardous. pollutants=["aqi"] (default) is the cheap headline call; add pollutant keys or include_forecast=true when the user digs in. Example: {"location": "Boise", "pollutants": ["aqi", "pm25"], "include_forecast": true}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
pollutants("aqi" | "pm25" | "ozone" | "pm10")[], default ["aqi"]NoWhich measurements to return. aqi = combined AQI index. Default: ["aqi"].
include_forecastboolean, default falseNoAlso return the AirNow next-day AQI forecast.

One of: location, or lat + lon

Returns: location, current, forecast, widget

observed stations, soundings, recon

Add it to the root with /x/core,catalog,observed

get_observationsobserved1 credit per call with an API key

METAR surface observations from weather stations: temperature, wind, visibility, ceiling, flight category, raw METAR. Nearest mode (default) returns the closest N stations to a location; station mode returns history for a specific ICAO identifier. Examples: {"location": "Denver", "n": 3} or {"station": "KJFK", "hours": 6}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
ninteger 1-10, default 1NoNumber of nearest stations (1-10). Default 1. Ignored in station mode.
stationstring 3-4 charsNoICAO station identifier (e.g. KJFK). Switches to station-history mode.
hoursinteger 1-24NoHours of history in station mode (1-24).

One of: location, or lat + lon

Returns: location, station, observations

get_soundingobserved1 credit per call with an API key

Nearest RAOB (radiosonde) vertical soundings to a point. Each sounding carries: profile (pressure-indexed thermodynamics: pressure_hpa, height_m, temperature_c, dewpoint_c, wind arrays), wind_profile (height-indexed winds for hodographs/shear), and derived indices (sbcape/mucape/mlcape + cin, lifted_index, k_index, total_totals, pwat_mm, freezing_level_m, lcl/lfc/el, bulk_shear_0_6km_kt). Soundings launch at 00Z/12Z so data can be hours old. Example: {"location": "Norman, OK"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
ninteger 1-5, default 1NoNumber of nearest soundings (1-5). Default 1.

One of: location, or lat + lon

Returns: location, soundings

get_tropical_observationsobserved1 credit per call with an API key

Hurricane Hunter aircraft reconnaissance for active tropical systems: vortex data message (VDM) center fixes — pressure, max flight-level wind, eye — and high-density (HDOB) flight-level observations. These are aircraft measurements, not surface weather stations (use get_observations for METAR). Use get_tropical for NHC cones, tracks, and watches; this tool is what the aircraft measured. kind=hdob returns the newest 200 records (about 1–2 h of flight; truncated says when more exist). Empty when no aircraft has flown in the window.

ParameterTypeRequiredDescription
stormstring <= 32 charsNoATCF id (al14) or storm name (polo). Unnumbered USAF missions never match.
kind"vdm" | "hdob" | "all", default "vdm"Novdm = vortex fixes; hdob = flight-level obs; all = both. Default vdm.
hoursinteger 1-72, default 24NoLookback window in hours (1-72). Default 24.

Returns: active, storms, feature_count, truncated, features

severe happening now

Add it to the root with /x/core,catalog,severe

get_lightning_activitysevere1 credit per call with an API key

Real-time lightning near a location: GLM satellite flash count (30km/10min) and MRMS ground-truth lightning density + 30-minute probability. The summary field is ready-to-use. A zero flash count means no lightning inside that window -- report it as a quiet observation scoped to the window in scope, never as a data gap. Only call when storms may be active or the user asks about lightning. Example: {"location": "Tampa"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).

One of: location, or lat + lon

Returns: location, scope, lightning

get_storm_cellssevere1 credit per call with an API key

Radar-identified storm cells near a location, merging NEXRAD Level III algorithm output from the nearest radar site: storm tracks (cell position, movement, forecast positions), hail index (probability of hail/severe hail + max expected size), mesocyclone detections (rotation), and TVS (tornado vortex signatures). Use during active convection to see what the radar algorithms flag. An empty result means no detected cells -- common outside active storms. Example: {"location": "Norman, OK"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
include("tracks" | "hail_index" | "mesocyclone" | "tvs")[], default ["tracks","hail_index","mesocyclone","tvs"]NoWhich detection families to include. Default: all.

One of: location, or lat + lon

Returns: location, summary, tracks, detections

get_storm_reportssevere1 credit per call with an API key

Recent NWS Local Storm Reports (LSRs) -- verified reports of tornadoes, hail, damaging winds, flooding near a location. Use to confirm severe weather occurrence or assess reported damage. valid_time is event occurrence (UTC); cite in local time. Example: {"location": "Wichita", "hours": 12, "type": "H"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
hoursinteger 1-24, default 6NoLookback window in hours (1-24). Default 6.
typestringNoReport type filter: T=tornado, H=hail, W=wind, F=flood, D=damage, S=snow.

One of: location, or lat + lon

Returns: location, hours, reports

guidance outlooks, forecaster text

Add it to the root with /x/core,catalog,guidance

get_outlooksguidance1 credit per call with an API key

Hazard outlooks affecting a location. severe: SPC convective (day 1-8 categorical + tornado/wind/hail probabilities); fire: SPC fire weather; rain: WPC Excessive Rainfall (days 1-3); heat: NWS HeatRisk index (0-4, days 1-3); temperature/precipitation: CPC 6-10 day, 8-14 day, week 3-4 and monthly outlooks (favored category + probability bin; period=seasonal: 3-month leads). include_narrative=true adds the forecaster discussion (SWO, FWD, QPFERD, or the period's CPC PMD). Empty means no outlook covers the point, not a failure. Examples: {"location": "Moore, OK", "hazard": "severe", "include_narrative": true} or {"location": "Denver", "hazard": "temperature"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
hazard"severe" | "fire" | "rain" | "heat" | "temperature" | "precipitation"NoHazard family (see description). Default severe; with period, both CPC hazards.
dayinteger 1-8, default 1NoOutlook day for the narrative filter (1-8). Default 1.
include_narrativeboolean, default falseNoInclude the forecaster narrative (all hazards but heat).
period"610" | "814" | "wk34" | "monthly" | "seasonal"NoTemperature/precipitation only. Default: all but seasonal.

One of: location, or lat + lon

Returns: location, hazard, day, outlooks, heat_risk, narrative

get_forecast_discussionguidance1 credit per call with an API key

Expert forecaster text products. type=afd: Area Forecast Discussion. type=hwo: Hazardous Weather Outlook. type=now: WFO short-term NOW. type=fwf/hls/esf: local fire weather / hurricane local statement / hydrologic discussion. type=mcd: SPC Mesoscale Discussion. type=mpd: WPC Mesoscale Precipitation Discussion (flash flood). type=swo/fwd/ero: national outlook discussions. type=tcd/tcp/tcm/twd/two: NHC tropical text (type=two is the text TWO, not GIS nhc_two). type=pmd: WPC/CPC desk discussion (pass awips_id for a specific desk, e.g. PMDSPD). type=pwo: SPC public weather outlook. National types (swo/fwd/ero/tcd/tcp/tcm/twd/two/pmd/pwo) need no location; day selects the outlook day for swo and fwd. summary_only=true returns the pipeline LLM summary without the full body. Examples: {"location": "Des Moines", "type": "afd"} or {"type": "swo", "day": 2, "summary_only": true}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
type"afd" | "hwo" | "now" | "fwf" | "hls" | "esf" | "mcd" | "mpd" | "swo" | "fwd" | "ero" | "tcd" | "tcp" | "tcm" | "twd" | "two" | "pmd" | "pwo"YesProduct type: afd (WFO discussion), hwo (hazard outlook), now (short-term NOW), fwf/hls/esf (local WFO), mcd (SPC mesoscale), mpd (WPC precipitation discussion), swo (SPC convective outlook), fwd (SPC fire weather), ero (WPC excessive rainfall), tcd/tcp/tcm/twd/two (NHC tropical text; two is text TWO not GIS), pmd (desk discussion), pwo (SPC public outlook).
dayinteger 1-8, default 1NoOutlook day for type=swo or type=fwd (1-8). Ignored for the other types; WPC files ERO days 1-3 under one product.
awips_idstring 3-12 charsNoAWIPS id (e.g. TCDAT1, PMDSPD; CPC: PMDMRD 6-10/8-14d, PMD34D wk3-4, PMD30D 30d, PMD90D 90d, PMDTHR hazards, PMDENS ENSO). Exact source_ref; beats type+location.
wfostring 3-4 charsNoWFO identifier override (e.g. BOU). Default: resolved from the location.
limitinteger 1-10, default 1NoNumber of recent products (1-10). Default 1 (latest).
summary_onlyboolean, default falseNoReturn only the LLM summary + sections, omitting the full body text.

Returns: location, type, products

get_tropicalguidance1 credit per call with an API key

Active NHC (National Hurricane Center) tropical systems: forecast cones, track lines, forecast points, coastal watches/warnings, and 7-day Tropical Weather Outlook formation areas -- Atlantic + East Pacific. Each feature carries a kind (cone | track | points | watch_warning | outlook_area) plus storm name, intensity, and timing properties. include_geometry=true adds full GeoJSON geometries (large). An empty result means no active tropical activity. Aircraft reconnaissance fixes and flight-level observations are in get_tropical_observations. Example: {} or {"include_geometry": true}.

ParameterTypeRequiredDescription
include_geometryboolean, default falseNoInclude full GeoJSON geometries (cone/track polygons). Default false.

Returns: active, feature_count, features

history climate

Add it to the root with /x/core,catalog,history

get_climate_recordshistory1 credit per call with an API key

NWS daily climate data: type=reports returns CLI daily climate reports (observed high/low/precip vs normals per station); type=records returns RER record event reports (record highs/lows/rainfall actually set). Filter by wfo (3-letter office, e.g. DMX), station, date (YYYY-MM-DD), start/end range, or hours lookback. Examples: {"type": "records", "hours": 48} or {"type": "reports", "wfo": "DMX", "date": "2026-07-04"}.

ParameterTypeRequiredDescription
type"reports" | "records"Yesreports = CLI daily climate reports; records = RER record events.
wfostring 3-4 charsNoWFO office filter (e.g. DMX, OUN).
stationstringNoStation identifier filter (reports only).
record_typestringNoRecord type filter (records only), e.g. HIGH, LOW, RAIN.
datestringNoSingle date, YYYY-MM-DD.
startstringNoRange start date, YYYY-MM-DD.
endstringNoRange end date, YYYY-MM-DD.
hoursinteger 1-168NoLookback window in hours (1-168) when no date/range is given.

Returns: type, results

get_climate_normalshistory1 credit per call with an API key

Day-of-year climate normals (NCEI 1991-2020 30-year averages) for a US location, from the nearest station with a record. Returns normal high, normal low, and normal mean for each date in the window, plus the station and how far away it is. Use this whenever a question needs a baseline rather than a forecast: "is this warm for October?", "what is a typical high here in January?", "how does this week compare to normal?". Pair it with get_forecast to say how far above or below normal the coming days run. Covers dates by day of year, so it answers for any date, past or future -- these are long-period averages, not a forecast and not observed history for a specific year.

ParameterTypeRequiredDescription
latnumber -90 to 90YesLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180YesLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
startstring /^\d{4}-\d{2}-\d{2}$/NoInclusive range start as YYYY-MM-DD. Must be supplied with end.
endstring /^\d{4}-\d{2}-\d{2}$/NoInclusive range end as YYYY-MM-DD. Must be supplied with start.
daysinteger 1-366NoRange length in days when start/end are omitted; the window opens today (default 14).
unit"imperial" | "metric"NoUnit system for the normals. Default imperial (°F).

verification accuracy

Add it to the root with /x/core,catalog,verification

get_forecast_skillverification1 credit per call with an API key

How accurate our forecasts have actually been near a location, measured against observed analysis truth. Returns bias (positive = the model runs high), mean absolute error, RMSE, and a skill score against local climatology, per model, weather variable, and forecast lead time; continuous and vector entries also carry persistenceSkillScore, skill against the analysis at forecast issue time (null means not enough persist pairs, not zero skill -- do not compare it to skillScore as if they shared a denominator), and analysisDisagreementMae, the analyses' own disagreement at that lead -- a floor on how good the forecast can look, not a skill score and not an excuse (null means the sibling row is missing or below minimumSamples); for probability forecasts, the Brier score and a reliability breakdown. Use this to qualify a forecast rather than assert it -- "NBM has been running 1.8F warm at 3-day leads near you, so treat that 72 as around 70" -- and to answer "how much should I trust this forecast", "is the model biased here", or "how accurate were you last month". Evidence comes at three scopes side by side: the exact point (strongest, slowest to accumulate), the neighborhood and the region (coarse pooled cells, not street-level). Prefer the most specific scope that has samples. Metrics below minimumSamples observations are withheld and listed under insufficientHistory with their count -- say history is still accumulating; do not treat thin numbers as evidence. Coverage is a rolling recent window over verified US variables, not all of history. Samples aren't matched across models, so never conclude one model beats another from these numbers. Each entry states the truth field it was measured against (one designated analysis per variable); never compare numbers with different truth values either. Each entry also states its regime: ALL (every observation, any weather) or a conditioned tier such as SEA:DJF (winter), SCN1:WINDY / SCN1:WET / SCN1:QUIET (what the forecast was showing), or JC1:NW (a circulation pattern). Pass the regime parameter to ask for a conditioned track record. It falls back: asking for SCN1:WINDY and getting regime ALL is a successful answer, not a missing one -- always read the regime field and qualify the claim with it, because "NBM runs warm here when it shows windy" and "NBM runs warm here" are different statements. Regimes overlap by construction across families, so entries under different regimes are alternative answers to one question; never compare or add them. Within SCN1: the labels are mutually exclusive. Entries with a categorical block answer a yes/no question instead of an error magnitude -- did it rain, at the thresholdMm stated on the entry -- with pod (of the times it happened, how often we called it), far (of the times we called it, how often it did not happen), and frequencyBias (above 1 = we call it too often). Use these for "will it actually rain" questions, where a small average error means nothing if the rain lands in the wrong hour. A null rate means the sample cannot answer it -- the event has not happened, or been forecast, enough times to divide by -- and must be reported as unknown, never as zero. The counts beside it are still evidence, and for a rare event they are often the whole answer: "it has only rained twice here in the record" is a useful thing to say.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
variablestringNoNarrow to one variable, e.g. temperature_2m, dew_point_2m, wind_speed_10m, wind_gusts_10m, wind_vector_10m, cloud_cover, precipitation, precipitation_probability, or a thresholded rain event such as precipitation_gt_0p254mm (any measurable rain) or precipitation_gt_2p54mm. Omit for everything measured at the location.
modelstringNoNarrow to one model, e.g. nbm or rrfs.
lead_hoursinteger >= 1NoNarrow to the lead time being asked about, in hours; the containing lead bucket is selected for you (60 gives the 48-72h bucket). Use the lead of the forecast you are qualifying: ~24 for tomorrow, ~72 for three days out. Never approximated -- a lead we have not verified returns no entries rather than a nearby bucket, so an empty result means we cannot speak to that range.
truthstringNoMeasure against a named truth source instead of the default one for each variable, e.g. urma. Only pass this if the user asked which analysis was used or named one; the default is already the designated source, and the analyses disagree, so switching changes the numbers.
regimestringNoAsk for a track record measured only under particular conditions, as a comma-separated preference chain, most specific first, e.g. "SCN1:WINDY,SEA:JJA". SEA: is the meteorological season (DJF, MAM, JJA, SON); SCN1: is a forecast-conditioned scenario (WINDY, WET, QUIET — mutually exclusive within the family); JC1: is a circulation pattern. The most specific tier with enough observations answers and the unconditioned record is the last resort, so this never empties a result the way truth does -- it degrades. Read the regime field on each entry to see which tier actually answered. Pass this when the question is conditional ("is it worse in winter", "how does it do when the model shows windy"); omit it otherwise, since conditioned tiers are thinner and slower to earn numbers.
unit"imperial" | "metric" | "si"NoUnits for the error magnitudes. Default imperial (bias/MAE/RMSE in °F, mph, in).

One of: location, or lat + lon

Returns: location, units, minimumSamples, tracked, cells, skill, insufficientHistory

Input examples

{
  "location": "Denver",
  "variable": "temperature_2m",
  "lead_hours": 72
}
{
  "lat": 39.7392,
  "lon": -104.9903
}
{
  "location": "Dallas, TX",
  "variable": "precipitation_probability",
  "lead_hours": 24
}
{
  "location": "Chicago",
  "variable": "temperature_2m",
  "regime": "SEA:DJF"
}
{
  "location": "Houston",
  "variable": "precipitation_gt_0p254mm",
  "lead_hours": 24
}
get_forecast_skill_mapverification1 credit per call with an API key

Measured forecast skill as a map of res-4 hexes inside a bounding box, sliced from the public skill map. Use this when the question is spatial ("where is NBM temperature skill weak across Colorado"), not "how good is the forecast at this point" — that is get_forecast_skill. Requires model, variable, lead_hours, and bbox {west,south,east,north}. lead_hours selects the containing published bucket (20 → NBM 24); a lead we have not published returns no slices rather than a nearby one. A hex is included when its center is inside the box; edge-overlapping hexes are dropped. The box cannot wrap the dateline. Each cell is [h3, samples, skill_score]; skill_score is unitless (fraction of climatological variance explained) and already gated at n ≥ 30. withheld lists hexes still accumulating. Do not compare slices across models or truths. This is CELL# only — never treat a hex as a person.

ParameterTypeRequiredDescription
bboxobjectYesBounding box {west,south,east,north}. Hexes whose H3 center falls inside are returned.
bbox.westnumber -180 to 180YesLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
bbox.southnumber -90 to 90YesLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
bbox.eastnumber -180 to 180YesEastern edge, longitude in decimal degrees.
bbox.northnumber -90 to 90YesNorthern edge, latitude in decimal degrees.
modelstringYesModel id, e.g. nbm, gfs, hrrr, or rrfs.
variablestringYesVerified variable, e.g. temperature_2m, dew_point_2m, precipitation, or precipitation_gt_0p254mm.
lead_hoursinteger >= 1YesLead time in hours; the containing published bucket is selected. Never approximated.
domainstringNoOptional domain (conus, alaska, hawaii). Omit unless you already know it.

Returns: generated_at, atom_resolution, minimum_samples, bbox, slices

Input examples

{
  "bbox": {
    "west": -105.2,
    "south": 39.5,
    "east": -104.7,
    "north": 40
  },
  "model": "nbm",
  "variable": "temperature_2m",
  "lead_hours": 24
}

visual images

Add it to the root with /x/core,catalog,visual

get_map_snapshotvisual4 credits per call with an API key

Render a weather map image for visual analysis. Simple form: pass product (a viz-catalog product_id like "mrms_qpe_01h_pass2_conus", "goes_truecolor_conus", "spc_day1_categorical", "hrrr_precip_hybrid_derived_conus" (future radar), "hrrr_subhourly_conus" (15-min Future Radar), "mrms_radar_nowcast_conus", "rtma_conus", "nbm_daily_temps", or "nexrad_l3:{SITE}:{PRODUCT}" for single-site radar, e.g. "nexrad_l3:TLX:N0B") plus a location and zoom (5=regional, 8=metro, 10=city). Composed form: pass scene -- a declarative scene document layering basemap + multiple weather products + active alerts + storm features + inline GeoJSON in one image (layers draw bottom-to-top, under basemap labels). Example scene: {"scene":"1.0","view":{"center":{"lat":43.8,"lon":-91.2},"zoom":8},"layers":[{"type":"weather","product":"goes_truecolor_conus"},{"type":"weather","product":"nexrad_l3:ARX:N0B"},{"type":"alerts","filter":{"events":["Tornado Warning"]},"onError":"skip"}]}. Alert filters (all optional, AND-combined): ids (specific alerts), events, severities, minSeverity (Extreme>Severe>Moderate>Minor>Unknown). Single-site radar keys: the address is nexrad_l3:{SITE}:{KEY} where KEY is N{tilt}{measurement} and tilt 0 is the 0.5 degree sweep -- N0B reflectivity (dBZ, where and how heavy), N0G base velocity (knots toward/away from the radar), N0S storm-relative velocity (storm motion removed, so a couplet is rotation rather than translation -- prefer it for rotation questions), N0C correlation coefficient (0-1, debris and hail), N0X differential reflectivity (dB). Legacy codes (N0V, N0R, N0Q) are accepted as aliases. Not every site produces every key; when a render reports which keys a site has, retry with one of those. Optional time (unix seconds): closest frame. Forecast (HRRR/nowcast/NBM) honors future times; analysis (MRMS/NEXRAD/RTMA/GOES) clamps to latest past. Pass time for future-radar asks — do not claim that capability is missing. Product ids must be real viz-catalog entries -- shorthand like "radar" or "reflectivity" is not one. Omit product for the default hybrid precip still. For Alaska and Hawaii prefer a local site or mrms_precip_hybrid_derived_alaska over CONUS mosaics, which do not cover them. Returns the rendered image plus per-layer resolved valid times.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
productstringNoviz-catalog product_id or nexrad_l3:{SITE}:{KEY} (simple form)
zoomnumber 2-14, default 7NoMap zoom (simple form)
timeintegerNoUnix seconds; closest frame (default: latest). Forecasts honor future times.
opacitynumber 0-1NoWeather layer opacity
widthinteger 300-2000, default 720No
heightinteger 200-2000, default 440No
sceneobjectNoFull scene document (composed form). When set, product/location/zoom are ignored.

Input examples

{
  "location": "Tulsa, OK",
  "product": "nexrad_l3:TLX:N0B",
  "zoom": 8
}
{
  "lat": 39.74,
  "lon": -104.99,
  "product": "goes_truecolor_conus",
  "zoom": 5
}
{
  "location": "Chicago, IL",
  "product": "hrrr_precip_hybrid_derived_conus",
  "zoom": 7,
  "time": 1783554900
}
get_sounding_chartvisual3 credits per call with an API key

Render the nearest RAOB (radiosonde) sounding as a Skew-T log-P + hodograph chart image for visual analysis: temperature/dewpoint traces, wind barbs, height-banded hodograph, and a derived-indices table (CAPE/CIN, lifted index, PWAT, shear, LCL). Soundings launch at 00Z/12Z so data can be hours old. Use get_sounding for the raw profile numbers. Example: {"location": "Norman, OK"}.

ParameterTypeRequiredDescription
locationstring 1-200 charsNoFree-text place: city ("Denver"), city+state ("Portland, OR"), US ZIP, venue/address where enabled, or "lat,lon". Use this OR lat+lon, not both.
latnumber -90 to 90NoLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180NoLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
unit"fahrenheit" | "celsius", default "fahrenheit"NoTemperature axis display unit
scalenumber 1-3, default 2NoRaster scale factor (2 = retina; higher = larger image payload)

One of: location, or lat + lon

exposure people at risk

Add it to the root with /x/core,catalog,exposure

get_population_exposureexposure1.5 credits per call with an API key

National population-exposure headline for a risk-zone outlook product: how many people are inside risk bands at or above min_level. Powers headlines like "~57M people under major heat risk tomorrow". hazard=heat covers NWS HeatRisk days 1-3 (levels: 1 minor, 2 moderate, 3 major, 4 extreme). Pass product_id directly for other risk-zone products. Example: {"hazard": "heat", "min_level": 3}.

ParameterTypeRequiredDescription
hazard"heat"NoHazard family (expands the day-1..3 product set). Currently: heat (HeatRisk).
product_idstringNoExplicit risk-zone product ID (overrides hazard), e.g. heatrisk_day1_conus.
min_levelinteger 1-5, default 1NoMinimum risk level to count (>=). Default 1 (any elevated risk).

Returns: min_level, summaries

get_path_exposureexposure1.5 credits per call with an API key

Civic POIs (schools, hospitals, airports, …) inside a caller-supplied GeoJSON Polygon or MultiPolygon. Not enabled for every caller: when off it returns 403 flag-disabled. Clip first; not a CONUS HeatRisk dissolve. Optional classes filters the civic allowlist. Example: {"geometry":{"type":"Polygon","coordinates":[[[-88.15,41.77],[-88.14,41.77],[-88.14,41.78],[-88.15,41.78],[-88.15,41.77]]]},"classes":["school"]}.

ParameterTypeRequiredDescription
geometryobjectYesGeoJSON Polygon or MultiPolygon. Clip national outlooks first.
geometry.type"Polygon" | "MultiPolygon"Yes
geometry.coordinatesany[]Yes
classesstring[]NoOptional civic classes: airport, station, hospital, school, university, library, museum, stadium, cemetery, place_of_worship, camp_site, golf, attraction.

Returns: counts, features

agriculture crops

Add it to the root with /x/core,catalog,agriculture

get_growing_degree_daysagriculture2 credits per call with an API key

Growing Degree Units (GDU / GDD) for a US location (CONUS, Alaska, Hawaii), computed from daily max/min temperatures. Pass a crop id (e.g. "corn", "soybean", "wheat") to use calibrated base/upper thresholds, or crop="custom" with base_temp_c (and optional upper_temp_c / method). Without season_start you get per-day GDU across the forecast horizon; WITH season_start (YYYY-MM-DD) you get the cumulative season-to-date total (observed history + today + forecast) plus a per-day cumulative series -- the number a grower tracks against crop milestones. Answers "how many growing degree days has my corn accumulated since May 1?" and "what's the GDU forecast this week?".

ParameterTypeRequiredDescription
latnumber -90 to 90YesLatitude in decimal degrees (-90 to 90). Most tools also accept a location place-name string instead of lat/lon.
lonnumber -180 to 180YesLongitude in decimal degrees (-180 to 180). For continental US use negative values (west of the prime meridian).
cropstringYesCrop id from the catalog (e.g. "corn", "soybean", "wheat") or "custom" to supply your own thresholds via base_temp_c.
season_startstring /^\d{4}-\d{2}-\d{2}$/NoSeason/planting start as YYYY-MM-DD (local date). Presence switches the response to a cumulative season-to-date GDU total. Must be within the ~180-day observed window.
daysinteger 1-30NoForecast horizon in days (default 10).
day_definition"nws" | "local_calendar"NoDaily boundary: "nws" (default; NBM MaxT/MinT period extremes) or "local_calendar" (midnight-to-midnight local day).
unit"imperial" | "metric"NoUnit system for GDU + temps. Default imperial (°F-days).
base_temp_cnumberNoCustom base threshold in °C. Required when crop="custom".
upper_temp_cnumberNoCustom upper cutoff in °C (enables the modified method). Optional.
method"simple" | "modified"NoGDU method for custom crops. Defaults from whether upper_temp_c is set.
include_milestonesbooleanNoInclude the crop's growth-stage GDU milestones in the response.

Errors

A failed tools/call is a result with isError: true whose first text block is an RFC 9457 Problem with the REST API's type URIs. Key on type, then status. Full rules: /errors#mcp.