关于 faa-airmen-registry-mcp-server
这是一款 MCP 服务,可从《可公开飞行员数据库》的本地快照中检索 FAA 飞行员记录,涵盖证书、教员、远程飞行员及说明性医疗字段,并支持 PII 脱敏。
主要功能
- 01按姓名或 FAA ID 搜索证书记录
- 02查看评级和教员证书
- 03查询远程飞行员记录
- 04读取说明性医疗字段
- 05浏览参考代码和快照状态
适用场景
- 01核对飞行员登记的证书和评级
- 02按地点或评级查找飞行及地面教员
- 03查看远程飞行员证书记录
- 04检查数据来源覆盖情况和快照新旧
MCP 相关
通过 STDIO 或 Streamable HTTP 向 MCP 客户端提供六种 FAA 记录查询工具,并提供公共托管端点。自托管部署使用本地构建的快照。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://faa-airmen-registry.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-faa-airmen-registry https://faa-airmen-registry.caseyjhand.com/mcp{"mcpServers":{"cyanheads-faa-airmen-registry":{"type":"http","url":"https://faa-airmen-registry.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-faa-airmen-registry":{"type":"http","url":"https://faa-airmen-registry.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-faa-airmen-registry":{"type":"http","url":"https://faa-airmen-registry.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-faa-airmen-registry":{"serverUrl":"https://faa-airmen-registry.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
6| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| city | string | 否 | 准确的城市名,1–60 个可见字符;需要操作员启用位置访问,且在个人数据遮盖开启时不接受。留空表示未设置。 |
| mode | enum | 是 | id 模式需要 uniqueId,并禁止填写非空的姓名/位置字段以及显式设置 nameMatch;name 模式需要 lastName,且个人数据遮盖开启时还需要 firstName,并禁止填写非空的 uniqueId。id | name |
| limit | integer | 否 | 每页最多返回的完整人员或参考条目数;默认值为 10,最大值为 50。超过上限的值最多返回 50 条,并附带提示。 |
| state | string | 否 | 两字母州或地区代码;会去除首尾空格并转换为大写。留空表示未设置。 |
| offset | integer | 否 | 从零开始的偏移量;默认值为 0,最大值为 10000。达到上限时,请遵循 nextOffset 或缩小筛选范围。 |
| zipCode | string | 否 | 五位数 ZIP 或 ZIP+4,保留前导零;需要操作员启用位置访问,且在个人数据遮盖开启时不接受。留空表示未设置。 |
| lastName | string | 否 | 姓氏,可包含后缀;默认的 words 匹配可从 SMITH 匹配到 SMITH JR。规范化后为 1–60 个可见字符。留空表示未设置。 |
| uniqueId | string | 否 | 不透明的 FAA Unique ID,由 faa_airmen_verify_certificate 在 name 模式下返回,格式为 A 或 C 加七位数字,例如 A9999999;不是证书编号。去除首尾空格并转为大写。 |
| firstName | string | 否 | 名字,通常包含中间名;默认的 words 匹配可从 JOHN 匹配到 JOHN ROBERT。规范化后为 1–60 个可见字符。留空表示未设置。 |
| nameMatch | enum | 否 | 每个提供的姓名字段的匹配方式;姓名搜索默认使用 words。words:字段等于搜索词,或在搜索词后以空格继续;单词之间只能用空格分隔,因此含连字符或撇号的姓名算作一个单词。exact:匹配整个字段。prefix:字段以搜索词开头,也可在单词中间匹配;启用个人数据屏蔽时不允许使用。words | exact | prefix |
| ratingCodes | array | 否 | 1 至 11 个 rating code,重复项会合并;每个代码都必须与其他请求的资质出现在同一张证书上,不能跨证书匹配。 |
| typeRatings | array | 否 | 1 至 11 个型别等级代号,重复项会合并;每个代号都必须与其他请求的资质出现在同一张证书上。 |
| certificateType | string | 否 | 一个 FAA 证书类型字母、faa_airmen_list_reference 主题 certificate_types 中的对应说明(不区分大小写;可用下划线或空格,例如 remote pilot 或 flight_instructor),或 CFI;用于筛选人员,同时保留其所有证书。 |
| certificateLevel | string | 否 | 一个在 faa_airmen_list_reference 主题 certificate_levels 中为 certificateType 列出的等级字母,例如 certificateType 为 P 时的 A(airline transport pilot);必须提供 certificateType,并匹配证书本身的等级。去除首尾空格并转为大写;留空表示未设置。 |
详细介绍
@cyanheads/faa-airmen-registry-mcp-server
通过 MCP 搜索 FAA 航空人员证书、等级和说明性医疗记录。支持 STDIO 或 Streamable HTTP。
概述
FAA 航空人员认证记录来自 可公开航空人员数据库,由本地快照提供。将姓名解析为不同的身份候选项,读取飞行员和非飞行员证书及其排序后的等级,查找飞行和地面教员以及远程飞行员,并读取说明性医疗字段。
可作为 stdio 进程、环回 Streamable HTTP 服务(直接运行或通过 Docker 运行),或通过上述公开托管端点运行。自托管运营方需使用单独的 CLI 构建快照;服务不会下载数据,也无需 API 密钥。
工具
| 工具 | 描述 |
|---|---|
faa_airmen_verify_certificate | 按姓名或 FAA Unique ID 查找身份候选项,可选按证书类型、级别和等级缩小范围,并读取其完整证书记录 |
faa_airmen_get_type_ratings | 读取所有飞行员类别证书及其航空器型别、类别/级别和仪表等级 |
faa_airmen_check_medical_status | 读取说明性医疗和 BasicMed 字段,不评估适航性或资格 |
faa_airmen_search_instructors | 按姓名、州和等级查找飞行和地面教员记录 |
faa_airmen_verify_remote_pilot | 按姓名或 Unique ID 查找可公开的远程飞行员证书记录 |
faa_airmen_list_reference | 读取代码、释义指南、已观察到的型别代号和镜像状态 |
功能参考
faa_airmen_verify_certificate 工具
mode: "name"需要提供lastName;firstName、state、city和zipCode可缩小范围。nameMatch会应用于每个提供的姓名字段:words(默认值)匹配开头的完整单词,因此JOHN可找到 FIRST NAME 为JOHN ROBERT的记录(FAA 的名字通常包含中间名),而SMITH可找到 LAST NAME 为SMITH JR的记录;单词之间只能用空格分隔,因此SMITH找不到SMITH-JONES。exact会比较整个字段,prefix会从字段开头匹配,也包括单词中间mode: "id"接受一个uniqueId,这是由 A 或 C 加上七位数字组成的不透明 ID,并非证书编号;该模式不接受姓名和地点字段certificateType(一个类型字母、参考主题certificate_types中的描述,例如remote pilot或flight_instructor,大小写不限,或CFI)用于筛选人员,但会返回这些人的所有证书;姓名相同的人仍会作为不同候选人certificateLevel(参考主题certificate_levels中的一个字母;需要同时提供certificateType)、ratingCodes(主题ratings中的 1–11 个代码)和typeRatings(主题type_ratings中的 1–11 个型号标记,例如B-737)可进一步缩小候选范围。每项请求的资质都必须出现在同一张证书上,匹配结果仍会返回所有证书。重复项会合并。不带级别的代码或型号标记会匹配任意级别;level/code只匹配该级别:A/B-737表示在 ATP 级别持有的型号等级,而certificateLevel: "A"搭配B-737则表示查找持有该型号等级且级别为任意级别(包括C/B-737)的 ATP 证书- 使用资质筛选条件时,如果结果为零,会说明不使用这些条件时姓名搜索匹配到多少人,从而区分姓名未匹配和资质未匹配
- 启用
FAA_AIRMEN_REDACT_PII时(默认设置),姓名模式必须同时提供lastName和firstName,并且会以pii_redacted拒绝nameMatch: "prefix"、city和zipCode;结果中会省略城市和 ZIP
faa_airmen_get_type_ratings 工具
- 接受一个来自
faa_airmen_verify_certificate的uniqueId;返回 FAA 飞行员档案中的所有证书,并按顺序提供ratings和typeRatings槽位,每个槽位都会保留其raw值、ordinal和code - 未知 ID 返回
found: false;如果已知人员只有非飞行员证书,则返回空的certificates数组
faa_airmen_check_medical_status 工具
- 接受一个
uniqueId;返回每条不同的已报告医疗记录:medicalClass、medicalDateRaw和medicalExpireDateRaw(通常为 MMYYYY),以及 BasicMed 课程和检查清单日期(通常为 YYYYMMDD) found用于区分未知 ID 和已知人员;hasReportedMedicalFields: false表示未报告任何信息,绝不表示存在不利结果。每个结果都包含disclaimer:这些字段仅供参考,并非证明适航或符合资格的依据- 启用
FAA_AIRMEN_REDACT_PII时(默认设置),所有调用都会被pii_redacted拒绝
faa_airmen_search_instructors 工具
- 至少需要提供
lastName、firstName、state、city、zipCode或ratingCodes中的一项;instructorType可设为flight(F)、ground(G)或both(默认值) ratingCodes接受参考主题ratings中的 1–11 个代码,且这些代码都必须出现在同一张证书上;重复项会合并。不带级别的代码会匹配任何来源级别;level/code(结果返回的raw格式,例如F/INSTA;级别为一个字母)只匹配该级别。CFII 是 F 级别上的INSTA、INSTH、INSTI或INSTP,MEI 是AME或ASME;INST、ADV和BASIC只出现在 G 级别- 启用
FAA_AIRMEN_REDACT_PII时(默认设置),姓名搜索必须同时提供lastName和firstName,并且会以pii_redacted拒绝nameMatch: "prefix"、city和zipCode;结果中会省略城市和 ZIP - 匹配结果会包含完整的合格
instructorCertificates。旧版有效期字段不能证明当前资质有效;根据 2024 年 12 月的规则,CFI 证书不再过期
faa_airmen_verify_remote_pilot 工具
- 与
faa_airmen_verify_certificate使用相同的mode、uniqueId和姓名选择器;仅返回持有 U 证书的人员,并将所有证书列在remotePilotCertificates中 - 启用
FAA_AIRMEN_REDACT_PII时(默认启用),适用相同的姓名限制:必须同时提供两个姓名;拒绝nameMatch: "prefix"、city和zipCode,并返回pii_redacted - 持有证书并不能证明符合 Part 107 的复训要求或拥有操作权限
faa_airmen_list_reference 工具
topic可以是certificate_types、certificate_levels、ratings、type_ratings、identifiers、medical_guidance或mirror_status;四个词汇主题支持不超过 80 个字符的筛选条件filter,且不区分大小写- 静态主题和
mirror_status在快照生成前即可返回;type_ratings会列出导入快照中观察到的型号等级代号 mirror_status会返回mirrorStatus.state(missing、ready、unavailable)、refreshState(idle、running、failed)、lastRefreshFailure(未完成的刷新阶段,例如acquisition、validation、disk、cancelled、timeout;若进程结束时未记录结果,则为interrupted),以及最新一代数据的来源信息,不包含文件系统路径
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),并提供结构化日志记录和可选的 OpenTelemetry 跟踪。
FAA 专属功能:
- 使用 SQLite 对四个每月源文件(
PILOT_BASIC、NONPILOT_BASIC、PILOT_CERT、NONPILOT_CERT)进行离线查询,并按 FAA 唯一 ID 联结,同时保留每张不同的证书和身份信息的不同版本 - 在存储任何内容之前丢弃街道地址。导入、输出和筛选城市及 ZIP 需要设置
FAA_AIRMEN_INCLUDE_LOCATION=true;州始终可用 - 默认启用服务时脱敏(
FAA_AIRMEN_REDACT_PII,只有设为false才会关闭):姓名搜索需要同时提供名字和姓氏;拒绝prefix匹配以及城市/ZIP 筛选;输出中省略城市和 ZIP;faa_airmen_check_medical_status拒绝所有调用。拒绝响应会附带原因pii_redacted,每个成功响应都会附带piiRedacted,且不会影响镜像导入 faa-airmen-registry-mirrorCLI 会下载并验证每个快照,将其存入不可变的版本;刷新失败时,仍由最后一个完整版本提供服务- FAA 不包含拒绝公开地址的飞行员,也不发布证书编号或复训日期。未找到记录并不能证明某人没有证书,找到记录也不能证明其当前拥有相关权限;如需权威答复,请使用 FAA 官方服务
便于 Agent 使用的输出:
- 每个基于快照的响应都会包含来源名称、快照月份、带有
stale标记的来源时效、版本 ID、该版本的位置导入策略,以及标准化后的appliedFilters;faa_airmen_list_reference的mirror_status主题会返回完整记录,包括哈希、行数和来源质量警告数量 - 按完整记录分页:列表工具会在约 24 KiB 的响应预算内返回完整人员记录,因此
limit(默认值为 10,最多为 50;超过上限时返回 50 条并附带提示)只是上限。totalCount、returnedCount和nextOffset描述实际分页结果;偏移量最大为 10,000,达到上限时会通过atPagingCap提示缩小筛选范围 - 类型化错误会指出下一步应调用的工具:
mirror_missing、location_access_disabled、pii_redacted、invalid_filter以及其他已声明原因都会附带恢复步骤。验证失败会指出字段及其预期格式(state must be a two-letter state or territory code.),但不会显示字段值;即使结果页为空,也会返回总数和指引
开始使用
公共托管实例
现已提供公共实例:https://faa-airmen-registry.caseyjhand.com/mcp——无需安装或准备快照。该实例使用 Streamable HTTP;每个客户端的配置格式各不相同。
Claude Code:
claude mcp add --transport http faa-airmen-registry-mcp-server https://faa-airmen-registry.caseyjhand.com/mcp
Cline(cline_mcp_settings.json):
{
"mcpServers": {
"faa-airmen-registry-mcp-server": {
"type": "streamableHttp",
"url": "https://faa-airmen-registry.caseyjhand.com/mcp"
}
}
}
Cursor(mcp.json):
{
"mcpServers": {
"faa-airmen-registry-mcp-server": {
"url": "https://faa-airmen-registry.caseyjhand.com/mcp"
}
}
}
Claude Desktop 可在“设置”→“连接器”中添加远程服务。
托管实例默认启用脱敏:姓名搜索需要同时提供名字和姓氏;拒绝 nameMatch: "prefix" 和城市/ZIP 搜索;无法进行医疗信息查询。默认的 words 匹配仍支持完整的前导词。如需使用完整功能,请自行托管并设置 FAA_AIRMEN_REDACT_PII=false。
自托管 / 本地
本地安装使用自己的数据快照,因此连接客户端前请先构建:
export FAA_AIRMEN_MIRROR_DIR="$HOME/.local/share/faa-airmen-registry-mcp-server"
npx -y --package @cyanheads/faa-airmen-registry-mcp-server faa-airmen-registry-mirror init
init 会下载当前 FAA 存档(约 57 MB),并构建约 1.75 GB 的 SQLite 数据库;测试中耗时约 12 分钟。导入器还会预留 1 GiB 的可用空间,因此请准备约 3 GB。相同的 CLI 还可运行 verify、status、refresh 和 prune。refresh 会在当前数据版本旁构建下一版本(额外约 1.75 GB),且不会删除旧版本,因为运行中的服务可能仍在读取旧版本。status 会报告已有多少个已被取代的数据版本及其大小。请停止所有使用该镜像的服务进程,然后运行 prune:它会获取写入锁,除非已发布的数据快照处于就绪状态,否则会拒绝执行;随后删除 CURRENT 未指向的所有数据版本,并输出删除内容和释放的字节数。删除仍被服务打开的数据版本可能导致该服务的查询失败(macOS 上的 Bun),也可能导致删除操作本身失败(Windows)。
将 MCP 客户端指向相同的 FAA_AIRMEN_MIRROR_DIR;如果未设置,两者都会使用平台用户数据目录。若要保留城市和邮政编码,请在导入和服务端运行时都设置 FAA_AIRMEN_INCLUDE_LOCATION=true;启用该选项前导入的数据快照需要执行 refresh。输出脱敏默认开启,且仅在服务时生效;若个人本地安装需要完整功能(医疗信息查询、部分姓名和城市/邮政编码搜索,以及在输出中包含城市和邮政编码),请在服务端设置 FAA_AIRMEN_REDACT_PII=false。
MCP 客户端配置
将以下内容添加到 MCP 客户端配置文件中。
{
"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"
}
}
}
}
或者使用 npx(无需 Bun):
{
"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"
}
}
}
}
也可以使用 Docker。镜像会将数据快照保存在 /data/airmen,因此请先初始化一个命名卷;维护时使用相同命令并传入 refresh、verify 或 status,待所有使用该卷的服务容器停止后,再传入 prune:
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"]
}
}
}
对于 Streamable HTTP,请在环回地址上启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Or from the image, published on loopback only:
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
# Server listens at http://127.0.0.1:3010/mcp
先决条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- 约 3 GB 的本地持久存储空间,用于保存数据快照;仅运行
init和refresh时需要网络连接。 - 在 Node 下,
better-sqlite3无需编译步骤即可加载适用于 x64 和 arm64 架构上 macOS、Linux 和 Windows 的预构建绑定。已在 macOS 上使用 Node 和 Bun 测试运行。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/faa-airmen-registry-mcp-server.git
- 进入目录:
cd faa-airmen-registry-mcp-server
- 安装依赖:
bun install
- 配置环境:
cp .env.example .env
# set FAA_AIRMEN_MIRROR_DIR, and FAA_AIRMEN_INCLUDE_LOCATION if you want city and ZIP
# FAA_AIRMEN_REDACT_PII=false lifts serving-time redaction on a personal local install
- 构建并初始化数据快照:
bun run rebuild
node --env-file=.env dist/cli/mirror.js init
CLI 不会自行加载 .env;请传入 --env-file=.env 或导出这些变量。
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
FAA_AIRMEN_MIRROR_DIR | 持久化快照目录,由 CLI 和服务共用。 | 平台用户数据目录加上 faa-airmen-registry-mcp-server |
FAA_AIRMEN_INCLUDE_LOCATION | 设为 true 时启用城市和 ZIP 导入,并在 FAA_AIRMEN_REDACT_PII=false 时启用输出和筛选;设为 false 时禁用这些功能。 | false |
FAA_AIRMEN_REDACT_PII | 服务时进行脱敏,默认开启;仅设为 false(不区分大小写)时才会关闭,其他任何值都会使其保持开启。不会改变镜像导入的内容。 | true |
FAA_AIRMEN_STALE_AFTER_DAYS | 源数据年龄警告阈值,整数范围为 1–366;绝不代表凭证判定。 | 45 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_HOST | HTTP 绑定地址。 | 127.0.0.1 |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式:stateless、stateful 或 auto;有实际意义的值会覆盖服务端的 stateless 声明。 | stateless |
MCP_AUTH_MODE | 身份验证:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(debug、info、warning、error 等)。 | info |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
常见框架覆盖项请参见 .env.example。框架存储设置不会更改 FAA 快照的位置。
运行服务
本地开发
-
构建并运行生产版本:
# One-time build and snapshot bun run rebuild node --env-file=.env dist/cli/mirror.js init # Run the built server bun run start:stdio # or bun run start:http -
运行检查和测试:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
项目结构
| 目录 | 用途 |
|---|---|
src/mcp-server/tools | 工具定义(*.tool.ts)、共享架构和无损呈现。包含六个只读工具。 |
src/services/airmen | FAA 数据获取、流式导入、不可变快照生命周期、查询和参考表。 |
src/cli | faa-airmen-registry-mirror 运维 CLI。 |
src/config | 使用 Zod 解析并验证服务专用环境变量。 |
tests/ | 合成数据源生命周期、查询和 MCP 合约测试。 |
开发指南
开发指南和架构规则请参见 CLAUDE.md。简要说明:
- 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用
try/catch - 快照由运维人员管理且为只读;将其保留在服务层,并且仅将
ctx.state用于租户状态 - 在
src/index.ts中的createApp()数组里注册新工具 - 验证源数据行 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段,绝不持久化街道地址,并在测试和示例中使用合成身份
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
本项目采用 Apache 2.0 许可证。详情请参见 LICENSE 文件。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。