@cyanheads/aviation-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/aviation-weather-mcp-serverget METAR for KLAX"
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://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
Tool | Description |
| Resolve airports and weather stations by identifier, bounding box, or US state. Returns ICAO/IATA/FAA IDs, coordinates, elevation, and available data types. |
| 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. |
| 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. |
| Get 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. |
| Get 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
Prompt | Description |
| Structure a preflight weather briefing for a flight, calling the tools above in sequence and synthesizing a weather-risk summary. |
Related MCP server: mcp-metar
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 availableDiscover 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 queryingEvery result states whether the upstream 400-row cap cut it;
limit(1–400) bounds how many stations abboxorstatesearch returns, ordered by ICAO identifier ascending with identifier-less stations last — rejected alongsidestation_ids, since that mode already names the set. An area search returning more than 130 stations with nolimitsays so and names the lever; omittinglimitstill returns every matchAn 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, sokseaandK0S9work) for named airports, orbboxto survey every reporting station in an area — mutually exclusivehours(1–12) is a lookback window, not a row limit: withstation_idsevery observation inside it is returned, and withbboxthe result is the latest observation per stationflight_category(e.g.,["IFR", "LIFR"]) narrows abboxsurvey to the stations in those categories — judged on each station's latest observation, applied beforelimit, 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 alongsidestation_idsA
bboxsurvey states whether the upstream 400-row cap cut it and, abovehours: 1, nameshoursas 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 alongsidestation_ids. A survey returning more than 40 stations with nolimitsays so and names the levers; omittinglimitstill returns every stationFlight 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_conditiondistinguishes a reported clear sky from an unreported one whencloudsis emptymetar_typedistinguishes routineMETARfrom specialSPECIobservationsEvery 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 groupsForecast obscurations keep their layer and carry the vertical visibility into them, rather than reading as clear sky;
sky_conditiondistinguishes an unamended period from a stated clear skyText the upstream decoder left undecoded — often a fourth cloud layer — is surfaced per period in
not_decodedrather than droppedLow-level wind shear (
WS020/20040KT) decoded to the shear-layer top and forecast wind at that heightvalid_from/valid_toin ISO 8601 for time comparisonsEvery 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, orbboxfor area search — mutually exclusive; astation_idAWC does not recognize as a search center returns a typed error pointing toaviation_find_stationsorbboxaltitude_min_ft/altitude_max_ftfilter 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 layersTurbulence 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/WXflight weather decoded beside its raw groups (weather), for PIREPs and AIREPs alike. The wind direction is published as reported, with no conversion — a PIREP/WVdirection is magnetic, unlike the true-north METAR and TAF windsEvery 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 nolimitsays so and names the lever; omittinglimitstill returns every matchPIREPs 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), orall(default: all three independent products)hazardis applied upstream: domestic supportsCONVECTIVE,TURBULENCE,ICING,IFR; international supportsTS,TURBULENCE,ICING,MTW,DS,SS,TC,VA; CWA supportsTS,TURBULENCE,ICING,IFR,PCPN,UNK. Incompatible sources arenot_applicable; a selection with no compatible source is rejectedcoveragereports each selected source asok,failedornot_applicable, with decoded drawn counts only for readable sources.partialmarks 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 legsbboxuses each geometry part's bounding envelope, including date-line crossings, rather than exact polygon intersection. Input remains ordered (minLat <= maxLat,minLon <= maxLon). With bbox,drawncounts rows after product/hazard selection,matchedcounts geographic matches,returnedcounts rows after any limit, andunlocatedseparately counts rows without decoded geometrylimitis optional with no default: omitted means every available match. An explicit limit orders by source, issuer, series and validity, reportstotal/returned/truncated, and explains how to retrieve withheld matches by omitting or raising itMissing issuer, series, hazard, validity and raw text stay null.
geometry.partspreserves separate rings/lines and source-nativekind(including null); compatibilitypolygonis null for multipart, line or missing geometry. Domestic numeric severity/movement stay unchanged; international movement preservesdirection_textand decoded knots. CWA severity/movement remain null, and altitudes are never inferred from bulletin textOriginal 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_icaoanddestination_icaorequired;alternates(comma-separated ICAOs),departure_time(ISO 8601 UTC),cruise_altitude(feet MSL), androute_waypoints(semicolon-separatedlat,lonpairs) optionalEvery ICAO argument accepts 4 ASCII letters or digits in either case and generates uppercase IDs. For an IATA/FAA code, use
aviation_find_stationswithstateorbboxto find the ICAO ID; no mapping is inferred. Direct IDs reject surrounding whitespace; comma-separated alternates allow itCalls
aviation_get_metar,aviation_get_taf,aviation_get_pireps, andaviation_get_advisoriesin sequence, chunked to each tool's station-per-call limitdeparture_timeselects the TAF forecast period the briefing is read against;cruise_altitudebounds the PIREP search to a ±3,000 ft band;route_waypointsbecome the advisoriesbbox, widened by 1° on each sideOmitting 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 endpointRaw coded strings (
raw_metar,raw_taf,raw_pirep,raw_text) surfaced alongside decoded fields so agents have both layersState→bbox table enables US-state station queries that the AWC API doesn't natively support
Server-level
instructionsfield surfaces the "not an official briefing" safety disclaimer to all clients oninitialize
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 visibilityStructured error contracts — typed
reasonfields withrecoveryhints (e.g., "Verify ICAO IDs withaviation_find_stations")Partial-result reconciliation — batch tools report
requested/returned/missing/partialfields, so a short batch is never mistaken for full coverageWorkflow sequencing — the
aviation_preflight_briefprompt 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/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key required — the AWC Data API is fully public and keyless.
Installation
Clone the repository:
git clone https://github.com/cyanheads/aviation-weather-mcp-server.gitNavigate into the directory:
cd aviation-weather-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env if you need to override AWC_BASE_URL or AWC_TIMEOUT_MSConfiguration
Variable | Description | Default |
| Base URL for the NWS AWC Data API. |
|
| Per-request timeout in milliseconds (1000–60000). |
|
| Transport: |
|
| Port for HTTP server. |
|
| HTTP session handling: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Enable OpenTelemetry instrumentation. |
|
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:httpRun 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-serverThe 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
Directory | Purpose |
|
|
| Server-specific env var parsing ( |
| AWC Data API client — HTTP fetch, retry with exponential backoff, response normalization. |
| Tool definitions ( |
| Prompt definitions ( |
| 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 request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and prompts in the
createApp()arrays insrc/index.tsWrap 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
instructionsfield sent on everyinitialize.
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Aviation Weather MCP — METAR, TAF, PIREPs, AIRMET/SIGMET, station info
Hosted MCP server for Xweather weather data: conditions, forecasts, alerts, and more.
FlightAware MCP — wraps FlightAware AeroAPI v4 (aeroapi.flightaware.com)
NOAA and ECMWF weather forecast MCP for discovery, validation, and GribStream OAuth queries.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides aviation weather information through a Model Context Protocol server, enabling access to METARs, TAFs, PIREPs, and route weather data for informational purposes only.2MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for fetching METAR and TAF aviation weather data for airports by ICAO code.29 PyPIMIT
- FlicenseNot gradedqualityDmaintenanceFetches and parses METAR/TAF aviation weather data from NOAA with caching and human-readable formatting.1-
- AlicenseNot gradedqualityCmaintenanceMCP server providing real-time aviation weather data (METAR, TAF, PIREPs, AIRMETs) from aviationweather.gov for flight planning and analysis.4 npmMIT