mcpField
K
KeyFlight PNR Converter

KeyFlight PNR Converter

远程服务
keyflight.io地图与出行01 周前更新

关于 KeyFlight PNR Converter

KeyFlight PNR Converter 是面向旅行代理、旅行社及处理 GDS 预订的开发者的托管 MCP 服务和 PNR API。它可解析 Amadeus、Sabre、Galileo 和 Worldspan 记录,生成行程与 JSON,也能制作 PRO 票 PDF。

主要功能

  1. 01解析四种 GDS 格式的 PNR
  2. 02输出可读行程和结构化 JSON
  3. 03选择行程布局及日期时间格式
  4. 04生成可选价格的 PRO 票 PDF

适用场景

  1. 01将 GDS 预订转换为旅客行程
  2. 02把解析后的预订数据传入预订工具或 CRM
  3. 03根据 PNR 制作 PRO 票 PDF

MCP 相关

托管 MCP 服务位于 https://keyflight.io/mcp,提供 PNR 解析和 PRO 票 PDF 生成工具。它使用 Streamable HTTP,并要求提供 bearer API 密钥。

配置

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

服务地址https://keyflight.io/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 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://keyflight.io/mcp需要授权

工具

详细介绍

KeyFlight PNR API 与 MCP:在 Claude、Cursor 或代码中解析 Amadeus、Sabre、Galileo 和 Worldspan PNR

KeyFlight PNR Converter:MCP 服务和 PNR API

将 GDS(Amadeus、Sabre、Galileo、Worldspan)中的原始预订内容粘贴到 Claude、Cursor 或其他 AI 助手中,即可获取易读的行程、JSON 格式的预订信息或 PRO 机票 PDF。

KeyFlight 在 https://keyflight.io/mcp 托管了 Model Context Protocol 服务,并在 https://keyflight.io/api/v1/pnr/decode 提供 HTTP API。两者使用的解码器与 keyflight.io 上的免费 PNR converter 相同。

此代码库包含文档和示例。服务本身由 KeyFlight 托管:无需安装或运行任何内容。完整参考文档:keyflight.io/pnr-api。

适用对象: 使用 GDS 预订的旅行代理和代理机构,以及希望在预订工具、CRM、聊天机器人或电子邮件工作流中添加 PNR 解码功能的开发者。

获取 API 密钥

MCP 服务和 PNR API 使用同一个密钥,格式为 kfp_ 后接 43 个字母、数字、- 和 _。

  1. 获取 KeyFlight 订阅(旅行代理订阅)。
  2. 在同一页面使用 "Already subscribed?",打开我们通过电子邮件发送给你的链接,然后点击 "Create API key"。
  3. 复制密钥:它只会显示一次。一个订阅最多可同时拥有 2 个密钥;你可以在同一页面撤销密钥。

订阅尚未激活时,密钥会返回 403 subscription_inactive。API 和 MCP 服务均不提供免费套餐。网站上的 PNR converter 面向所有人免费开放,无需密钥。

连接 AI 助手(MCP)

服务 URLhttps://keyflight.io/mcp
传输方式Streamable HTTP,仅支持 POST,不使用会话,也不提供服务器发送事件流
身份验证请求头 Authorization: Bearer kfp_…
协议版本2025-06-18、2025-03-26、2024-11-05
Claude Code
claude mcp add --transport http keyflight https://keyflight.io/mcp --header "Authorization: Bearer kfp_…"
Cursor(.cursor/mcp.json)
{
  "mcpServers": {
    "keyflight": {
      "url": "https://keyflight.io/mcp",
      "headers": {
        "Authorization": "Bearer kfp_…"
      }
    }
  }
}
Claude Desktop(claude_desktop_config.json,需要 Node.js)

Claude Desktop 通过 mcp-remote 连接:

{
  "mcpServers": {
    "keyflight": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://keyflight.io/mcp",
        "--header",
        "Authorization: Bearer kfp_…"
      ]
    }
  }
}

然后可以这样提问:“解码此 PNR,并制作一张价格为 850 EUR 的 PRO 机票”,再粘贴预订内容。

其他客户端:任何支持 Streamable HTTP 和自定义请求头的 MCP 客户端。来自其他网站网页(带有浏览器 Origin 请求头)的请求会被拒绝,并返回 403 origin_not_allowed,因此请从桌面应用、命令行或你的服务连接。若没有客户端,请参阅 examples/mcp/raw-jsonrpc.sh:每个 POST 请求发送一条 JSON-RPC 消息,并返回 JSON。

MCP 工具

decode_pnr:解码 PNR

将原始 PNR 转换为易读的行程(文本)和结构化 JSON:乘客、航班、机场、航站楼、本地时间、飞行时长、航空公司定位码。

参数类型默认值描述
textstring, requiredGDS 显示的 PNR,最多 20,000 个字符。系统会根据文本识别格式。
viewtable、lines2、lines3、whatsapptable行程文本的布局。
time_format"24"、"12""24"24 小时制或 12 小时制。
date_format"short"、"numeric""short"short:2026 年 5 月 3 日;numeric:03.05.2026。

返回行程文本,随后是 JSON: 和与 PNR API 响应相同的 JSON。读取 structuredContent 的客户端可在其中获取该 JSON。

每次成功解码出航班,都会计入订阅的每月解码次数,与 API 调用相同。不含航班的文本会返回错误,且不计入次数。当月解码次数用完后,该工具会一直返回错误,直到 1 日(UTC)。

make_ticket:制作 PRO 机票 PDF

根据原始 PNR 制作 PRO 机票 PDF(PNR、航空公司标志、舱位、可选价格),并返回 PDF 链接。已包含在 KeyFlight 订阅中。

机票是提供给旅客的文件:它不是航空公司的机票,其中的 PNR 也不会与航空公司的系统核对。

参数类型默认值描述
textstring, requiredPNR,最多 20,000 个字符。每个航班都需要日期和时间。
passengers最多包含 20 个字符串的数组PNR 中的姓名机票上的乘客姓名,例如 "SMITH/JOHN MR"。
pnrstring文本中的代码,或随机代码印在机票上的预订代码,由 5–8 个字母和数字组成。
booking_classEconomy、Premium Economy、Business、First Class第一个航班的预订舱位机票上的舱位。
pricestring机票上不显示价格印在机票上的总价,例如 "1200.50"。
currency最多 10 个字符的 string"$"价格旁的货币,例如 "USD"、"€"。
logonone、expeditionnone机票页眉中的标志。
time_format"24"、"12""24"24 小时制或 12 小时制。
date_format"short"、"numeric"short 或 numeric。

返回一行 PRO ticket PDF: https://keyflight.io/tickets/….pdf,其中包含 PNR、航班数量和乘客信息;并通过 structuredContent 返回:

{ "url": "https://keyflight.io/tickets/….pdf", "pnr": "PQ7XNR", "passengers": ["JOHNSON JOHN", "JOHNSON JANE"], "segments": 2 }

机票不计入每月解码次数;一个密钥每小时最多可制作 30 张机票。

出错时(文本中没有航班、航班缺少日期或时间、没有乘客姓名、pnr 或选项错误、每小时制作超过 30 张机票),工具会返回带有 isError: true 的结果,以便助手读取错误并修正调用。

通过 HTTP 使用 PNR API

使用 Content-Type: application/json 和 Authorization: Bearer kfp_… 向 POST https://keyflight.io/api/v1/pnr/decode 发送请求。请求体为 { "text": "…", "options": { … } }。HTTP API 会以文本和 HTML 形式返回数据及行程;PRO 机票 PDF 则由 MCP 工具 make_ticket生成。以下示例使用来自 examples/pnr-amadeus.txt 的 Amadeus 预订记录。

curl
curl https://keyflight.io/api/v1/pnr/decode \
  -H "Authorization: Bearer $KEYFLIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "RP/LHRBA/LHRBA            BA/BA  26APR26/1200Z   PQ7XNR\nPQ7XNR/BA QLHR 03MAY\n1.JOHNSON JOHN\n2.JOHNSON JANE\n3  BA 178 Y 03MAY 7 LHRJFK HK2  0855 1205  03MAY  E  BA/PQ7XNR\n4  BA 117 Y 10MAY 7 JFKLHR HK2  1830 0640  11MAY  E  BA/PQ7XNR\n5 TKT/TIME LIMIT\n6 OPC LHRBA-10MAY:1900/1S2/Q TKT/T-BA\n7 FA PAX 125-2196837482/ETBA/GBP560.20/03MAY26/LHRBA2104/00390755/S3-4",
  "options": {
    "view": "table"
  }
}'
Node.js 18+

examples/api/decode.mjs:

// Node.js 18+ (fetch is built in), in an ES module or an async function
const text = `RP/LHRBA/LHRBA            BA/BA  26APR26/1200Z   PQ7XNR
PQ7XNR/BA QLHR 03MAY
1.JOHNSON JOHN
2.JOHNSON JANE
3  BA 178 Y 03MAY 7 LHRJFK HK2  0855 1205  03MAY  E  BA/PQ7XNR
4  BA 117 Y 10MAY 7 JFKLHR HK2  1830 0640  11MAY  E  BA/PQ7XNR
5 TKT/TIME LIMIT
6 OPC LHRBA-10MAY:1900/1S2/Q TKT/T-BA
7 FA PAX 125-2196837482/ETBA/GBP560.20/03MAY26/LHRBA2104/00390755/S3-4`;

const response = await fetch('https://keyflight.io/api/v1/pnr/decode', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KEYFLIGHT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ text, options: { "view": "table" } }),
});
const data = await response.json();
if (response.ok) {
  data.segments.forEach((s) => console.log(s.airlineCode, s.flightNumber, s.departure.date));
} else {
  console.error(response.status, data.error, data.message);
}
Python

examples/api/decode.py(需要 requests):

import os
import requests

text = """RP/LHRBA/LHRBA            BA/BA  26APR26/1200Z   PQ7XNR
PQ7XNR/BA QLHR 03MAY
1.JOHNSON JOHN
2.JOHNSON JANE
3  BA 178 Y 03MAY 7 LHRJFK HK2  0855 1205  03MAY  E  BA/PQ7XNR
4  BA 117 Y 10MAY 7 JFKLHR HK2  1830 0640  11MAY  E  BA/PQ7XNR
5 TKT/TIME LIMIT
6 OPC LHRBA-10MAY:1900/1S2/Q TKT/T-BA
7 FA PAX 125-2196837482/ETBA/GBP560.20/03MAY26/LHRBA2104/00390755/S3-4"""

response = requests.post(
    "https://keyflight.io/api/v1/pnr/decode",
    headers={"Authorization": f"Bearer {os.environ['KEYFLIGHT_API_KEY']}"},
    json={"text": text, "options": { "view": "table" }},
    timeout=30,
)
data = response.json()
if response.ok:
    for s in data["segments"]:
        print(s["airlineCode"], s["flightNumber"], s["departure"]["date"])
else:
    print(response.status_code, data["error"], data["message"])
选项
字段取值默认值
text必填。GDS 显示的预订信息,最多 20,000 个字符。
options.viewtable、lines2、lines3、whatsapp:itinerary 的布局。table
options.timeFormat"24"(18:30)、"12"(6:30 PM)"24"
options.dateFormat"short"(2026 年 5 月 3 日)、"numeric"(03.05.2026)"short"
options.show.logotrue / false。航空公司标志(仅限 HTML)。true
options.show.airportstrue / false。城市旁显示机场名称和航站楼。true
options.show.cabintrue / false。舱位和预订舱等:经济舱(Y)。false
options.show.statustrue / false。航段状态:已确认、候补。false
options.show.passengerstrue / false。航班上方显示乘客姓名。false
options.show.pnrtrue / false。航班上方显示预订编号和航空公司的编号。false

未知选项或错误的取值会返回 400 invalid_option,并附上字段和允许的取值。

响应

上方示例的完整响应:examples/api/response-example.json(itinerary.html 已缩短)。主要字段:

字段含义
pnrCode文本中找到的预订编号,或 null。
passengers[].namePNR 中记录的乘客姓名。
segments[].airlineCode、airlineName、flightNumber航空公司和航班号(UA0950 对应 "950")。
segments[].bookingClass、cabin预订舱等字母及其对应舱位:经济舱、高端经济舱、商务舱、头等舱。
segments[].status、statusTextPNR 中的状态代码("HK2"),以及“已确认”“候补”或该代码本身。
segments[].logoUrl航空公司标志,64×64 PNG。
segments[].duration按两个机场所在时区计算的飞行时间(分钟),或 null。
segments[].distance两个机场之间的距离 { km, miles },或 null。
segments[].aircraftCode、aircraftPNR 中显示的机型,或 null。
segments[].operatedByPNR 中显示的承运航空公司(OPERATED BY …),或 null。
segments[].airlineLocator{ airlineCode, code }:航空公司自己的预订编号,或 null。
segments[].departure、arrivalcode、city、airport、terminal、当地 date(YYYY-MM-DD)和 time(HH:MM)。
itineraryview、text 和 html(带表格和内联样式的电子邮件 HTML;whatsapp 视图下为 null)。

以下是示例在 table 视图下、options.show.logo: false 时的 itinerary.html,显示效果与免费转换器一致:

示例预订的解码行程:2026 年 5 月 3 日 BA 178 从伦敦(LHR)飞往纽约(JFK),2026 年 5 月 10 日 BA 117 从纽约(JFK)飞往伦敦(LHR)

限制

限制值
PNR 文本最多 20,000 个字符;JSON 请求体最多 100kb
每个密钥的请求数API 和 MCP 服务均为每分钟 60 次;超出后返回 429 too_many_requests,并附带 Retry-After
每个 IP 地址的请求数每分钟 120 次
每份订阅的解码次数每个日历月(UTC)3,000 次,两个密钥合计;API 和 decode_pnr 合计。仅统计找到航班的解码次数。
PRO 机票 PDF(make_ticket)每个密钥每小时 30 次

HTTP API 的响应会附带 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset 和 X-Monthly-Limit、X-Monthly-Remaining、X-Monthly-Reset。

错误

PNR API 错误采用 JSON 格式:{ "error": "<code>", "message": "…" }。

状态码error发生情况
400invalid_json请求正文不是 JSON 对象。
400text_required缺少 text 或其值为空。
400invalid_option选项未知或值不正确。field 指明相关字段,allowed 列出允许的值。
401missing_api_key未提供 Authorization: Bearer … 标头。
401invalid_api_key密钥无效或已被撤销。
403subscription_inactive密钥对应的订阅未激活。
404not_found未找到此端点。
405method_not_allowed请求方法不是 POST。
413too_long文本超过 20,000 个字符(响应中的 max 字段会显示上限)。
413payload_too_large请求正文超过 100kb。
415unsupported_encoding请求正文不是 UTF-8 编码。
422no_flights文本中没有航班。不会计入每月限额。
429too_many_requests超出每分钟限额;请等待 Retry-After 秒。
429monthly_limit_reached该订阅本月的解析次数已用完。
500server_error我们这边发生了错误。
503service_unavailable目前无法验证密钥。请一分钟后重试。

工具运行前,MCP 服务会以相同的 JSON 格式返回以下错误:401 missing_api_key / invalid_api_key、403 subscription_inactive、429 too_many_requests 和 503 service_unavailable;此外,对于来自其他网站网页的请求,还会返回 403 origin_not_allowed;对于非 POST 请求,还会返回 405 method_not_allowed。在工具内部发生的错误(包括达到每月限额)会作为工具结果返回,并带有 isError: true。

支持的 GDS 格式

Amadeus (1A)、Sabre (1B/1S)、Galileo (1G) 和 Worldspan (1P)。请按 GDS 显示的格式发送预订信息;无需说明其来源系统。各系统的预订示例:Amadeus、Sabre、Galileo、Worldspan。

链接

许可证

本仓库中的示例和文档遵循 MIT License。KeyFlight 服务并非开源;使用该服务需要订阅 KeyFlight。

评论

支持 Markdown

第一次接触 MCP?

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

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