Skip to main content
Glama
Relyonyou

flight-deals-mcp

by Relyonyou

flight-deals-mcp

A local MCP server for discovering and re-verifying domestic flight options in mainland China.

中文: 本地运行的 Python MCP Server。面向支持 MCP 的 AI 客户端,用于比较中国大陆境内低价航班方案,并在购买前重新核验价格与可售状态。

仓库:https://github.com/Relyonyou/flight-deals-mcp

WARNING

本项目仍是 MVP,尚未通过生产验收。报价、库存、乘客适用性和票规必须在购买前重新核验。正式 Key 下已完成 24/24 路线矩阵的基准搜索 + 购买前核验 + HTTPS 短链可达(baseline-only);登录后购买页与扩展策略的人工验收仍待执行。详见 验收矩阵

导航:MVP 范围 · 快速开始 · 如何获取正式 API Key · MCP 客户端配置 · 使用方式 · 测试与构建 · 安全与隐私 · 贡献与许可证


MVP 范围

当前固定搜索意图:

维度

约束

航线

中国大陆境内民航

行程

单程

乘客

1 名成人(项目意图;见下)

舱位

经济舱

城市

随包静态表约 31 个主要城市,见 src/flight_deals_mcp/data/airports.json

不在静态表内的城市不会生成扩展候选。这是有意收窄,不等于覆盖全部大陆民航城市。

服务会向上游发送出发地、目的地、日期,以及经济舱、单程等上游支持的约束。官方 @fly-ai/flyai-cli 1.0.16search_flight schema 不提供乘客人数参数。因此「1 名成人」是本项目固定意图,实际报价依赖上游默认语义,购买页必须再次确认该价格适用于 1 名成人。项目不会向上游编造 adult_count 等不存在的字段。

本项目不会创建订单、收款、支付、出票、退改签,也不代替航空公司或售票平台的最终页面。即使首次搜索刚完成,购买前也必须调用 verify_flight_option;只有外部售票页当时显示的价格、库存和规则才是最终依据。


功能概览

仅暴露两个 MCP 工具:

工具

作用

find_flight_options

查询直飞/官方联程基准,并在约束内尝试扩展策略

verify_flight_option

购买前按 search_id + option_id 重新查询,核对价格、可售状态、航段与链接

默认数据路径:official_cli(官方 FlyAI CLI)。另有实验性 direct_mcp(Bearer 直连,未作正式验收)。


策略说明

  • 直飞 / 官方联程:低风险基准,以数据源返回的完整报价为准。

  • 日期浮动:可搜索原日期前后各 1 天(date_flex_days 仅允许 01)。

  • 同城机场:比较同一城市不同机场;注意地面交通时间与费用。

  • 自拼中转:两张彼此独立的机票,可能更便宜,但无联程保护;前序延误、行李再托运、误机损失通常由旅客自行承担。

  • 隐藏城市:仅在 risk_preference=exploratory 且不托运行李时可能出现,并固定标为高风险。航变可能绕过真实目的地,弃乘可能影响后续票联,航司可能重新计价,行李可能被运到票面终点。不是默认推荐,也不保证更便宜或可实际使用。

扩展策略只是候选。coverage.completed / failed / skipped 说明实际完成、失败与跳过的搜索;部分结果 ≠ 覆盖整个市场。搜索总预算默认 60 秒search_timeout_seconds);超时不等于确认无航班。


快速开始

需要:

  • Python 3.12(项目约束 >=3.12,<3.13

  • uv

  • Node.js + npm(official_cli 模式)

  • 官方 CLI:@fly-ai/flyai-cli@1.0.16

git clone https://github.com/Relyonyou/flight-deals-mcp.git
Set-Location flight-deals-mcp
uv sync

npm install --global '@fly-ai/flyai-cli@1.0.16' --registry https://registry.npmjs.org/
# 正式 Key 申请与配置见下文「如何获取正式 API Key」
flyai config set FLYAI_API_KEY 你的正式Key
# Windows 若遇执行策略问题,可用:flyai.cmd config set FLYAI_API_KEY 你的正式Key

uv run flight-deals-mcp

flight-deals-mcpstdio Server:启动后安静等待 MCP 客户端属正常现象。不要在同一终端输入聊天文字;Ctrl+C 停止。

查询本机 uv 绝对路径(写入客户端配置时用):

(Get-Command uv).Source

Windows 上建议用 flyai.cmd(PowerShell 可能拦截 flyai.ps1)。确认:

where.exe node
where.exe flyai.cmd
flyai.cmd --help

如何获取正式 API Key

正式 Key 由 飞猪 AI 开放平台 发放,不由本仓库生成。官方说明见:

建议步骤(以官网当前流程为准,页面文案可能调整):

  1. 使用淘宝账号打开并登录 飞猪 AI 开放平台

  2. 如需推广者能力,按官网「立即申请加入」完成实名认证并签署推广协议(详见 入驻指南)。

  3. 在平台控制台获取正式 API Key(官网快速开始写明:安装后前往控制台领取)。

  4. 仅在本机配置,不要写入 Git、Issue、PR 或聊天记录:

flyai config set FLYAI_API_KEY 你的正式Key
# Windows 若遇执行策略问题:
flyai.cmd config set FLYAI_API_KEY 你的正式Key
  1. 配置后完全重启 MCP 客户端(Codex / Claude Desktop 等),再调用本项目的搜索工具。

说明:

  • 未配置 Key 时,官方 CLI 仍可能进入体验调用;额度与稳定性有限,正式使用请配置 Key。

  • 本项目默认 official_cli:Key 交给官方 CLI 本地配置即可,不必写进 Codex config.toml

  • 控制台入口、领取按钮名称以飞猪官网为准;若与上文不一致,以 快速开始 为准。


安装与数据源

推荐:official_cli + 正式 Key

先按上一节在控制台拿到 Key,再执行:

$env:FLIGHT_PROVIDER_MODE = 'official_cli'   # 默认,可省略
flyai config set FLYAI_API_KEY 你的正式Key

Key 由官方 CLI 本地配置管理;不要写进仓库、客户端明文配置或对话历史。配置后重启 MCP 客户端,并确保客户端子进程 PATH 能解析到 nodeflyai.cmd

无 Key 体验路径

安装官方 CLI 后,不设 Key 也可能获得有限体验调用。额度、稳定性、返回范围均可能受限,不是官方稳定服务承诺,仅适合本地试用。

Windows 上 CLI 有时会先输出业务成功 JSON(status: 0),随后 Node 退出码为 1。本项目接受该成功业务载荷,并把非零退出保留为警告;业务 status 非 0 仍按失败处理。

实验性:direct_mcp

direct_mcp 是实验性、未实测的标准 Bearer-Key 直连路径,不是当前推荐或已验收的生产路径。

$env:FLIGHT_PROVIDER_MODE = 'direct_mcp'
$env:FLYAI_API_KEY = '你的正式Key'
$env:FLYAI_MCP_URL = 'https://flyai.open.fliggy.com/mcp'

无正式 Key 时该模式拒绝启动。优先使用官方 CLI + 正式 Key。不要从 CLI 提取私有签名或未公开请求头。


接入 MCP 客户端

下文用 <MCP存放路径><uv绝对路径> 表示本机路径,请自行替换。

Codex(推荐关注)

Codex 使用 [mcp_servers.<id>]config.toml)或 codex mcp add不使用 Claude Desktop 风格的 mcpServers JSON。

CLI 注册

codex mcp add flight-deals --env FLIGHT_PROVIDER_MODE=official_cli -- '<uv绝对路径>' --directory '<MCP存放路径>' run flight-deals-mcp

~/.codex/config.toml(Windows 建议写法)

Codex 默认不把完整用户环境交给 stdio MCP。在 Windows 上若只配 FLIGHT_PROVIDER_MODE,子进程经常找不到 node / flyai.cmd,或家庭目录/系统变量缺失,表现为「官方数据源在 60 秒预算内超时」(本机直接跑 CLI 往往数秒就有结果)。请显式配置 PathUSERPROFILESystemRoot 等,并将客户端 tool_timeout_sec 设为大于 Server 的 60 秒总预算(建议 90~120)。

[mcp_servers.flight-deals]
command = '<uv绝对路径>'
args = ["--directory", "<MCP存放路径>", "run", "flight-deals-mcp"]
cwd = "<MCP存放路径>"
startup_timeout_sec = 90
tool_timeout_sec = 120
env_vars = [
  "USERPROFILE", "HOME", "APPDATA", "LOCALAPPDATA",
  "TEMP", "TMP", "SystemRoot", "SYSTEMROOT", "ComSpec",
  "USERNAME", "USERDOMAIN", "PATHEXT", "NUMBER_OF_PROCESSORS",
]

[mcp_servers.flight-deals.env]
FLIGHT_PROVIDER_MODE = "official_cli"
USERPROFILE = '<你的用户目录>'
HOME = '<你的用户目录>'
APPDATA = '<你的用户目录>\\AppData\\Roaming'
LOCALAPPDATA = '<你的用户目录>\\AppData\\Local'
TEMP = '<你的用户目录>\\AppData\\Local\\Temp'
TMP = '<你的用户目录>\\AppData\\Local\\Temp'
SystemRoot = 'C:\\Windows'
SYSTEMROOT = 'C:\\Windows'
ComSpec = 'C:\\Windows\\System32\\cmd.exe'
PATHEXT = '.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC'
# 必须能解析到 uv、node.exe、flyai.cmd
Path = '<uv所在目录>;<Node安装目录>;<npm全局目录>;C:\\Windows\\System32;C:\\Windows'

保存后完全退出并重启 Codex。应只发现 find_flight_optionsverify_flight_option

超时专项排查(含本机对照命令与决策树): docs/codex-timeout-troubleshooting.md

Claude Desktop / 通用 JSON stdio

{
  "mcpServers": {
    "flight-deals": {
      "command": "<uv绝对路径>",
      "args": [
        "--directory",
        "<MCP存放路径>",
        "run",
        "flight-deals-mcp"
      ],
      "env": {
        "FLIGHT_PROVIDER_MODE": "official_cli"
      }
    }
  }
}

JSON 中反斜杠需写成 \\。Codex 不使用上述 JSON;Codex 请用上一节的 CLI 或 TOML。其他客户端的具体配置文件位置由客户端决定。


推荐使用方式

自然语言搜索示例

可直接复制到已接入本 MCP 的 AI 客户端:

固定日期(建议首次先用这个,降低超时与风控概率):

用 flight-deals 搜索 2026-08-12 北京到杭州,日期不要浮动,不托运行李,最长 10 小时,风险偏好 balanced。

日期前后浮动 1 天:

搜索 2026-08-12 北京到杭州,前后可浮动 1 天,不托运行李,最长 10 小时,风险偏好 balanced。

需要托运行李(会排除不兼容方案,含隐藏城市):

搜索 2026-08-12 上海到成都,不浮动日期,需要托运行李,最长 12 小时,风险偏好 conservative。

风险偏好场景:

偏好

适用

conservative

默认更稳妥;偏直飞/官方联程

balanced

可接受有限扩展(如日期浮动、自拼等,仍受规则约束)

exploratory

才可能看到隐藏城市等高风险候选;须保留完整风险提示

购买前核验示例

选出方案后:

购买前用刚才的 search_id 和该方案的 option_id 调用 verify_flight_option 重新核验。

核验会重新访问数据源,不会把缓存旧价冒充实时价。核验后仍须自行打开最新 HTTPS 购买链接,确认:1 名成人适用、航班、日期、机场、经济舱、行李、退改规则与总价。上游无乘客人数入参,此步不可省略。

MCP 工具参数示例

以下仅为参数对象示意,不是完整 JSON-RPC 信封;价格/ID 亦为示意。

find_flight_options

{
  "origin_city": "北京",
  "destination_city": "杭州",
  "departure_date": "2026-08-12",
  "date_flex_days": 0,
  "checked_baggage": false,
  "max_duration_hours": 10,
  "risk_preference": "balanced"
}

verify_flight_option

{
  "search_id": "00000000-0000-4000-8000-000000000000",
  "option_id": "example-option-id"
}

以上两个值是示意 ID,实际调用必须使用 find_flight_options 返回的值。 示例不代表当前价格、库存或链接有效。

结果解读

  • search_id:本次搜索快照标识,核验时必填。

  • option_id:候选方案标识。

  • baseline:基准报价(通常来自直飞/官方联程筛选)。

  • options:可比较候选列表(含风险字段)。

  • coverage:哪些策略完成 / 失败 / 跳过。

  • warnings:超时、部分失败等提示。

部分策略超时或失败 ≠ 整个搜索失败,更 ≠ 市场上无航班。 隐藏城市必须保留完整风险提示,且不适用于托运行李场景。


数据与缓存

内容

位置

机场 / 城市静态表

src/flight_deals_mcp/data/airports.json

隐藏城市后续目的地表

src/flight_deals_mcp/data/onward_destinations.json

搜索快照 SQLite

进程工作目录下 .local/flight-deals.db(默认 TTL 5 分钟)

通过客户端 cwduv --directory <MCP存放路径> 固定工作目录后,缓存落在 <MCP存放路径>/.local/flight-deals.db。过期快照仅用于核验时定位旧方案并比较变化;当前报价仍会重新查询

缓存含路线与报价,可能反映出行意图。不要提交、上传或随意分享 .local/。该目录已在 .gitignore 中忽略。


验收与项目进度

当前结论(2026-07-28)

状态

MVP 实现(双工具 MCP)

完成

最终审查 Important / Minor 修复

完成

正式 Key + official_cli:24/24 矩阵 baseline 搜索

完成

同矩阵:购买前核验 + HTTPS 短链可达

完成

登录后购买页人工核对 / 单成人适用性

未完成

日期浮动 / 自拼 / 隐藏城市等扩展策略矩阵

未覆盖

生产验收

未通过

明细与复现:docs/acceptance/manual-route-matrix.md

本地批量烟雾(注意上游风控,勿把 Key 与原始结果入库):

uv run python scripts/smoke_matrix_batch.py
$env:SMOKE_MATRIX_IDS = '1,2,3'
uv run python scripts/smoke_matrix_batch.py

本阶段相关文档

  • 设计 / 计划:docs/superpowers/specs/docs/superpowers/plans/

  • 数据源决策:docs/data-access-decision.md

  • Codex 超时排查:docs/codex-timeout-troubleshooting.md

  • 换机交接(开发用,含本机路径):HANDOFF.md


常见问题

正式 API Key 从哪里获取?

见上文 如何获取正式 API Key。入口是 飞猪 AI 开放平台,在控制台领取后执行 flyai config set FLYAI_API_KEY ...。本仓库不发放、不代理 Key。

客户端找不到 uv

(Get-Command uv).Source

把绝对路径写入 TOML/JSON 的 command,保存后彻底重启客户端。

flyai CLI is not installed

npm install --global '@fly-ai/flyai-cli@1.0.16' --registry https://registry.npmjs.org/
where.exe flyai.cmd

客户端仍找不到时:检查 MCP 子进程 Path 是否包含 npm 全局目录与 Node 安装目录,然后完全重启客户端。

FLYAI_API_KEY is required

当前为实验性 direct_mcp。改回 official_cli 并用 flyai.cmd config set 配置 Key。

Codex / 客户端报「60 秒预算超时」「未获得航班结果」

优先阅读:docs/codex-timeout-troubleshooting.md

要点:

  1. 文案中的 60 秒多为 Server 搜索总预算,不是「确认无航班」。

  2. 先在本机跑通 flyai.cmd search-flight;若本机秒级成功、仅客户端超时,重点查 MCP 环境变量与 Windows 沙箱出网。

  3. 首次搜索建议 date_flex_days=0;通了再加浮动。

没有结果或只有部分策略

查看 coveragewarnings。体验额度、风控、上游空结果均可能发生。可缩小浮动、稍后重试,或为 CLI 配置正式 Key。

修改配置后仍用旧环境

MCP 客户端通常只在启动 Server 时读取 env。改 TOML/JSON 后须完全退出客户端再打开,不要只关聊天窗口。

SQLite 被占用或缓存异常

停止所有本项目 MCP 进程后,备份并删除 <MCP存放路径>/.local/flight-deals.db;下次启动会重建。


测试与构建

uv run pytest -v
uv run ruff check .
uv build

仅跑产品验收层断言:

uv run pytest tests/test_acceptance.py -v

自动化测试通过 不等于 24 条路线已完成人工购买页核对,也不等于生产验收通过。


安全与隐私

  • Key 只通过环境变量或官方 CLI 本地配置注入;不写入源码、测试、日志或 MCP 业务输出。

  • 含真实 Key 的客户端配置视为秘密,勿提交 Git、勿发 Issue/PR。

  • 不收集乘机人身份,不接收支付信息,无下单能力。

  • 购买链接经 HTTPS 校验,但 HTTPS ≠ 页面一定可靠;仍需核对域名与页面内容。

  • 不绕过验证码、登录、限流或平台访问控制。

  • 默认仅本地 stdio,不监听公网端口。

  • 分享日志或缓存前,检查是否暴露行程意图或凭据。

安全问题请优先通过 GitHub Security Advisory 私密报告(若仓库已启用)。


贡献与许可证

欢迎通过 Issue 和 Pull Request 改进项目。提交前请阅读贡献指南; 安全问题请按安全政策私下报告,并遵守 社区行为准则

本项目采用 MIT License

贡献前请勿提交:.local/、真实 Key、未脱敏行程日志、个人绝对路径配置。Issue / PR 中同样不要粘贴密钥。

文档索引

文档

说明

docs/acceptance/manual-route-matrix.md

24 行人工核对矩阵与执行状态

docs/codex-timeout-troubleshooting.md

Codex 60 秒超时排查

docs/data-access-decision.md

数据访问路径决策

docs/superpowers/specs/2026-07-24-domestic-flight-deals-mcp-design.md

产品设计规格

HANDOFF.md

换机开发交接