cyanheads avatar

Nws Weather Mcp Server

cyanheads/nws-weather-mcp-server

Connects Claude directly to the National Weather Service API with zero authentication required. You get seven tools covering the essentials: 7-day and hourly forecasts by coordinates, active alert searches with filtering by severity and event type, current observations from nearby stations, and narrative products like Area Forecast Discussions from any Weather Forecast Office. The coordinate-to-grid resolution happens automatically with caching, and observations come back in dual units. Useful when you need authoritative US weather data without managing API keys or parsing raw NOAA feeds. Available as a public hosted instance at nws.caseyjhand.com/mcp or self-hosted via npm.

GitHub stars
2
tools
10
transport
STDIO, HTTP
env vars
7
last updated
Nov 11, 2026

Install

From registry metadata
$ npx add-mcp https://nws.caseyjhand.com/mcp --name nws-weather

Run in your terminal. add-mcp asks which agents to add it to (Claude Code, Codex, Cursor and more). Add -g to install it for every project.

Review the command, arguments and environment values before installing. MCP servers run with your local permissions.

Other ways

Claude Code

$ claude mcp add --transport http nws-weather https://nws.caseyjhand.com/mcp

Run in your terminal. Add --scope user to make it available in every project.

Tools

Verified live · 10 tools

Verified live against the running server on Nov 13, 2026.

nws_get_forecastGet the weather forecast for a US location. Returns either named 12-hour periods (default) or hourly breakdowns.5 params

Get the weather forecast for a US location. Returns either named 12-hour periods (default) or hourly breakdowns.

Parameters* required
cursorstring
Opaque continuation token from a previous response's nextCursor, to retrieve the next 48 periods. Omit for the first page. The token carries the mode it was issued in (hourly or 7-day), so the next...
hourlyboolean
If true, returns hourly forecast (48 one-hour periods per page, ~156 available) instead of 12-hour named periods (14 periods). Hourly includes dewpoint and relative humidity. Sets the mode of the f...default: false
include_amountsboolean
Include every native quantitativePrecipitation, snowfallAmount, and iceAccumulation interval from the NWS grid. Applies to this call only, including cursor pages; units and interval strings remain...default: false
latitude*number
Latitude in decimal degrees (e.g., 47.6062).
longitude*number
Longitude in decimal degrees (e.g., -122.3321).
nws_search_alertsSearch weather alerts (watches, warnings, advisories) across the US: the alerts active now, or — with start and/or end — every alert message issued in that window within the last 7 days, updates and cancellations included, to answer whether a place was under a warning at a pas...15 params

Search weather alerts (watches, warnings, advisories) across the US: the alerts active now, or — with start and/or end — every alert message issued in that window within the last 7 days, updates and cancellations included, to answer whether a place was under a warning at a pas...

Parameters* required
areastring
US state/territory code (e.g., "WA", "OK", "PR") or marine area code (e.g., "GM"). Mutually exclusive with point and zone.
certaintyarray
Filter by certainty level.
cursorstring
Opaque continuation token from a previous response's nextCursor; send it on its own. Omit for the first page. It carries that query's filters, window, and page size, so the filter inputs, start, en...
endstring
Latest issuance time to include (inclusive), in the same format as start. On its own it searches every message NWS still keeps that was issued at or before it; equal to start, it searches that one...
eventarray
Filter to specific event types (e.g., ["Tornado Warning"]). Matches are case-insensitive and partial, so "tornado" matches both "Tornado Warning" and "Tornado Watch". Use nws_list_alert_types to di...
limitinteger
Maximum number of alerts to include in this page (default 25). A page holds at most 25; a larger limit is served as 25 and reported through requestedLimit and effectiveLimit. On an active search to...default: 25
message_typestring
Filter by CAP message type: "Alert" for an original issuance, "Update" for a revision of an earlier message, "Cancel" for a cancellation. Applies to active and windowed searches alike.one of Alert · Update · Cancel
pointstring
Coordinates as "lat,lon" (e.g., "47.6,-122.3"). Returns alerts whose geometry contains this point. Mutually exclusive with area and zone.
regionarray
Restrict to NWS marine region groups: "AL" (Alaska waters), "AT" (Atlantic Ocean), "GL" (Great Lakes), "GM" (Gulf of Mexico), "PA" (Eastern Pacific and US West Coast), "PI" (Central and Western Pac...
region_typestring
Restrict to land-based or marine alerts. Mutually exclusive with area, point, zone, and region.one of Land · Marine
severityarray
Filter by severity level.
startstring
Search the alert messages issued at or after this time instead of the alerts active now, as an ISO 8601 date-time with seconds and an offset (e.g., "2026-11-10T00:00:00Z" or "2026-11-09T18:00:00-06...
statusstring
Alert status filter. Default "Actual". Use a different value only when you specifically need non-live alerts.one of Actual · Exercise · System · Test · Draftdefault: Actual
urgencyarray
Filter by urgency level.
zonestring
NWS forecast zone (e.g., "WAZ558") or county zone (e.g., "WAC033"). Mutually exclusive with area and point.
nws_get_alertFetch one NWS alert message by ID — a current alert, or an earlier message that an update or cancellation has since superseded and that an active-alert search no longer returns. Takes an id from nws_search_alerts or a references[].identifier from any alert, and returns the sam...1 params

Fetch one NWS alert message by ID — a current alert, or an earlier message that an update or cancellation has since superseded and that an active-alert search no longer returns. Takes an id from nws_search_alerts or a references[].identifier from any alert, and returns the sam...

Parameters* required
alert_id*string
NWS alert message ID, e.g. "urn:oid:2.49.0.1.840.0.654087301e4bfcbe71d24494c26a965e54d3a1ad.001.1": the id of an alert from nws_search_alerts, or the identifier of one of its references. Pass it ex...
nws_get_alert_countsCount active weather alerts nationwide, per state/territory or marine area, and per marine region, in one small response — the answer to "how many alerts are active, and where" without fetching the alerts themselves. Counts cover every message status, Test and Exercise include...

Count active weather alerts nationwide, per state/territory or marine area, and per marine region, in one small response — the answer to "how many alerts are active, and where" without fetching the alerts themselves. Counts cover every message status, Test and Exercise include...

No parameters. Call it with no arguments.

nws_get_observationsGet current weather observations (actual measured conditions). Accepts coordinates (resolves nearest station automatically) or a station ID directly (e.g., "KSEA").3 params

Get current weather observations (actual measured conditions). Accepts coordinates (resolves nearest station automatically) or a station ID directly (e.g., "KSEA").

Parameters* required
latitudenumber
Latitude for automatic station resolution. Use with longitude. Ignored if station_id is provided.
longitudenumber
Longitude for automatic station resolution. Use with latitude. Ignored if station_id is provided.
station_idstring
Station identifier directly (e.g., "KSEA", "KORD"). Use nws_find_stations to discover station IDs.
nws_get_observation_historyGet a station's recent observation history, newest first — the trend behind the single latest reading nws_get_observations returns (is pressure falling, is the wind picking up). NWS keeps about the last 7 days per station, and a busy airport station reports as often as every 5...5 params

Get a station's recent observation history, newest first — the trend behind the single latest reading nws_get_observations returns (is pressure falling, is the wind picking up). NWS keeps about the last 7 days per station, and a busy airport station reports as often as every 5...

Parameters* required
cursorstring
Opaque continuation token from a previous response's nextCursor. Omit for the first page. It carries that query's start, end, and applied limit, so those inputs apply to the first page only. Each p...
endstring
Time to stop before (exclusive), in the same format as start. Omit to start from the most recent observation.
limitinteger
Observations per page, newest first. A page holds at most 100; a larger limit is served as 100 and reported through requestedLimit and effectiveLimit. When older observations remain in the window,...default: 24
startstring
Earliest observation time to include (inclusive), as an ISO 8601 date-time with seconds and an offset (e.g., "2026-09-30T00:00:00Z" or "2026-09-29T17:00:00-07:00"). Omit to reach back as far as NWS...
station_id*string
Observation station ID (e.g., "KSEA"), case-insensitive. Use nws_find_stations to discover station IDs near a coordinate.
nws_find_stationsFind weather observation stations near a location. Returns stations sorted by proximity with distance and bearing. Use to discover station IDs for nws_get_observations.4 params

Find weather observation stations near a location. Returns stations sorted by proximity with distance and bearing. Use to discover station IDs for nws_get_observations.

Parameters* required
cursorstring
Opaque continuation token from a previous response's nextCursor. Omit for the first page. The token carries its own page size, so limit applies to the first page only. Every call re-fetches the sta...
latitude*number
Center latitude for proximity search.
limitinteger
Max stations per page. A page holds at most 50; a larger limit is served as 50 and reported through requestedLimit and effectiveLimit. totalCount still reports every station near the point, so pass...default: 10
longitude*number
Center longitude for proximity search.
nws_list_alert_typesList all valid NWS alert event type names. Use to discover valid values for the event filter in nws_search_alerts, or to browse alert categories. No parameters required.

List all valid NWS alert event type names. Use to discover valid values for the event filter in nws_search_alerts, or to browse alert categories. No parameters required.

No parameters. Call it with no arguments.

nws_get_office_discussionGet the latest narrative forecast product from a Weather Forecast Office (WFO). The default product is AFD (Area Forecast Discussion), which explains the meteorological reasoning behind the forecast — synoptic setup, model guidance, and forecaster confidence. Other types: HWO...3 params

Get the latest narrative forecast product from a Weather Forecast Office (WFO). The default product is AFD (Area Forecast Discussion), which explains the meteorological reasoning behind the forecast — synoptic setup, model guidance, and forecaster confidence. Other types: HWO...

Parameters* required
office*string
Product location code of 2–3 letters or digits, case-insensitive — usually the 3-letter Weather Forecast Office (WFO) code (e.g., "SEW" for Seattle, "LOX" for Los Angeles), returned as the "office"...
product_typestring
Product type code. AFD (Area Forecast Discussion) — meteorological reasoning, model analysis, forecaster confidence. HWO (Hazardous Weather Outlook) — 1-7 day outlook for severe weather, flooding,...one of AFD · HWO · ZFP · SPS · FWFdefault: AFD
sectionsarray
Sections to return instead of the whole product: AFD section names, case-insensitive (e.g., "DISCUSSION", "AVIATION"), or zone codes for ZFP/HWO/SPS/FWF (e.g., "WAZ315"; a code inside a listed rang...
nws_get_zone_forecastGet the text forecast for an NWS forecast zone. Returns named forecast periods (e.g., "Today", "Tonight", "Monday") with detailed narrative text — the human-readable, zone-level forecast written by local forecasters. Completes the alert-to-forecast chain: nws_search_alerts ret...1 params

Get the text forecast for an NWS forecast zone. Returns named forecast periods (e.g., "Today", "Tonight", "Monday") with detailed narrative text — the human-readable, zone-level forecast written by local forecasters. Completes the alert-to-forecast chain: nws_search_alerts ret...

Parameters* required
zone_id*string
NWS forecast zone code (e.g., "WAZ315" for the City of Seattle, or a marine zone such as "PZZ251"). Returned as "forecastZone" by nws_get_forecast and nws_find_stations, or as the "code" of an "aff...

Sponsors

Configuration

NWS_USER_AGENTdefault: (nws-weather-mcp-server, github.com/cyanheads/nws-weather-mcp-server)

User-Agent header for NWS API requests. The API requires this header but a default is provided.

MCP_LOG_LEVELdefault: info

Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').

MCP_TRANSPORT_TYPEdefault: http

Selects the HTTP transport.

MCP_HTTP_HOSTdefault: 127.0.0.1

The hostname for the HTTP server.

MCP_HTTP_PORTdefault: 3010

The port to run the HTTP server on.

MCP_HTTP_ENDPOINT_PATHdefault: /mcp

The endpoint path for the MCP server.

MCP_AUTH_MODEdefault: none

Authentication mode to use: 'none', 'jwt', or 'oauth'.

Readme

@cyanheads/nws-weather-mcp-server

Get US weather forecasts, active and recent alerts, and current observations via the National Weather Service API. STDIO or Streamable HTTP.

10 Tools • 2 Resources

Details

Repository
github.com/cyanheads/nws-weather-mcp-server
Package
@cyanheads/nws-weather-mcp-server
Transport
STDIO, HTTP
Registry
MCP registry, active
Resources
2
Tools verified
Nov 13, 2026

More from cyanheads