Nws Weather Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.12.0Updated Oct 29, 2026

Get US weather forecasts, active alerts, and current observations.

VerifiedStreamable HTTPWeb executableLocation & LifestyleData & Analytics

Overview

AI-generated overview

Serves real-time US National Weather Service data: forecasts, active alerts, station observations, and forecaster discussions for any US point.

What you can do
  • Get point forecasts for coordinates, as 7-day named periods or paged hourly data, with optional precipitation amounts
  • Search, read and count active weather alerts by area, point, zone, event, severity, urgency or certainty, and list valid alert types
  • Read current conditions and up to about 7 days of observation history for a station, and find nearby stations by distance and bearing
  • Fetch forecast office narrative products (AFD, HWO, ZFP, SPS, FWF) and zone-level text forecasts, with section outlines for large products
When to use it
Useful when an assistant needs current or forecast US weather, active watches and warnings, measured conditions at a station, or the reasoning behind a forecast. Covers the 50 states, US territories and adjacent marine areas, and needs no API key.
Requirements
Either the hosted HTTP endpoint or a local process via npx (Node.js v24+ for the published executable; Bun v1.4+ only for source builds). No account or API key. NWS_USER_AGENT optionally sets the contact identifier sent to NWS; MCP_HTTP_HOST, MCP_HTTP_PORT, MCP_TRANSPORT_TYPE, MCP_AUTH_MODE and MCP_LOG_LEVEL configure the server itself. Network access to the NWS API is required.
Before you install
Read-only lookups; no data is written or sent on the user's behalf. The API does not geocode, so place names must be resolved to coordinates first. Coverage is US-only, point forecasts are land-only, and marine or fire zones may return typed errors. The hosted endpoint is a third-party server, so requests and query locations pass through it.

Installation

In SourceWeft

  1. Open Nws Weather Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Fnws-weather-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "nws-weather": {
      "type": "http",
      "url": "https://nws.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/nws-weather-mcp-server

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

10 Tools • 2 Resources

Public Hosted Server: https://nws.caseyjhand.com/mcp


Overview

Real-time US weather from the National Weather Service: forecasts, active alerts, current conditions, and forecaster discussions for any point in the 50 states and US territories, plus zone forecasts, coastal and marine alerts, and a week of station history. No API key required.

Tools

ToolDescription
nws_get_forecast7-day or hourly forecast for coordinates. Resolves NWS grid internally.
nws_search_alertsActive weather alerts filtered by area, point, zone, event, severity, urgency, certainty, and status.
nws_get_alertOne alert message by ID, current or superseded (~7-day retention).
nws_get_alert_countsActive alert counts nationwide, per state/territory or marine area, and per marine region.
nws_get_observationsCurrent conditions by coordinates (nearest station) or station ID.
nws_get_observation_historyA station's recent observations, newest first, paged back through the ~7 days NWS keeps.
nws_find_stationsNearby observation stations sorted by distance with bearing.
nws_list_alert_typesAll valid alert event type names for filter discovery.
nws_get_office_discussionLatest narrative product (AFD, HWO, ZFP, SPS, FWF) from a Weather Forecast Office; a product too large to inline comes back as a section outline.
nws_get_zone_forecastText forecast periods for an NWS forecast zone.

Resources

ResourceDescription
nws://alert-typesStatic list of all valid NWS alert event type names.
skill://nws-weather-guide/SKILL.mdDecision gates for combining forecasts, alerts, station trends, and forecaster discussions.

Alert types are also reachable via nws_list_alert_types. The weather guide is available through the MCP Skills extension and in the plugin's skills/ directory.

Capability reference

nws_get_forecast tool

  • latitude + longitude; returns 14 named 12-hour periods (~7 days) by default, or with hourly: true one-hour periods with dewpoint and humidity, 48 per page of the ~156 upstream
  • nextCursor carries its mode, so an hourly walk continues hourly without resending hourly: true
  • include_amounts: true adds every native quantitativePrecipitation, snowfallAmount, and iceAccumulation interval as precipitationAmounts (layer, uom, values with validTime and value), plus the separate amountsUpdateTime. Default false; resend it on any cursor page that needs amounts. Interval strings, units, zeroes, and nulls stay unchanged. Missing layers and unavailable amounts are explained in notice; present empty layers carry values: []. Absent units or update time are null. An unavailable amount feed leaves the main forecast available.
  • Returns updateTime, when the grid's forecast data was last updated, beside generatedAt; a notice flags a grid not updated in more than 24 hours
  • Returns the forecastZone and county zone codes for chaining into nws_search_alerts
  • Marine coordinates fail with marine_forecast_unsupported, and land points NWS serves no forecast grid for fail with no_forecast_grid

nws_search_alerts tool

  • At most one location filter (area, point, zone, region_type, or region), or none for a national search; event matches case-insensitively and partially; status defaults to Actual (also Exercise, System, Test, Draft)
  • limit (default 25) is capped at 25; a larger limit is served as 25 and reported through requestedLimit/effectiveLimit
  • nextCursor carries the query's filters and page size, so pass it back as cursor on its own; filters sent with it are ignored
  • Each affectedZones entry carries its zone type (forecast/county/fire); references lists superseded messages newest first by sent; a point outside NWS coverage fails with invalid_point
  • Each alert carries office (the issuing office code for nws_get_office_discussion, e.g. RIW), raw vtec strings, the nwsHeadline, and hazard tags such as maxHailSize and maxWindGust, verbatim

nws_get_alert tool

  • alert_id: an alert id from nws_search_alerts, or a references[].identifier from any alert; returns { alert } in the same shape as nws_search_alerts, including superseded messages
  • A malformed ID, an unknown one, and one past NWS's ~7-day retention all fail with alert_not_found

nws_get_alert_counts tool

  • No input; returns national totalAlerts (landAlerts + marineAlerts), plus areas counts keyed by state/territory or marine area code and regions counts keyed by marine region (AL, AT, GL, GM, PA, PI), each listing only codes with an active alert
  • Counts cover every message status, Test and Exercise included, so totalAlerts can exceed a national nws_search_alerts totalCount (status: Actual by default); an alert counts once in each area its zones fall in, so areas can sum past totalAlerts

nws_get_observations tool

  • Look up by coordinates (resolves nearest station) or station_id directly
  • Dual-unit display on every measurement (F/C, mph/km/h, inHg/hPa, mi/km, in/mm), temperatures to one decimal; 1-, 3-, and 6-hour precipitation amounts from hourly reports, with 0 a trace and null no amount reported; observations older than 2 hours carry a staleness notice, and a separate warning flags a station with most measurements unavailable

nws_get_observation_history tool

  • station_id (from nws_find_stations); optional start (inclusive) and end (exclusive) as ISO 8601 date-times with seconds and an offset; newest first, back through the ~7 days NWS keeps
  • limit (default 24) is capped at 100; a larger limit is served as 100 and reported through requestedLimit/effectiveLimit
  • Each observation carries the nws_get_observations measurement fields, null where the station reported nothing; an unknown station fails with station_not_found, and a malformed window or a start not before end with invalid_time_window
  • nextCursor appears only when older observations remain; there is no totalCount, since NWS reports none for a window

nws_find_stations tool

  • latitude + longitude; optional limit (default 10) is capped at 50; a larger limit is served as 50 and reported through requestedLimit/effectiveLimit
  • Nearest first; each result carries the station ID for nws_get_observations, distance (km), bearing, zone codes, elevation, and time zone

nws_list_alert_types tool

  • Returns the full set of event types the NWS API recognizes (e.g., "Tornado Warning", "Heat Advisory")
  • Use to discover valid values for the event filter in nws_search_alerts

nws_get_office_discussion tool

  • office: usually the 3-letter WFO code (e.g., "SEW" for Seattle) returned as the office field by nws_get_forecast; product_type: AFD (default), HWO, ZFP, SPS, or FWF (Fire Weather Planning Forecast)
  • Returns productText plus issuanceTime, issuingOffice, productName, productCode, wmoCollectiveId; content[] carries the product text in a text code block, so fixed-width tables keep their columns; an unknown office, or one with no current product of the requested type, fails with no_products
  • A product too large to inline (most ZFPs and FWFs) returns an outline of its sections instead of productText; pass sections (AFD section names, or zone codes for ZFP/HWO/SPS/FWF) to get the matching sections, and an unknown name fails with unknown_section
  • An alert zone typed fire gets its forecast from the FWF: office from the alert's office field, product_type: "FWF", sections: [<zone code>]

nws_get_zone_forecast tool

  • zone_id: forecast zone code (e.g., "WAZ315") — returned by nws_get_forecast (forecastZone), nws_find_stations (forecastZone column), and nws_search_alerts (the code of an affectedZones entry with type: "forecast")
  • Returns named periods (e.g., "Today", "Tonight", "Monday") with narrative text from local forecasters
  • County (XXC###) and unknown zone codes fail with zone_not_found, and so do most fire zone codes, whose forecast is their segment of the office FWF on nws_get_office_discussion; a fire code that is also a public zone code returns the public zone's forecast; marine zones with no text forecast fail with marine_forecast_unsupported, and land zones with none with zone_forecast_unavailable

nws://alert-types resource

  • Static list of all valid NWS alert event type names, returned as application/json
  • No parameters; cached publicly for 1 hour

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

NWS-specific:

  • Sends the required User-Agent header automatically (configurable via NWS_USER_AGENT) — NWS returns 403 without one
  • Automatic coordinate-to-grid resolution via /points, cached for 1h since grid cells rarely change
  • Request timeouts plus retry/backoff for transient NWS API failures
  • Zero-auth access — no API keys required
  • Paged results — pass the returned nextCursor back as cursor for the next page (omitted on the last page)

Agent-friendly output:

  • Provenance — responses echo office codes, time zones, and zone codes so agents can chain into nws_get_office_discussion, nws_get_zone_forecast, and nws_search_alerts
  • Guidance over silence — empty, truncated, or cursor-past-end results carry a notice naming the cause and the next step
  • Typed error reasons (invalid_area_code, no_products, zone_not_found, …) so callers branch on data, not string parsing
  • Dual-unit measurements (F/C, mph/km/h, inHg/hPa, mi/km, in/mm), rounded to match the text output

Getting started

Connect to the hosted instance, no install:

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

Or run it locally:

sh
claude mcp add nws-weather-mcp-server -- npx -y @cyanheads/nws-weather-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "nws-weather-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/nws-weather-mcp-server"]    }  }}

NWS_USER_AGENT optionally sets the contact identifier sent to NWS. For Docker or a source build, see Running the server.

Configuration

VariableDescriptionDefault
NWS_USER_AGENTUser-Agent for NWS API requests. The API requires this header.(nws-weather-mcp-server, ...)
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_HTTP_HOSTHostname for HTTP server.127.0.0.1
MCP_SESSION_MODEHTTP session mode: stateful, stateless, or auto.stateless
MCP_LOG_LEVELLog level: debug, info, notice, warning, error.info

See .env.example for the full list including auth, storage, and OpenTelemetry options.

Running the server

Local development

Source development requires Bun v1.4+. The published executable also runs on Node.js v24+.

sh
git clone https://github.com/cyanheads/nws-weather-mcp-server.gitcd nws-weather-mcp-server && bun installcp .env.example .env
  • Build and run the production version:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:http# orbun run start:stdio
  • Run checks and tests:

    sh
    bun run devcheck     # Lints, formats, type-checksbun run test         # Runs test suite

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/nws-weather-mcp-server:latest

The image defaults to HTTP transport, stateless session mode, and logs to /var/log/nws-weather-mcp-server. To run it over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/nws-weather-mcp-server:latest"]. To build locally, docker build -t nws-weather-mcp-server .; OpenTelemetry peers are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools, the alert-types resource, and published skills.
skills/Published agent skills, also served over MCP.
src/mcp-server/tools/definitions/Tool definitions (*.tool.ts).
src/mcp-server/resources/definitions/Resource definitions (*.resource.ts).
src/services/nws/NWS API client and response types.
src/config/Environment variable parsing and validation with Zod.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for domain-specific logging, ctx.state for storage
  • Add new tools/resources to the barrel exports and the createApp() arrays in src/index.ts
  • Wrap NWS API calls: validate raw JSON → normalize to domain types → return the output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks before submitting:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit 7229c3c

Tools

10

nws_get_forecast

Nws Get Forecast

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

Parameterscursorhourlylatituderequiredlongituderequiredinclude_amounts

nws_search_alerts

Nws Search Alerts

Search active weather alerts (watches, warnings, advisories) across the US. Filter by state, coordinates, zone, land/marine region, event type, severity, urgency, or certainty. area, point, zone, region_type, and region are mutually exclusive — provide at most one. Omit all filters for a national search.

Parametersareazoneeventlimitpointcursorregionstatusurgencyseveritycertaintyregion_type

nws_get_alert

Nws Get Alert

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 same alert fields nws_search_alerts does. The message carries its own references, newest first, so a revision chain is walked one call per message. Every reference sharing the newest sent time is an immediate predecessor (an update can merge several earlier segments), so references[0] is one of them, not always the only one. NWS serves messages for about 7 days after they are sent.

Parametersalert_idrequired

nws_get_alert_counts

Nws Get Alert Counts

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 included, so totalAlerts can run above the totalCount a national nws_search_alerts search reports under its default status of Actual. An alert counts once in each area its zones fall in, so the area counts can sum past totalAlerts; landAlerts plus marineAlerts equals totalAlerts. Takes no filters. For counts per zone or under a filter, call nws_search_alerts with that zone or filter and read its totalCount.

Takes no parameters.

nws_get_observations

Nws Get Observations

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

Parameterslatitudelongitudestation_id

nws_get_observation_history

Nws Get Observation History

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 minutes, so a day can run past 100 observations: narrow with start (inclusive) and end (exclusive), and page back to older observations with nextCursor. Takes a station ID; use nws_find_stations to find one near a coordinate.

Parametersendlimitstartcursorstation_idrequired

nws_find_stations

Nws Find Stations

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.

Parameterslimitcursorlatituderequiredlongituderequired

nws_list_alert_types

Nws List Alert Types

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.

Takes no parameters.

nws_get_office_discussion

Nws Get Office Discussion

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 (Hazardous Weather Outlook, 1-7 day severe/flood/winter outlook), ZFP (Zone Forecast Product, zone-by-zone text), SPS (Special Weather Statement, short-fuse advisory), FWF (Fire Weather Planning Forecast, one segment per fire weather zone). The office code is the 3-letter WFO identifier returned as the "office" field by nws_get_forecast. A product over 24,000 bytes (most ZFPs and FWFs) comes back as an outline of its sections — AFD section names, or ZFP/HWO/SPS/FWF zone segments with their area names — with each section's size, instead of the text; re-call with sections to get the ones you need. sections also works on a product of any size, to read one AFD section or one zone's forecast. For an alert zone typed "fire" (Red Flag Warning, Fire Weather Watch), pass the alert's "office" field as office, product_type "FWF", and the zone code in sections.

Parametersofficerequiredsectionsproduct_type

nws_get_zone_forecast

Nws Get Zone Forecast

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 returns each affected zone in "affectedZones" as a code plus a type, and nws_find_stations returns codes in the "forecastZone" column. Only affectedZones entries with type "forecast" work here; entries typed "county" have no text forecast upstream and will not resolve. An entry typed "fire" has its forecast in a segment of the office's Fire Weather Planning Forecast: call nws_get_office_discussion with office set to the alert's "office" field, product_type "FWF", and sections set to the zone code; a fire zone code that is also a public zone code (e.g., "NDZ040") returns that public zone's forecast here, not the fire weather forecast. Marine forecast zones vary: many coastal zones serve a text forecast of wind and seas (e.g., "PZZ251"), while offshore zones (e.g., "GMZ056") and some coastal ones have none. Zone codes follow the pattern XXZ### (e.g., "WAZ315" for the City of Seattle).

Parameterszone_idrequired

Version history

8
  1. v0.12.0LatestOct 29, 2026
  2. v0.11.2Oct 25, 2026
  3. v0.11.1Oct 23, 2026
  4. v0.11.0Oct 16, 2026
  5. v0.10.0Sep 30, 2026
  6. v0.9.5Sep 25, 2026
  7. v0.9.4Sep 19, 2026
  8. v0.9.3Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts