@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
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
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. |
| One alert message by ID, current or superseded (~7-day retention). |
| 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, FWF) from a Weather Forecast Office; a product too large to inline comes back as a section outline. |
| Text forecast periods for an NWS forecast zone. |
Resources
Resource | Description |
| Static list of all valid NWS alert event type names. |
| Decision 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.
Related MCP server: weather
Capability reference
nws_get_forecast tool
latitude+longitude; returns 14 named 12-hour periods (~7 days) by default, or withhourly: trueone-hour periods with dewpoint and humidity, 48 per page of the ~156 upstreamnextCursorcarries its mode, so an hourly walk continues hourly without resendinghourly: trueinclude_amounts: trueadds every nativequantitativePrecipitation,snowfallAmount, andiceAccumulationinterval asprecipitationAmounts(layer,uom,valueswithvalidTimeandvalue), plus the separateamountsUpdateTime. 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 innotice; present empty layers carryvalues: []. 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, besidegeneratedAt; anoticeflags a grid not updated in more than 24 hoursReturns the
forecastZoneandcountyzone codes for chaining intonws_search_alertsMarine coordinates fail with
marine_forecast_unsupported, and land points NWS serves no forecast grid for fail 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)limit(default 25) is capped at 25; a larger limit is served as 25 and reported throughrequestedLimit/effectiveLimitnextCursorcarries the query's filters and page size, so pass it back ascursoron its own; filters sent with it are ignoredEach
affectedZonesentry carries its zonetype(forecast/county/fire);referenceslists superseded messages newest first bysent; apointoutside NWS coverage fails withinvalid_pointEach alert carries
office(the issuing office code fornws_get_office_discussion, e.g.RIW), rawvtecstrings, thenwsHeadline, andhazardtags such asmaxHailSizeandmaxWindGust, verbatim
nws_get_alert tool
alert_id: an alertidfromnws_search_alerts, or areferences[].identifierfrom any alert; returns{ alert }in the same shape asnws_search_alerts, including superseded messagesA 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), 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, in/mm), temperatures to one decimal; 1-, 3-, and 6-hour precipitation amounts from hourly reports, with
0a trace andnullno 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(fromnws_find_stations); optionalstart(inclusive) andend(exclusive) as ISO 8601 date-times with seconds and an offset; newest first, back through the ~7 days NWS keepslimit(default 24) is capped at 100; a larger limit is served as 100 and reported throughrequestedLimit/effectiveLimitEach 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 older observations remain; there is nototalCount, since NWS reports none for a window
nws_find_stations tool
latitude+longitude; optionallimit(default 10) is capped at 50; a larger limit is served as 50 and reported throughrequestedLimit/effectiveLimitNearest 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: usually the 3-letter WFO code (e.g., "SEW" for Seattle) returned as theofficefield bynws_get_forecast;product_type:AFD(default),HWO,ZFP,SPS, orFWF(Fire Weather Planning Forecast)Returns
productTextplusissuanceTime,issuingOffice,productName,productCode,wmoCollectiveId;content[]carries the product text in atextcode block, so fixed-width tables keep their columns; an unknown office, or one with no current product of the requested type, fails withno_productsA product too large to inline (most ZFPs and FWFs) returns an
outlineof its sections instead ofproductText; passsections(AFD section names, or zone codes for ZFP/HWO/SPS/FWF) to get the matching sections, and an unknown name fails withunknown_sectionAn alert zone typed
firegets its forecast from the FWF:officefrom the alert'sofficefield,product_type: "FWF",sections: [<zone code>]
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###) and unknown zone codes fail withzone_not_found, and so do most fire zone codes, whose forecast is their segment of the office FWF onnws_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 withmarine_forecast_unsupported, and land zones with none withzone_forecast_unavailable
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 — pass the returned
nextCursorback ascursorfor 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, andnws_search_alertsGuidance over silence — empty, truncated, or cursor-past-end results carry a
noticenaming the cause and the next stepTyped error reasons (
invalid_area_code,no_products,zone_not_found, …) so callers branch on data, not string parsingDual-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:
claude mcp add --transport http nws-weather-mcp-server https://nws.caseyjhand.com/mcpOr run it locally:
claude mcp add nws-weather-mcp-server -- npx -y @cyanheads/nws-weather-mcp-serverFor other clients, add this to the MCP config file:
{
"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
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
Source development requires Bun v1.4+. The published executable also runs on Node.js v24+.
git clone https://github.com/cyanheads/nws-weather-mcp-server.git
cd nws-weather-mcp-server && bun install
cp .env.example .envBuild 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
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/nws-weather-mcp-server:latestThe 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
Directory | Purpose |
|
|
| Published agent skills, also served over MCP. |
| 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 NWS weather alerts and 5-day forecasts for AI agents. $0.01 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.
Active National Weather Service warnings for any US ZIP code. Free weather_alerts tool.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides US weather alerts and forecasts via the National Weather Service API.89 npmGPL 3.0
- FlicenseNot gradedqualityDmaintenanceProvides weather forecasts, current conditions, and alerts for US locations using the National Weather Service API.1-
- AlicenseNot gradedqualityDmaintenanceProvides weather alerts and forecasts for US locations using the National Weather Service API.GPL 3.0
- FlicenseBqualityDmaintenanceProvides weather forecasts and active alerts from the US National Weather Service API for US locations.2-