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. 014種類のGDS形式のPNRを解析
  2. 02読みやすい旅程と構造化JSONを出力
  3. 03旅程のレイアウトと日時形式を選択
  4. 04価格を指定可能なPROチケットPDFを生成

活用シーン

  1. 01GDS予約を旅客向けの旅程に変換
  2. 02解析した予約データを予約ツールやCRMに渡す
  3. 03PNRから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 は、ホスト型の Model Context Protocol サーバー(https://keyflight.io/mcp)と、HTTP API(https://keyflight.io/api/v1/pnr/decode)を提供しています。どちらも、keyflight.io にある無料の PNR converter と同じデコーダーを使用します。

このリポジトリには、ドキュメントとサンプルが含まれています。サーバー自体は KeyFlight がホストしているため、インストールや実行は不要です。リファレンスの全文は keyflight.io/pnr-api をご覧ください。

対象ユーザー: GDS の予約を扱う旅行代理店や旅行会社、および予約ツール、CRM、チャットボット、メールのワークフローに PNR デコード機能を追加する開発者です。

API キーを取得する

MCP サーバーと PNR API では、同じキーを使用します。キーは kfp_ の後に43文字の英字、数字、-、_ が続く形式です。

  1. KeyFlight サブスクリプション(旅行代理店向けのサブスクリプション)を取得します。
  2. 同じページで 「すでに登録済みですか?」 を選び、メールで届くリンクを開いて 「API キーを作成」 を押します。
  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 ごとに1つの 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:、そして同じ JSON です。PNR API の応答をご覧ください。structuredContent を読み取るクライアントは、そこから JSON を取得できます。

フライトが見つかったデコードは、それぞれ API 呼び出しと同様に、サブスクリプションの月間デコード数にカウントされます。フライトを含まないテキストはエラーを返し、カウントされません。その月のデコード数を使い切ると、1 日(UTC)までツールはエラーを返します。

make_ticket:PRO チケット PDF を作成する

未加工の PNR から PRO チケット PDF(PNR、航空会社のロゴ、クラス、任意の料金)を作成し、PDF へのリンクを返します。KeyFlight サブスクリプションに含まれています。

このチケットは旅行者向けの書類です。航空券ではなく、PNR も航空会社のシステムで照合されません。

引数型デフォルト説明
textstring, requiredPNR。最大 20,000 文字です。すべてのフライトに日付と時刻が必要です。
passengersarray of strings, up to 20PNR 内の名前チケットに記載する搭乗者名。例:"SMITH/JOHN MR"。
pnrstringテキスト内のコード、またはランダムなコードチケットに印字する予約コード。英字と数字を 5~8 文字で指定します。
booking_classEconomy, Premium Economy, Business, First Class最初のフライトの予約クラスの客室チケットに記載するクラスです。
pricestringチケットに料金を記載しないチケットに印字する合計料金。例:"1200.50"。
currencystring, up to 10 characters"$"料金の横に表示する通貨。例:"USD"、"€"。
logonone, expeditionnoneチケットのヘッダーに表示するロゴです。
time_format"24", "12""24"24 時間表記または 12 時間表記です。
date_format"short", "numeric"short または numeric。

返される内容は、PNR、フライト数、搭乗者名を含む PRO ticket PDF: https://keyflight.io/tickets/….pdf の行と、structuredContent です。

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

チケットは月間デコード数にカウントされません。1 つのキーで 1 時間に最大 30 枚のチケットを作成できます。

エラー(テキストにフライトがない、フライトに日付または時刻がない、搭乗者名がない、pnr またはオプションが誤っている、1 時間に 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"(3 May 2026)、"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[].duration2空港のタイムゾーンを考慮したフライト時間(分)、または null。
segments[].distance2空港間の距離 { 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 表示の例の itinerary.html(options.show.logo: false):

予約例をデコードした旅程:BA 178、2026年5月3日、ロンドン(LHR)からニューヨーク(JFK)、BA 117、2026年5月10日、ニューヨーク(JFK)からロンドン(LHR)

制限

制限値
PNRテキスト最大20,000文字。JSON本文は最大100kb
キーごとのリクエスト数APIとMCPサーバーでそれぞれ1分あたり60件。超過すると Retry-After を含む 429 too_many_requests が返されます
IPアドレスごとのリクエスト数1分あたり120件
サブスクリプションごとのデコード数1暦月(UTC)あたり3,000件。2つのキーを合算し、APIと decode_pnr を合算します。フライトが見つかったデコードのみがカウントされます。
PROチケットPDF(make_ticket)キーごとに1時間あたり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_requiredtext がないか、空です。
400invalid_option不明なオプション、または誤った値です。field に項目名、allowed に許可される値が列挙されます。
401missing_api_keyAuthorization: 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_requests1 分あたりの上限を超えています。Retry-After 秒待ってください。
429monthly_limit_reached今月のサブスクリプションのデコード回数を使い切りました。
500server_errorサーバー側で問題が発生しました。
503service_unavailable現在キーを確認できません。1 分後にもう一度お試しください。

ツールの実行前に、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 のサブスクリプションが必要です。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。