@cyanheads/nws-weather-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/nws-weather-mcp-serverWhat's the forecast for Denver, CO?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://nws.caseyjhand.com/mcp
Overview
US weather data from the National Weather Service API (api.weather.gov). Get forecasts, active alerts, current observations, forecast-office narrative products, and zone-level text forecasts for any coordinate in the 50 states and US territories, plus national alert counts and a station's last ~7 days of observations. Adjacent marine areas are covered by alerts, plus stations and observations near the coast; NWS publishes no point or zone text forecast for them. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| 7-day or hourly forecast for coordinates. Resolves NWS grid internally. |
| Active weather alerts filtered by area, point, zone, event, severity, urgency, certainty, and status. |
| Active alert counts nationwide, per state/territory or marine area, and per marine region. |
| Current conditions by coordinates (nearest station) or station ID. |
| A station's recent observations, newest first, paged back through the ~7 days NWS keeps. |
| Nearby observation stations sorted by distance with bearing. |
| All valid alert event type names for filter discovery. |
| Latest narrative product (AFD, HWO, ZFP, SPS) from a Weather Forecast Office. |
| Text forecast periods for a public NWS forecast zone. |
Resources
Resource | Description |
| Static list of all valid NWS alert event type names. |
Also reachable via the nws_list_alert_types tool, for MCP clients that don't support resources.
Related MCP server: weather-mcp
Capability reference
nws_get_forecast tool
latitude+longitude; returns named 12-hour periods by default (14, ~7 days), or withhourly: trueone-hour periods with dewpoint and humidity, 48 per page of the ~156 upstreamReturns the
forecastZoneandcountyzone codes for chaining intonws_search_alerts; marine coordinates fail with a typedmarine_forecast_unsupportederror pointing to a nearby land point ornws_search_alerts, and land points NWS serves no forecast grid for withno_forecast_grid
nws_search_alerts tool
At most one location filter —
area,point,zone,region_type, orregion— or none for a national search;eventmatches case-insensitively and partially;statusdefaults toActual(alsoExercise,System,Test,Draft);limit1-25 (default 25) per pageEach
affectedZonesentry carries its zonetype(forecast/county/fire), marking which codes chain intonws_get_zone_forecast; CAP message-lifecycle fields (sent,effective,status,messageType,references) are distinct from the hazard's ownonset/ends
nws_get_alert_counts tool
No input; returns national
totalAlerts(landAlerts+marineAlerts), plusareascounts keyed by state/territory or marine area code andregionscounts keyed by marine region (AL,AT,GL,GM,PA,PI), each listing only codes with an active alertCounts cover every message status, Test and Exercise included, so
totalAlertscan exceed a nationalnws_search_alertstotalCount(status: Actualby default); an alert counts once in each area its zones fall in, soareascan sum pasttotalAlerts
nws_get_observations tool
Look up by coordinates (resolves nearest station) or
station_iddirectlyDual-unit display on every measurement (F/C, mph/km/h, inHg/hPa, mi/km); 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(fromnws_find_stations); optionalstart(inclusive) andend(exclusive) as ISO 8601 date-times with seconds and an offset;limit1-100 (default 24) per page, newest first, back through the ~7 days NWS keepsEach observation carries the
nws_get_observationsmeasurement fields,nullwhere the station reported nothing; an unknown station fails withstation_not_found, and a malformed window or astartnot beforeendwithinvalid_time_windownextCursorappears only when a page fillslimit, and pages neither repeat nor skip an observation; nototalCount, since NWS reports none for a window
nws_find_stations tool
latitude+longitude; optionallimit(1-50, default 10) sizes the pageNearest 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
eventfilter innws_search_alerts
nws_get_office_discussion tool
office: 3-letter WFO code (e.g., "SEW" for Seattle), returned as theofficefield bynws_get_forecast;product_type:AFD(default),HWO,ZFP, orSPSReturns
productTextplusissuanceTime,issuingOffice,productName,productCode,wmoCollectiveId; an unknown office, or a valid office with no current product of the requested type, fails with a typedno_productserror
nws_get_zone_forecast tool
zone_id: forecast zone code (e.g., "WAZ315") — returned bynws_get_forecast(forecastZone),nws_find_stations(forecastZonecolumn), andnws_search_alerts(thecodeof anaffectedZonesentry withtype: "forecast")Returns named periods (e.g., "Today", "Tonight", "Monday") with narrative text from local forecasters; county (
XXC###), fire, and unknown zone codes fail with a typedzone_not_founderror, marine forecast zones (e.g.,PZZ251) withmarine_forecast_unsupported, and a valid zone NWS publishes no text forecast for withzone_forecast_unavailable, which carries a point inside the zone fornws_get_forecast
nws://alert-types resource
Static list of all valid NWS alert event type names, returned as
application/jsonNo 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-Agentheader automatically (configurable viaNWS_USER_AGENT) — NWS returns 403 without oneAutomatic coordinate-to-grid resolution via
/points, cached for 1h since grid cells rarely changeRequest timeouts plus retry/backoff for transient NWS API failures
Zero-auth access — no API keys required
Paged results —
nws_get_forecast,nws_find_stations, andnws_search_alertsreporttotalCountagainst this page'sshown, andnws_get_observation_historyreportsshownalone (NWS gives no total for a time window); pass the returnednextCursorback ascursorfor the next page (omitted on the last page)
Agent-friendly output:
Provenance — forecast, observation, and station responses echo office codes, time zones, and forecast/county zone codes so agents can chain directly into
nws_get_office_discussion,nws_get_zone_forecast, andnws_search_alertswithout re-deriving themGuidance over silence — empty, truncated, or cursor-past-end results carry a
noticenaming the cause and the concrete next step, rather than an empty array or a bare pageDiscriminated output contracts — zone
type(forecast/county/fire), CAPstatus/messageTypedistinct from hazardonset/ends, and typed error reasons (invalid_area_code,no_products,zone_not_found, …) — callers branch on data, not string parsingResponse shaping — upstream single-unit floats are normalized into dual-unit pairs (F/C, mph/km/h, inHg/hPa, mi/km) and rounded to match what
format()renders, so structured and text output agree
Getting started
Public Hosted Instance
A public instance is available at https://nws.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"nws-weather-mcp-server": {
"type": "streamable-http",
"url": "https://nws.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"nws-weather-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/nws-weather-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"nws-weather-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/nws-weather-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"nws-weather-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/nws-weather-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_SESSION_MODE=stateless MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Installation
Clone the repository:
git clone https://github.com/cyanheads/nws-weather-mcp-server.gitNavigate into the directory:
cd nws-weather-mcp-serverInstall dependencies:
bun installConfiguration
Variable | Description | Default |
| User-Agent for NWS API requests. The API requires this header. |
|
| Transport: |
|
| Port for HTTP server. |
|
| Hostname for HTTP server. |
|
| HTTP session mode: |
|
| Log level: |
|
See .env.example for the full list including auth, storage, and OpenTelemetry options.
Running the server
Local development
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks bun run test # Runs test suite
Project structure
Directory | Purpose |
|
|
| Tool definitions ( |
| Resource definitions ( |
| NWS API client and response types. |
| Environment variable parsing and validation with Zod. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor domain-specific logging,ctx.statefor storageAdd new tools/resources to the barrel exports and the
createApp()arrays insrc/index.tsWrap 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:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
US weather for AI agents: active NWS alerts by state, 5-period forecasts by lat/lon. Paid per call.
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
US weather alerts (NWS): warnings, watches. $0.01/query. Register in-session — free testnet funds.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides weather alerts and forecasts for US locations using the National Weather Service API.134 npmGPL 3.0
- AlicenseNot gradedqualityDmaintenanceProvides US weather alerts and forecasts via the National Weather Service API.134 npmGPL 3.0
- FlicenseNot gradedqualityDmaintenanceProvides weather forecasts, current conditions, and alerts for US locations using the National Weather Service API.1-
- FlicenseBqualityDmaintenanceProvides weather forecasts and active alerts from the US National Weather Service API for US locations.2-