npm @cyanheads/nws-weather-mcp-serverstreamable-httpApache-2.0updated 14d ago
@cyanheads/nws-weather-mcp-server Get US weather forecasts, active alerts, and current observations via the National Weather Service API. STDIO or Streamable HTTP. 7 Tools • 1 Resource
What can you do with nws weather mcp server?
Public Hosted Server: https://nws.caseyjhand.com/mcp
Tools
Seven tools for real-time US weather data:
| Tool | Description |
|---|---|
nws_get_forecast |
7-day or hourly forecast for coordinates. Resolves NWS grid internally. |
nws_search_alerts |
Active weather alerts filtered by area, point, zone, event, severity, urgency, certainty, and status. |
nws_get_observations |
Current conditions by coordinates (nearest station) or station ID. |
nws_find_stations |
Nearby observation stations sorted by distance with bearing. |
nws_list_alert_types |
All valid alert event type names for filter discovery. |
nws_get_office_discussion |
Latest narrative product (AFD, HWO, ZFP, SPS) from a Weather Forecast Office. |
nws_get_zone_forecast |
Text forecast periods for a public NWS forecast zone. |
nws_get_forecast
Get the weather forecast for a US location.
- Default returns named 12-hour periods (14 total, ~7 days)
- Hourly mode returns 48 one-hour periods per page with dewpoint and humidity — the upstream feed carries ~156, and the pre-page total (
totalCount, against this page'sshown) plus a truncation notice are surfaced in the enrichment block - Pass the returned
nextCursorback ascursorto reach the remaining periods; it is omitted on the last page - Coordinates resolve to NWS grid internally via
/pointsendpoint - Formatted timestamps use the resolved local time zone
- Returns forecast zone and county zone codes for chaining into
nws_search_alerts
nws_search_alerts
Search active weather alerts with flexible filtering.
- Filter by area (state/territory/marine codes), point (lat,lon), zone, land/marine
region_type, marineregiongroups, event type, severity, urgency, certainty, or status area,point,zone,region_type, andregionare mutually exclusive; specify at most one location filter- National search when no filters provided
- A filter provided with no usable value — a blank
area/point/zone, or an emptyevent/severity/urgency/certainty/regionarray — is rejected rather than dropped, so a search never silently widens to national results - Each
affectedZonesentry carries its NWS zonetype(forecast,county, orfire) alongside thecode, so callers can tell which codes chain intonws_get_zone_forecast - Alerts include the CAP message lifecycle —
sent,effective,status,messageType, and the prior messages an updatereferences— distinct from the hazard's ownonset/ends - Event matching is case-insensitive and partial, so
"tornado"matches both watches and warnings statusdefaults to liveActualalerts, but can be set toExercise,System,Test, orDraft- Optional
limit(1–25, default 25) sizes the page;totalCountreports the full match count andshownthe size of this page, with a truncation notice and guidance to narrow filters - Alerts NWS repeats verbatim within one fetch are collapsed on
id, sototalCountcounts distinct alerts and a duplicate never straddles a page boundary - Pass the returned
nextCursorback ascursorto reach matches beyond the page. Consecutive pages are contiguous within one response only — every call re-fetches/alerts/active, and that set changes continuously as alerts are issued and expire - Validates area, point, and zone locally before the API call — malformed values fail fast as
invalid_area_code,invalid_point, orinvalid_zoneinstead of leaking a raw upstream 400
nws_get_observations
Current measured conditions from a weather station.
- Look up by coordinates (finds nearest station) or station ID directly
- A blank or whitespace-only
station_idis rejected rather than dropped, so coordinates never silently answer for a station that was asked for by name - Coordinate lookups choose the nearest station from the candidates returned by NWS
- Dual-unit display: F/C, mph/km/h, inHg/hPa, mi/km
- Observation timestamps use the station's local time zone when available
- Warns when most measurements are unavailable from a station
nws_find_stations
Discover nearby observation stations.
- Sorted by haversine distance from query point
- Returns distance (km) and compass bearing
- Includes zone codes, elevation, time zone
- Optional
limit(1–50, default 10) sizes the page;totalCountreports every station near the point and holds steady across pages, whileshownis the size of this page - Pass the returned
nextCursorback ascursorto reach stations beyond the page; it is omitted on the last page - Useful for finding station IDs for
nws_get_observations
nws_list_alert_types
List all valid NWS alert event type names.
- 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
Get the latest narrative product from a Weather Forecast Office (WFO).
office: 3-letter WFO code (e.g.,SEWfor Seattle) — returned as theofficefield bynws_get_forecastproduct_type:AFD(Area Forecast Discussion, default),HWO(Hazardous Weather Outlook),ZFP(Zone Forecast Product),SPS(Special Weather Statement)- Two-hop fetch: lists products by office/type (newest first), then retrieves full product text
- Returns
productTextplusissuanceTime,issuingOffice,productName,productCode,wmoCollectiveId - Unknown office returns a clear error with recovery instructions (the NWS API returns HTTP 200 with an empty list, not a 404)
nws_get_zone_forecast
Get the text forecast for a public NWS forecast zone.
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
- Completes the alert-to-forecast chain: look up alert zones, then retrieve zone forecasts
- County (
XXC###) and fire zone codes are not supported here — NWS publishes no text forecast for them. They remain valid values for thezonefilter onnws_search_alerts
Resources
| URI Pattern | Description |
|---|---|
nws://alert-types |
Static list of all valid NWS alert event type names. |
Features
Built on @cyanheads/mcp-ts-core:
- Declarative tool definitions — single file per tool, framework handles registration and validation
- Unified error handling across all tools
- Pluggable auth (
none,jwt,oauth) - Swappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1 - Structured logging with optional OpenTelemetry tracing
- Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
NWS-specific:
- Zero-auth access to the NWS API — no API keys required
- Automatic coordinate-to-grid resolution with caching (1h TTL)
- Request timeouts plus retry/backoff for transient NWS API failures
- Dual-unit display for observations (F/C, mph/km/h, inHg/hPa, mi/km)
- Continental US, Alaska, Hawaii, and US territories coverage
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_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
Installation
- Clone the repository:
git clone https://github.com/cyanheads/nws-weather-mcp-server.git
- Navigate into the directory:
cd nws-weather-mcp-server
- Install dependencies:
bun install
Configuration
| Variable | Description | Default |
|---|---|---|
NWS_USER_AGENT |
User-Agent for NWS API requests. The API requires this header. | (nws-weather-mcp-server, ...) |
MCP_TRANSPORT_TYPE |
Transport: stdio or http. |
stdio |
MCP_HTTP_PORT |
Port for HTTP server. | 3010 |
MCP_HTTP_HOST |
Hostname for HTTP server. | 127.0.0.1 |
MCP_SESSION_MODE |
HTTP session mode: stateful, stateless, or auto. |
stateless |
MCP_LOG_LEVEL |
Log 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
-
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
Run checks and tests:
bun run devcheck # Lints, formats, type-checks bun run test # Runs test suite
Project structure
| Directory | Purpose |
|---|---|
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. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor domain-specific logging,ctx.statefor storage - Add new tools/resources to the barrel exports and the
createApp()arrays insrc/index.ts
Contributing
Issues and pull requests are welcome. Run checks before submitting:
bun run devcheck
bun run test
License
Apache-2.0 — see LICENSE for details.
Install
Add nws weather mcp server to your client. Pick the one you use.
{
"servers": {
"nws-weather-mcp-server": {
"type": "http",
"url": "https://nws.caseyjhand.com/mcp"
}
}
}Add to `.vscode/mcp.json` in your workspace.
claude mcp add nws-weather-mcp-server -- npx -y @cyanheads/nws-weather-mcp-servercodex mcp add nws-weather-mcp-server -- npx -y @cyanheads/nws-weather-mcp-serveramp mcp add nws-weather-mcp-server -- npx -y @cyanheads/nws-weather-mcp-server{
"mcpServers": {
"nws-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"nws-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
{
"mcpServers": {
"nws-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"nws-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"nws-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"nws-weather-mcp-server": {
"type": "local",
"command": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"nws-weather-mcp-server": {
"command": {
"path": "npx",
"args": [
"-y",
"@cyanheads/nws-weather-mcp-server"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y @cyanheads/nws-weather-mcp-serverRun `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
7 tools
nws weather mcp server exposes 7 tools to a connected agent.
- nws_get_forecast
- 7-day or hourly forecast for coordinates. Resolves NWS grid internally.
- nws_search_alerts
- Active weather alerts filtered by area, point, zone, event, severity, urgency, certainty, and status.
- nws_get_observations
- Current conditions by coordinates (nearest station) or station ID.
- nws_find_stations
- Nearby observation stations sorted by distance with bearing.
- nws_list_alert_types
- All valid alert event type names for filter discovery.
- nws_get_office_discussion
- Latest narrative product (AFD, HWO, ZFP, SPS) from a Weather Forecast Office.
- nws_get_zone_forecast
- Text forecast periods for a public NWS forecast zone.
Score
87 / 100
Excellent
- Documentation25/25
- Maintenance25/25
- Trust13/20
- Capability9/15
- Install experience15/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 7 days ago
- Has a release history
- Repository is not archived
- Licensed Apache-2.0
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 7 tool(s) documented
- Provides prompt templates
- Provides resources
- 18 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
Version history
| Versions | Published |
|---|---|
| 0.9.1Latest | Aug 25, 2026 |
| 0.9.0 | Aug 13, 2026 |
| 0.8.0 | Aug 13, 2026 |
| 0.7.4 | Aug 13, 2026 |
| 0.7.3 | Aug 13, 2026 |
| 0.7.2 | Jul 2, 2026 |
| 0.7.1 | Jul 1, 2026 |
| 0.7.0 | Jun 30, 2026 |
| 0.6.5 | Jun 21, 2026 |
| 0.6.4 | Jun 20, 2026 |
| 0.6.3 | Jun 16, 2026 |
| 0.6.2 | Jun 13, 2026 |
| 0.6.1 | Jun 2, 2026 |
| 0.6.0 | May 30, 2026 |
| 0.5.13 | May 30, 2026 |
| 0.5.12 | May 29, 2026 |
| 0.5.11 | May 23, 2026 |
| 0.5.10 | May 23, 2026 |
| 0.5.9 | May 16, 2026 |
| 0.5.8 | May 9, 2026 |
| 0.5.7 | Apr 28, 2026 |
| 0.5.6 | Apr 24, 2026 |
| 0.5.5 | Apr 21, 2026 |
| 0.5.4 | Apr 19, 2026 |
| 0.5.3 | Apr 19, 2026 |
| 0.5.2 | Apr 15, 2026 |
| 0.5.1 | Apr 14, 2026 |
| 0.5.0 | Apr 14, 2026 |
| 0.4.0 | Apr 4, 2026 |
| 0.3.2 | Apr 4, 2026 |
| 0.3.1 | Apr 3, 2026 |