io.github.cyanheads/aviation-weather-mcp-server

Official registry Maps, travel and weather

METARs, TAFs, PIREPs, domestic/international SIGMETs and CWAs via NWS AWC. AIRMETs not served.

What can you do with io.github.cyanheads/aviation-weather-mcp-server?

  • Keyless — no API key or authentication required; all data is from the public AWC Data API
  • Single service (aviation-weather-service) with retry + exponential backoff for the keyless public endpoint
  • Raw coded strings (raw_metar, raw_taf, raw_pirep, raw_text) surfaced alongside decoded fields so agents have both layers
  • State→bbox table enables US-state station queries that the AWC API doesn't natively support
  • Server-level instructions field surfaces the "not an official briefing" safety disclaimer to all clients on initialize
  • Discriminated output — flight category (VFR/MVFR/IFR/LIFR) as a typed string field, so agents branch on it without parsing ceiling and visibility
  • Structured error contracts — typed reason fields with recovery hints (e.g., "Verify ICAO IDs with aviation_find_stations")
  • Partial-result reconciliation — batch tools report requested / returned / missing / partial fields, so a short batch is never mistaken for full coverage

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

Remote (streamable-http)
Claude Code
claude mcp add --transport http aviation-weather-mcp-server 'https://aviation-weather.caseyjhand.com/mcp'
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "aviation-weather-mcp-server": {
            "type": "http",
            "url": "https://aviation-weather.caseyjhand.com/mcp"
        }
    }
}
NPM package @cyanheads/aviation-weather-mcp-server
Claude Code
claude mcp add aviation-weather-mcp-server -e 'MCP_LOG_LEVEL=info' -e 'AWC_BASE_URL=https://aviationweather.gov/api/data' -e 'AWC_TIMEOUT_MS=10000' -- npx -y @cyanheads/aviation-weather-mcp-server@0.6.0
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "aviation-weather-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/aviation-weather-mcp-server@0.6.0"
            ],
            "env": {
                "MCP_LOG_LEVEL": "info",
                "AWC_BASE_URL": "https://aviationweather.gov/api/data",
                "AWC_TIMEOUT_MS": "10000"
            }
        }
    }
}

Environment variables

  • MCP_LOG_LEVEL Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').
  • AWC_BASE_URL Base URL for the AWC Data API. Useful for testing against a mock or staging instance.
  • AWC_TIMEOUT_MS Per-request timeout in milliseconds (1000–60000).
NPM package @cyanheads/aviation-weather-mcp-server
Claude Code
claude mcp add aviation-weather-mcp-server -e 'MCP_TRANSPORT_TYPE=<MCP_TRANSPORT_TYPE>' -e 'MCP_HTTP_HOST=127.0.0.1' -e 'MCP_HTTP_PORT=3010' -e 'MCP_HTTP_ENDPOINT_PATH=/mcp' -e 'MCP_AUTH_MODE=none' -e 'MCP_LOG_LEVEL=info' -e 'AWC_BASE_URL=https://aviationweather.gov/api/data' -e 'AWC_TIMEOUT_MS=10000' -- npx -y @cyanheads/aviation-weather-mcp-server@0.6.0
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "aviation-weather-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/aviation-weather-mcp-server@0.6.0"
            ],
            "env": {
                "MCP_TRANSPORT_TYPE": "<MCP_TRANSPORT_TYPE>",
                "MCP_HTTP_HOST": "127.0.0.1",
                "MCP_HTTP_PORT": "3010",
                "MCP_HTTP_ENDPOINT_PATH": "/mcp",
                "MCP_AUTH_MODE": "none",
                "MCP_LOG_LEVEL": "info",
                "AWC_BASE_URL": "https://aviationweather.gov/api/data",
                "AWC_TIMEOUT_MS": "10000"
            }
        }
    }
}

Environment variables

  • MCP_TRANSPORT_TYPE Selects the HTTP transport.
  • MCP_HTTP_HOST The hostname for the HTTP server.
  • MCP_HTTP_PORT The port to run the HTTP server on.
  • MCP_HTTP_ENDPOINT_PATH The endpoint path for the MCP server.
  • MCP_AUTH_MODE Authentication mode to use: 'none', 'jwt', or 'oauth'.
  • MCP_LOG_LEVEL Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').
  • AWC_BASE_URL Base URL for the AWC Data API. Useful for testing against a mock or staging instance.
  • AWC_TIMEOUT_MS Per-request timeout in milliseconds (1000–60000).

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. @cyanheads/aviation-weather-mcp-server
  2. Overview
  3. Capability reference
  4. Features
  5. Getting started
  6. Configuration
  7. Running the server
  8. Project structure
  9. Development guide
  10. Contributing
  11. License

@cyanheads/aviation-weather-mcp-server

Fetch METARs, TAFs, PIREPs, domestic/international SIGMETs and CWAs from NWS AWC via MCP. AIRMETs not served. STDIO or Streamable HTTP.

5 Tools • 1 Prompt

Public Hosted Server: https://aviation-weather.caseyjhand.com/mcp


Overview

Aviation weather from the NWS Aviation Weather Center — METARs, TAFs, PIREPs, domestic/international SIGMETs, and Center Weather Advisories. Look up stations, fetch current and forecast conditions, and pull pilot reports and hazard advisories. AIRMETs are not served.

Tools
ToolDescription
aviation_find_stationsResolve airports and weather stations by identifier, bounding box, or US state. Returns ICAO/IATA/FAA IDs, coordinates, elevation, and available data types.
aviation_get_metarGet 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_tafGet 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_pirepsGet recent Pilot Reports near an airport or within a bounding box. Returns decoded turbulence, icing, and cloud reports with altitude, aircraft type, intensity, outside air temperature, wind aloft, flight weather, and the raw PIREP string.
aviation_get_advisoriesGet domestic/international SIGMETs and Center Weather Advisories. Returns source coverage, hazard, severity, altitude, validity, movement, multipart geometry and original bulletins; omitted facts stay null.
Prompts
PromptDescription
aviation_preflight_briefStructure a preflight weather briefing for a flight, calling the tools above in sequence and synthesizing a weather-risk summary.

Capability reference

aviation_find_stations tool
  • Look up one or more stations by identifier (up to 20 per call) — a lookup matches the registry's own ID, which for an airport is its 4-character ICAO ID (e.g., KSEA, K0S9); a 3-letter IATA code never resolves, though each record includes its IATA/FAA aliases when available
  • Discover stations within a geographic bounding box, or list stations for one of the 50 US states or DC via two-letter USPS code
  • Returns data_types (METAR, TAF, etc.) so agents can confirm what's available before querying
  • Every result states whether the upstream 400-row cap cut it; limit (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 set. An area search returning more than 130 stations with no limit says so and names the lever; omitting limit still returns every match
  • An ID lookup names every identifier that resolved to nothing, separating a 3-letter IATA code (never resolves) from an identifier the registry simply does not list
  • Whitespace around an ID is trimmed rather than failing the batch; only an empty or whitespace-only entry is rejected

aviation_get_metar tool
  • station_ids (1–10 per call — 4 ASCII letters or digits, case-insensitive and normalized to uppercase, so ksea and K0S9 work) for named airports, or bbox to survey every reporting station in an area — mutually exclusive
  • hours (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 station
  • flight_category (e.g., ["IFR", "LIFR"]) narrows a bbox survey to the stations in those categories — judged on each station's latest observation, applied before limit, and disclosed with the count surveyed before it; a station AWC could not rate never matches, and a survey the filter empties returns an empty result that says so. Rejected alongside station_ids
  • A bbox survey states whether the upstream 400-row cap cut it and, above hours: 1, 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_ids. A survey returning more than 40 stations with no limit says so and names the levers; omitting limit still returns every station
  • Flight category (VFR/MVFR/IFR/LIFR) returned directly from the AWC API; decodes wind, visibility, present weather, and cloud layers alongside the raw METAR string
  • Ceiling reports both height and kind (measured, or indefinite for vertical visibility into an obscuration) — sky_condition distinguishes a reported clear sky from an unreported one when clouds is empty
  • metar_type distinguishes routine METAR from special SPECI observations
  • Every batch reports which requested stations came back, naming missing IDs with recovery guidance

aviation_get_taf tool
  • Accepts 1–4 ICAO station IDs per call: 4 ASCII letters or digits in either case, normalized to uppercase
  • Structured forecast periods with change types (FM, TEMPO, BECMG) and probabilities; weather decoded group by group beside the raw groups
  • Forecast obscurations keep their layer and carry the vertical visibility into them, rather than reading as clear sky; sky_condition distinguishes an unamended period from a stated clear sky
  • Text the upstream decoder left undecoded — often a fourth cloud layer — is surfaced per period in not_decoded rather than dropped
  • Low-level wind shear (WS020/20040KT) decoded to the shear-layer top and forecast wind at that height
  • valid_from / valid_to in ISO 8601 for time comparisons
  • Every batch reports which requested stations came back, naming missing IDs with recovery guidance

aviation_get_pireps tool
  • station_id (4 ASCII letters or digits in either case, normalized to uppercase) + 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 bbox
  • altitude_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 set
  • min_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 layers
  • Turbulence and icing arrays include up to two layers per report; icing layers the API synthesized for a report that never mentioned ice are dropped
  • Outside air temperature (temp_c), wind aloft (wind), and the /WX flight weather decoded beside its raw groups (weather), for PIREPs and AIREPs alike. The wind direction is published as reported, with no conversion — a PIREP /WV direction is magnetic, unlike the true-north METAR and TAF winds
  • Every result states whether the upstream 400-row cap cut it, naming only the narrowing levers the call can still use, and limit (1–400) bounds how many reports come back, ordered by recency. A result of more than 50 reports with no limit says so and names the lever; omitting limit still returns every match
  • PIREPs are sparse by nature — absence of reports does not mean smooth conditions

aviation_get_advisories tool
  • advisory_type: sigmet (domestic), isigmet (international, including oceanic), cwa (Center Weather Advisories), or all (default: all three independent products)
  • hazard is applied upstream: domestic supports CONVECTIVE, TURBULENCE, ICING, IFR; international supports TS, TURBULENCE, ICING, MTW, DS, SS, TC, VA; CWA supports TS, TURBULENCE, ICING, IFR, PCPN, UNK. Incompatible sources are not_applicable; a selection with no compatible source is rejected
  • coverage reports each selected source as ok, failed or not_applicable, with decoded drawn counts only for readable sources. partial marks failed sources or skipped unreadable rows. Independent healthy products survive a failure; all applicable products failing is an error. One 45-second deadline bounds the concurrent advisory reads and retries; caller cancellation aborts all legs
  • bbox uses each geometry part's bounding envelope, including date-line crossings, rather than exact polygon intersection. Input remains ordered (minLat <= maxLat, minLon <= maxLon). With bbox, drawn counts rows after product/hazard selection, matched counts geographic matches, returned counts rows after any limit, and unlocated separately counts rows without decoded geometry
  • limit is optional with no default: omitted means every available match. An explicit limit orders by source, issuer, series and validity, reports total/returned/truncated, and explains how to retrieve withheld matches by omitting or raising it
  • Missing issuer, series, hazard, validity and raw text stay null. geometry.parts preserves separate rings/lines and source-native kind (including null); compatibility polygon is null for multipart, line or missing geometry. Domestic numeric severity/movement stay unchanged; international movement preserves direction_text and decoded knots. CWA severity/movement remain null, and altitudes are never inferred from bulletin text
  • Original bulletins render in safe code fences preserving blank lines and embedded backticks. An empty result names readable sources and filtering stage; unavailable sources never establish fair weather
  • AIRMETs are not served. Requests for one (or MTN OBSCN / SURFACE WIND / LLWS) are rejected with guidance to separate AIRMET products

aviation_preflight_brief prompt
  • Arguments: departure_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) optional
  • Every ICAO argument accepts 4 ASCII letters or digits in either case and generates uppercase IDs. For an IATA/FAA code, use aviation_find_stations with state or bbox to find the ICAO ID; no mapping is inferred. Direct IDs reject surrounding whitespace; comma-separated alternates allow it
  • Calls aviation_get_metar, aviation_get_taf, aviation_get_pireps, and aviation_get_advisories in sequence, chunked to each tool's station-per-call limit
  • departure_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 side
  • Omitting any of the three still generates the briefing, naming the assessment it could not make
  • Reports weather risk rather than a go/no-go recommendation — that decision needs pilot, aircraft, and operational-minima context this server does not hold

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.

Aviation-weather-specific:

  • Keyless — no API key or authentication required; all data is from the public AWC Data API
  • Single service (aviation-weather-service) with retry + exponential backoff for the keyless public endpoint
  • Raw coded strings (raw_metar, raw_taf, raw_pirep, raw_text) surfaced alongside decoded fields so agents have both layers
  • State→bbox table enables US-state station queries that the AWC API doesn't natively support
  • Server-level instructions field surfaces the "not an official briefing" safety disclaimer to all clients on initialize

Agent-friendly output:

  • Discriminated output — flight category (VFR/MVFR/IFR/LIFR) as a typed string field, so agents branch on it without parsing ceiling and visibility
  • Structured error contracts — typed reason fields with recovery hints (e.g., "Verify ICAO IDs with aviation_find_stations")
  • Partial-result reconciliation — batch tools report requested / returned / missing / partial fields, so a short batch is never mistaken for full coverage
  • Workflow sequencing — the aviation_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 make

Getting started

Public Hosted Instance

A 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"
    }
  }
}
Self-Hosted / Local

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
Prerequisites
  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key required — the AWC Data API is fully public and keyless.
Installation
  1. Clone the repository:
git clone https://github.com/cyanheads/aviation-weather-mcp-server.git
  1. Navigate into the directory:
cd aviation-weather-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# edit .env if you need to override AWC_BASE_URL or AWC_TIMEOUT_MS

Configuration

VariableDescriptionDefault
AWC_BASE_URLBase URL for the NWS AWC Data API.https://aviationweather.gov/api/data
AWC_TIMEOUT_MSPer-request timeout in milliseconds (1000–60000).10000
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_SESSION_MODEHTTP 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_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
OTEL_ENABLEDEnable OpenTelemetry instrumentation.false

See .env.example for the full list of optional overrides.


Running the server

Local development
  • 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
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.


Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools/prompts and inits services.
src/configServer-specific env var parsing (AWC_BASE_URL, AWC_TIMEOUT_MS).
src/services/aviation-weatherAWC Data API client — HTTP fetch, retry with exponential backoff, response normalization.
src/mcp-server/toolsTool definitions (*.tool.ts).
src/mcp-server/promptsPrompt definitions (*.prompt.ts).
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 request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools and prompts in the createApp() arrays in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Not 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 instructions field sent on every initialize.


Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Frequently asked questions

What is io.github.cyanheads/aviation-weather-mcp-server?

METARs, TAFs, PIREPs, domestic/international SIGMETs and CWAs via NWS AWC. AIRMETs not served.

How do I install io.github.cyanheads/aviation-weather-mcp-server?

It runs as a remote server. In Claude Code: claude mcp add --transport http aviation-weather-mcp-server 'https://aviation-weather.caseyjhand.com/mcp'. For other clients, paste the JSON configuration from this page into their MCP settings.

Does io.github.cyanheads/aviation-weather-mcp-server need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is io.github.cyanheads/aviation-weather-mcp-server open source?

Yes. Its code is on GitHub under the Apache-2.0 license.

Who maintains io.github.cyanheads/aviation-weather-mcp-server?

It is published by cyanheads. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.