faa-airmen-registry-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., "@faa-airmen-registry-mcp-serverLook up John Smith's airman certificate and ratings."
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.
Overview
Search a local copy of the FAA Releasable Airmen Database. Resolve names to separate identity candidates, inspect pilot and non-pilot certificates, read ratings, find instructor and remote pilot records, and retrieve informational medical fields.
The operator initializes and refreshes the snapshot separately. MCP startup and tool calls never download it. This server is for local use through stdio or local Streamable HTTP, including Docker; no public hosted instance is provided. No API key is required.
Tools
Tool | Description |
| Find identity candidates by name or FAA Unique ID and read their complete certificate records |
| Read all pilot-family certificates and their aircraft type, category/class, and instrument ratings |
| Read informational medical and BasicMed fields without assessing fitness or eligibility |
| Find flight and ground instructor records by name, state, and ratings |
| Find releasable remote pilot certificate records by name or Unique ID |
| Read codes, interpretation guidance, observed type designators, and mirror status |
Related MCP server: SkyDemon MCP Server
Capability reference
faa_airmen_verify_certificate tool
mode: "name"requireslastName; optionalfirstName,state,city, andzipCodenarrow candidates.nameMatchisexactby default orprefix; FAA first names include middle names and last names can include suffixesmode: "id"requires a returneduniqueIdand excludes name/location selectors. IDs are opaque A/C plus seven digits, never certificate numbersOptional
certificateTypeselects people while preserving all their certificates, including other types; names that collide remain separate candidateslimitdefaults to 10, at most 50; follow the actualnextOffsetrather than adding the requested limit
faa_airmen_get_type_ratings tool
Takes one
uniqueIdobtained fromfaa_airmen_verify_certificateReturns every pilot-family certificate with complete ordered rating and type-rating arrays, source certificate type/level, raw values, and unknown codes
A missing ID returns
found: false; a known person with no pilot-family credentials returns an empty certificate array
faa_airmen_check_medical_status tool
Takes one
uniqueId; returns all distinct reported medical records, including medical class, raw dates, and BasicMed dates when suppliedSeparates a missing person from a known person with no reported medical fields through
foundandhasReportedMedicalFieldsThese fields are informational and are not authoritative evidence of medical certification, fitness, or eligibility to operate
faa_airmen_search_instructors tool
Requires at least one name, state, city, ZIP, or rating filter;
instructorTypeisflight,ground, orboth(default)Accepts 1–11 distinct
ratingCodesfrom reference topicratings; every requested code must occur on the same qualifying certificateReturns complete qualifying F/G certificates; legacy expiry fields do not establish instructor currency, and CFI certificates no longer expire under the December 2024 rule
Uses the same bounded paging and location policy as certificate search
faa_airmen_verify_remote_pilot tool
Uses the same mutually exclusive ID/name selectors and paging as certificate search
Returns only people with U certificates and all their remote pilot certificate records
Certificate presence does not establish Part 107 recurrent-training compliance or current operating authority
faa_airmen_list_reference tool
Topics:
certificate_types,certificate_levels,ratings,type_ratings,identifiers,medical_guidance, andmirror_statusStatic topics and
mirror_statuswork before initialization;type_ratingsreads designators observed in the imported snapshotVocabulary topics accept a literal case-insensitive
filterup to 80 normalized characters; all topics uselimit/offsetpagingmirror_statusreports readiness, refresh state, and available provenance without exposing filesystem paths
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.
FAA-specific:
Offline SQLite lookups join pilot and non-pilot source families by FAA Unique ID, retaining distinct certificates and source identity variants
Street addresses are discarded before persistence. City and ZIP import, output, and filtering require explicit operator opt-in; state remains available
Separate operator CLI downloads and validates a replacement before publishing it; a failed refresh preserves the last complete generation
Agent-friendly output:
Snapshot provenance, source-age warnings, normalized applied filters, and interpretation notices accompany results; importing an older source does not make it fresh
Paged responses preserve complete people and reference entries within a 24 KiB target.
limitis an upper bound;returnedCountandnextOffsetreflect the actual page. One complete person can exceed the target rather than lose credentialsPaging offsets stop at 10,000;
atPagingCaptells callers to narrow filters. Nested fields and enrichment carry the same values in text and structured output
Source limitations
The FAA omits airmen who withhold address release. A missing record is not evidence that someone is unlicensed, and a matching record is not a current credential or operational-privilege determination. The dataset supplies no certificate numbers or recurrent-training currency. Medical dates and legacy instructor expiry fields do not establish medical fitness or instructor currency. Use the FAA's official services for authoritative certification questions.
Getting started
Initialize the local snapshot
Install the package in an operator-owned directory so the compiled lifecycle CLI has a stable path:
bun add @cyanheads/faa-airmen-registry-mcp-server
export FAA_AIRMEN_MIRROR_DIR="$HOME/.local/share/faa-airmen-registry-mcp-server"
node node_modules/@cyanheads/faa-airmen-registry-mcp-server/dist/cli/mirror.js init
node node_modules/@cyanheads/faa-airmen-registry-mcp-server/dist/cli/mirror.js verifyThe initial import downloads the complete FAA archive and needs time and disk space; it requires at least 1 GiB of free storage reserve before acquisition. Keep the same FAA_AIRMEN_MIRROR_DIR and location policy in the CLI and MCP client. Replace the illustrative /absolute/path/to/airmen-mirror below with that directory.
Run refresh explicitly when a newer snapshot is needed, and status to inspect readiness:
node node_modules/@cyanheads/faa-airmen-registry-mcp-server/dist/cli/mirror.js refresh
node node_modules/@cyanheads/faa-airmen-registry-mcp-server/dist/cli/mirror.js statusTo retain city and ZIP, set FAA_AIRMEN_INCLUDE_LOCATION=true for both import and serving. Enabling it after an import that discarded those fields requires rebuilding through refresh. Disabling it suppresses location output and filtering immediately.
Local MCP client
Add the following to your MCP client configuration file.
{
"mcpServers": {
"faa-airmen-registry-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/faa-airmen-registry-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"FAA_AIRMEN_MIRROR_DIR": "/absolute/path/to/airmen-mirror"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"faa-airmen-registry-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/faa-airmen-registry-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"FAA_AIRMEN_MIRROR_DIR": "/absolute/path/to/airmen-mirror"
}
}
}
}Or with Docker, initialize a persistent named volume first:
docker volume create faa-airmen-data
docker run --rm -v faa-airmen-data:/data/airmen ghcr.io/cyanheads/faa-airmen-registry-mcp-server:latest bun dist/cli/mirror.js init{
"mcpServers": {
"faa-airmen-registry-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "faa-airmen-data:/data/airmen", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/faa-airmen-registry-mcp-server:latest"]
}
}
}Use the same Docker command with refresh, verify, or status instead of init for maintenance. For local HTTP, publish only on loopback:
docker run --rm -p 127.0.0.1:3010:3010 -v faa-airmen-data:/data/airmen ghcr.io/cyanheads/faa-airmen-registry-mcp-server:latest
# Local MCP URL: http://127.0.0.1:3010/mcpPrerequisites
Bun v1.4.0 or higher, or Node.js v24+
Persistent local storage for the full snapshot; network access is needed only for operator initialization and refresh
Node uses
better-sqlite3, which ships prebuilt bindings for supported macOS, Linux, and Windows x64/arm64 targets without an install/postinstall compiler step. Execution has been tested on macOS with Node 24.22 and Bun; that does not establish execution on every packaged target
Installation
git clone https://github.com/cyanheads/faa-airmen-registry-mcp-server.git
cd faa-airmen-registry-mcp-server
bun install
cp .env.example .env
bun run rebuild
node --env-file=.env dist/cli/mirror.js initSet FAA_AIRMEN_MIRROR_DIR in .env to use an explicit directory; use the same value in the client. Node lifecycle commands need --env-file=.env or exported variables: the CLI does not load .env itself. The default directory is platform user-data storage independent of the working directory.
Configuration
Variable | Description | Default |
| Persistent operator-owned mirror directory; shared by CLI and server | Platform user-data directory plus |
|
|
|
| Source-age warning threshold, integer 1–366; never a credential verdict |
|
| Transport: |
|
| Bind address for local HTTP |
|
| HTTP server port |
|
| HTTP session mode; |
|
| Authentication: |
|
| Log level |
|
| Enable OpenTelemetry |
|
See .env.example for common framework overrides. Framework storage settings do not relocate the FAA mirror.
Running the server
Local development
bun run rebuild
node --env-file=.env dist/cli/mirror.js init
bun run start:stdio
# Or local HTTP:
MCP_HTTP_HOST=127.0.0.1 bun run start:httpRun checks and tests:
bun run devcheck
bun run testProject structure
Directory | Purpose |
| Six read-only tools, shared schemas, and lossless rendering |
| FAA acquisition, streaming import, immutable mirror lifecycle, queries, and references |
| Compiled operator lifecycle command |
| Server-specific environment parsing and validation |
| Synthetic source, lifecycle, query, and MCP contract tests |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicKeep the operator-owned read-only FAA mirror in the service layer; use
ctx.stateonly for tenant stateRegister tools in
createApp()insrc/index.tsPreserve source uncertainty, complete credentials, and text/structured parity; tests and examples use synthetic identities
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Offline, keyless lookup of the US civil aircraft registry — decode N-numbers, search records.
FAA civil aircraft registry — resolve a US tail number (N-number) to its aircraft, engine…
Offline global aviation reference: airports, runways, navaids, frequencies from OurAirports.
Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables offline lookup and search of the US civil aircraft registry by N-number, owner, type, or state, returning detailed aircraft and ownership information.270 npm3Apache 2.0
- AlicenseAqualityBmaintenanceEnables authenticated access to a pilot's flight-planning account, letting an assistant search installed airfield charts offline, pull full airfield records with pilot notes and live feedback, and list, read, or download flightplans from local disk or cloud storage.102MIT
- AlicenseAqualityCmaintenanceEnables agents to search live public airfares between airports across a date window or flexibility range, returning itineraries with prices, times, layovers, and cheapest/fastest/compromise picks, plus offline airport resolution. It runs locally over stdio with no API key, and reports missing fields honestly rather than inventing bags, fares, or prices.2MIT
- AlicenseNot gradedqualityAmaintenanceEnables checking US airports for ground stops, Ground Delay Programs, delays, and closures, while listing all active national airspace events and reading the Command Center's operations plan and full ATCSCC advisory text. It runs over stdio or Streamable HTTP and also decodes FAA event types, traffic-management terms, ARTCC codes, and identifier formats.61 npm1Apache 2.0