Fetch METARs, TAFs, PIREPs, and domestic SIGMETs from the NWS Aviation Weather Center.
Fetch METARs, TAFs, PIREPs, and domestic SIGMETs from the NWS Aviation Weather Center via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://aviation-weather.caseyjhand.com/mcp
Aviation weather from the NWS Aviation Weather Center — METARs, TAFs, PIREPs, and domestic SIGMETs. Look up stations, fetch current and forecast conditions, and pull pilot reports and hazard advisories from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
aviation_find_stations | Resolve airports and weather stations by identifier, bounding box, or US state. Returns ICAO/IATA/FAA IDs, coordinates, elevation, and available data types. |
aviation_get_metar | Get current weather observations (METARs) for named airports, or survey every reporting station in a bounding box. Returns decoded wind, visibility, ceiling, present weather, temp/dewpoint, altimeter, cloud layers, flight category (VFR/MVFR/IFR/LIFR), and the raw METAR string. |
aviation_get_taf | Get Terminal Aerodrome Forecasts for one or more airports. Returns each forecast period with valid times, surface wind, low-level wind shear, visibility, decoded weather, cloud layers, and vertical visibility into a forecast obscuration, plus the raw TAF string. |
aviation_get_pireps | Get recent Pilot Reports near an airport or within a bounding box. Returns decoded turbulence, icing, and cloud reports with altitude, aircraft type, intensity, and the raw PIREP string. |
aviation_get_advisories | Get active domestic SIGMETs for a region. Returns hazard type (CONVECTIVE, TURBULENCE, ICING, IFR), severity, altitude range, valid period, polygon coordinates, and raw text. |
| Prompt | Description |
|---|---|
aviation_preflight_brief | Structure a preflight weather briefing for a flight, calling the tools above in sequence and synthesizing a weather-risk summary. |
aviation_find_stations toolKSEA, K0S9); a 3-letter IATA code never resolves, though each record includes its IATA/FAA aliases when availabledata_types (METAR, TAF, etc.) so agents can confirm what's available before queryinglimit (1–400) bounds how many stations a bbox or state search returns, ordered by ICAO identifier ascending with identifier-less stations last — rejected alongside station_ids, since that mode already names the setaviation_get_metar toolstation_ids (1–10 per call — 4 uppercase letters or digits, so K0S9-style identifiers work) for named airports, or bbox to survey every reporting station in an area — mutually exclusivehours (1–12) is a lookback window, not a row limit: with station_ids every observation inside it is returned, and with bbox the result is the latest observation per stationbbox survey states whether the upstream 400-row cap cut it and names hours as the first lever — a wide window spends the cap on repeat readings rather than on more stations; limit (1–400) bounds how many stations come back, ordered by station ID ascending, and is rejected alongside station_idssky_condition distinguishes a reported clear sky from an unreported one when clouds is emptymetar_type distinguishes routine METAR from special SPECI observationsaviation_get_taf toolFM, TEMPO, BECMG) and probabilities; weather decoded group by group beside the raw groupssky_condition distinguishes an unamended period from a stated clear skynot_decoded rather than droppedWS020/20040KT) decoded to the shear-layer top and forecast wind at that heightvalid_from / valid_to in ISO 8601 for time comparisonsaviation_get_pireps toolstation_id + distance_nm (10–500 nm, 100 when omitted) for radial search, or bbox for area search — mutually exclusive; a station_id AWC does not recognize as a search center returns a typed error pointing to aviation_find_stations or bboxaltitude_min_ft / altitude_max_ft filter to a cruise-altitude band in feet MSL, from 0 to 60000 ft (min must not exceed max); a report with unknown altitude is dropped once either bound is setmin_intensity (lgt / mod / sev) restricts to reports carrying a turbulence or icing layer at that intensity or above — a matching report still carries its lighter layerslimit (1–400) bounds how many reports come back, ordered by recencyaviation_get_advisories tooladvisory_type: sigmet or all (default) — both return the active SIGMET sethazard filter (CONVECTIVE, TURBULENCE, ICING, IFR) applied upstream by AWC; bbox filtered client-side by polygon overlapMTN OBSCN / SURFACE WIND / LLWS hazards) is rejected with guidance rather than answered with SIGMETsbbox — so a filter that needs broadening isn't mistaken for quiet weatheraviation_preflight_brief promptdeparture_icao and destination_icao required; alternates (comma-separated ICAOs), departure_time (ISO 8601 UTC), cruise_altitude (feet MSL), and route_waypoints (semicolon-separated lat,lon pairs) optionalaviation_get_metar, aviation_get_taf, aviation_get_pireps, and aviation_get_advisories in sequence, chunked to each tool's station-per-call limitdeparture_time selects the TAF forecast period the briefing is read against; cruise_altitude bounds the PIREP search to a ±3,000 ft band; route_waypoints become the advisories bbox, widened by 1° on each sideBuilt 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.
Aviation-weather-specific:
aviation-weather-service) with retry + exponential backoff for the keyless public endpointraw_metar, raw_taf, raw_pirep, raw_text) surfaced alongside decoded fields so agents have both layersinstructions field surfaces the "not an official briefing" safety disclaimer to all clients on initializeAgent-friendly output:
VFR/MVFR/IFR/LIFR) as a typed string field, so agents branch on it without parsing ceiling and visibilityreason fields with recovery hints (e.g., "Verify ICAO IDs with aviation_find_stations")requested / returned / missing / partial fields, so a short batch is never mistaken for full coverageaviation_preflight_brief prompt encodes the correct METAR → TAF → PIREPs → advisories sequence, chunks each step to the tool's station limit, and names the assessments it could not makeA public hosted instance is available at https://aviation-weather.caseyjhand.com/mcp. Add it to your MCP client configuration:
{
"mcpServers": {
"aviation-weather": {
"type": "streamable-http",
"url": "https://aviation-weather.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"aviation-weather": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/aviation-weather-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"aviation-weather": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/aviation-weather-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"aviation-weather": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/aviation-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
git clone https://github.com/cyanheads/aviation-weather-mcp-server.git
cd aviation-weather-mcp-server
bun install
cp .env.example .env
# edit .env if you need to override AWC_BASE_URL or AWC_TIMEOUT_MS
| Variable | Description | Default |
|---|---|---|
AWC_BASE_URL | Base URL for the NWS AWC Data API. | https://aviationweather.gov/api/data |
AWC_TIMEOUT_MS | Per-request timeout in milliseconds (1000–60000). | 10000 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_SESSION_MODE | HTTP session handling: auto (resolves to stateful), stateful, or stateless. The server declares stateless in code — no tool here needs a multi-round-trip input — and the shipped .env.example and Docker image pin the same value. Setting this overrides the declaration. | stateless |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
Build and run:
bun run rebuild
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t aviation-weather-mcp-server .
docker run --rm -p 3010:3010 aviation-weather-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/aviation-weather-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools/prompts and inits services. |
src/config | Server-specific env var parsing (AWC_BASE_URL, AWC_TIMEOUT_MS). |
src/services/aviation-weather | AWC Data API client — HTTP fetch, retry with exponential backoff, response normalization. |
src/mcp-server/tools | Tool definitions (*.tool.ts). |
src/mcp-server/prompts | Prompt definitions (*.prompt.ts). |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagecreateApp() arrays in src/index.tsNot an official preflight briefing. Data from the AWC is informational only. Real flight planning requires an authorized source (e.g., Leidos/1800wxbrief.com). The server surfaces this disclaimer via its
instructionsfield sent on everyinitialize.
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/aviation-weather-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-aviation-weather-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/aviation-weather-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/aviation-weather-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.