mcpField
F
faa-airmen-registry-mcp-server

faa-airmen-registry-mcp-server

远程服务
github.com/cyanheads法律与政务13 天前更新
代码仓库

关于 faa-airmen-registry-mcp-server

这是一款 MCP 服务,可从《可公开飞行员数据库》的本地快照中检索 FAA 飞行员记录,涵盖证书、教员、远程飞行员及说明性医疗字段,并支持 PII 脱敏。

主要功能

  1. 01按姓名或 FAA ID 搜索证书记录
  2. 02查看评级和教员证书
  3. 03查询远程飞行员记录
  4. 04读取说明性医疗字段
  5. 05浏览参考代码和快照状态

适用场景

  1. 01核对飞行员登记的证书和评级
  2. 02按地点或评级查找飞行及地面教员
  3. 03查看远程飞行员证书记录
  4. 04检查数据来源覆盖情况和快照新旧

MCP 相关

通过 STDIO 或 Streamable HTTP 向 MCP 客户端提供六种 FAA 记录查询工具,并提供公共托管端点。自托管部署使用本地构建的快照。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://faa-airmen-registry.caseyjhand.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@cyanheads/faa-airmen-registry-mcp-server0.2.1

工具

6
参数类型必填说明
citystring否准确的城市名,1–60 个可见字符;需要操作员启用位置访问,且在个人数据遮盖开启时不接受。留空表示未设置。
modeenum是id 模式需要 uniqueId,并禁止填写非空的姓名/位置字段以及显式设置 nameMatch;name 模式需要 lastName,且个人数据遮盖开启时还需要 firstName,并禁止填写非空的 uniqueId。id | name
limitinteger否每页最多返回的完整人员或参考条目数;默认值为 10,最大值为 50。超过上限的值最多返回 50 条,并附带提示。
statestring否两字母州或地区代码;会去除首尾空格并转换为大写。留空表示未设置。
offsetinteger否从零开始的偏移量;默认值为 0,最大值为 10000。达到上限时,请遵循 nextOffset 或缩小筛选范围。
zipCodestring否五位数 ZIP 或 ZIP+4,保留前导零;需要操作员启用位置访问,且在个人数据遮盖开启时不接受。留空表示未设置。
lastNamestring否姓氏,可包含后缀;默认的 words 匹配可从 SMITH 匹配到 SMITH JR。规范化后为 1–60 个可见字符。留空表示未设置。
uniqueIdstring否不透明的 FAA Unique ID,由 faa_airmen_verify_certificate 在 name 模式下返回,格式为 A 或 C 加七位数字,例如 A9999999;不是证书编号。去除首尾空格并转为大写。
firstNamestring否名字,通常包含中间名;默认的 words 匹配可从 JOHN 匹配到 JOHN ROBERT。规范化后为 1–60 个可见字符。留空表示未设置。
nameMatchenum否每个提供的姓名字段的匹配方式;姓名搜索默认使用 words。words:字段等于搜索词,或在搜索词后以空格继续;单词之间只能用空格分隔,因此含连字符或撇号的姓名算作一个单词。exact:匹配整个字段。prefix:字段以搜索词开头,也可在单词中间匹配;启用个人数据屏蔽时不允许使用。words | exact | prefix
ratingCodesarray否1 至 11 个 rating code,重复项会合并;每个代码都必须与其他请求的资质出现在同一张证书上,不能跨证书匹配。
typeRatingsarray否1 至 11 个型别等级代号,重复项会合并;每个代号都必须与其他请求的资质出现在同一张证书上。
certificateTypestring否一个 FAA 证书类型字母、faa_airmen_list_reference 主题 certificate_types 中的对应说明(不区分大小写;可用下划线或空格,例如 remote pilot 或 flight_instructor),或 CFI;用于筛选人员,同时保留其所有证书。
certificateLevelstring否一个在 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。

6 个工具

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


概述

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-mirror CLI 会下载并验证每个快照,将其存入不可变的版本;刷新失败时,仍由最后一个完整版本提供服务
  • 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 测试运行。
安装
  1. 克隆仓库:
git clone https://github.com/cyanheads/faa-airmen-registry-mcp-server.git
  1. 进入目录:
cd faa-airmen-registry-mcp-server
  1. 安装依赖:
bun install
  1. 配置环境:
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
  1. 构建并初始化数据快照:
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_HOSTHTTP 绑定地址。127.0.0.1
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_SESSION_MODEHTTP 会话模式: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/airmenFAA 数据获取、流式导入、不可变快照生命周期、查询和参考表。
src/clifaa-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 文件。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。