ourairports-mcp-server について
パブリックドメインのOurAirportsデータセットをオフラインで提供するMCPサーバーです。空港、滑走路、航法援助施設、無線周波数を調べる旅行者や研究者向けです。
主な機能
- 015種類のコードで空港を特定
- 02空港検索と滑走路条件の絞り込み
- 03座標から近隣の空港や航法援助施設を検索
- 04滑走路と周波数を含む空港情報を取得
- 05国と地域の参照データを一覧
活用シーン
- 01IATA、ICAO、GPS、ローカルコードから空港を特定
- 02地点周辺の空港や航法援助施設を検索
- 03路面、寸法、灯火、空港エリアで滑走路を絞り込み
MCP 対応
MCPクライアントに6種類の航空データツールと`airport://{code}`リソースを公開します。データセットを同梱してオフライン利用に対応し、stdioとStreamable HTTPで接続できます。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://ourairports.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-ourairports https://ourairports.caseyjhand.com/mcp{"mcpServers":{"cyanheads-ourairports":{"type":"http","url":"https://ourairports.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-ourairports":{"type":"http","url":"https://ourairports.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-ourairports":{"type":"http","url":"https://ourairports.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-ourairports":{"serverUrl":"https://ourairports.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
6| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| type | enum | いいえ | 空港の種別を 1 つに限定します:large_airport、medium_airport、small_airport、heliport、seaplane_base、balloonport、closed。large_airport | medium_airport | small_airport | heliport | seaplane_base | balloonport | closed |
| limit | integer | いいえ | 返す空港の最大数(1~100)。デフォルトは OURAIRPORTS_DEFAULT_SEARCH_LIMIT(20)です。 |
| query | string | いいえ | 空港名、自治体、キーワードを対象にフリーテキスト検索します。各語句は AND 条件で一致します。省略すると、分類のみで検索します。 |
| region | string | いいえ | ISO 3166-2 地域コードで絞り込みます(例:US-WA)。完全一致で、大文字と小文字は区別せず、前後の空白は無視します。 |
| country | string | いいえ | ISO 3166-1 alpha-2 国コードで絞り込みます(例:US)。完全一致で、大文字と小文字は区別せず、前後の空白は無視します。コードの確認には ourairports_list_countries を使用してください。 |
| include_closed | boolean | いいえ | 種別が "closed" の空港を含めます。デフォルトでは無効です。閉鎖された空港は、運航中のフライト位置特定の用途に不要なノイズを加えます。 |
詳細
@cyanheads/ourairports-mcp-server
同梱されたパブリックドメインの OurAirports データセットを使用して、MCP 経由で空港コード(IATA/ICAO/GPS/ローカル)を解決し、空港を検索し、座標から最寄りの空港を検索し、滑走路、航法援助施設、無線周波数を調べます。STDIO または Streamable HTTP に対応しています。
公開ホスト型サーバー: https://ourairports.caseyjhand.com/mcp
概要
パブリックドメインの OurAirports データセットを同梱しており、世界中の空港、滑走路、航法援助施設、無線周波数をオフラインで利用できます。任意のコードで空港を特定したり、名前や条件で検索したり、座標から最寄りの空港や航法援助施設を検索したりできます。
ツール
| ツール | 説明 |
|---|---|
ourairports_search_airports | 空港データ全体を対象に、名称、自治体、国、地域、種類で全文検索および条件検索を行います。検索順位付きの概要を返し、デフォルトでは閉鎖済みの空港を除外します。 |
ourairports_search_runways | 全空港の滑走路を対象に、舗装面の種類、長さ、幅、照明で検索します。該当する空港の情報を結合し、国、地域、空港の種類で絞り込めます。一致する滑走路ごとに、フラットな { airport, runway } 行を 1 件返します。 |
ourairports_get_airport | 任意のコード(IATA/ICAO/GPS/ローカル/ident)で特定した空港の完全なレコードを、滑走路と無線周波数を含めて返します。 |
ourairports_find_airports | 座標から一定半径内にある空港を大圏距離の近い順に並べ、距離と方位を表示します。 |
ourairports_find_navaids | 座標の近くにある、または特定の空港に対応する航法援助施設(VOR、VOR-DME、DME、NDB、NDB-DME、TACAN、VORTAC)を検索します。 |
ourairports_list_countries | 空港数と、任意でネストされた地域を含む国の一覧を、国および/または大陸で絞り込みます。両方の検索ツールで使用できる country/region フィルターの有効な値を確認するための一覧です。 |
リソース
| リソース | 説明 |
|---|---|
airport://{code} | 任意のコード(IATA/ICAO/GPS/ローカル/ident)で取得する単一の空港レコードです。滑走路と周波数もインラインで含まれます。 |
すべてのデータは ourairports_get_airport からも取得できます。ツールのみを使うクライアントも、利用できる情報に違いはありません。リソースリストとしては公開していません(85k件の空港を列挙しても、探索の助けにはならず、データの羅列になるためです)。探索には ourairports_search_airports を使用します。
機能リファレンス
ourairports_search_airports tool
- 名前、自治体、キーワードを対象にしたフリーテキスト検索です。トークンはAND条件で照合されます(単語の順序や部分一致にも対応しています)。
- ファセットフィルター:
country(2文字)、region(2文字に続けて、ハイフンで区切られた1~3文字または数字のセグメントが1つまたは2つ)、type。コードでは大文字と小文字を区別せず、前後の空白は無視します。リテラルの""は未設定として扱い、空白のみの値は無効です。不正なコードは引数検証エラーになります。同梱テーブルに存在しないコードは、探索方法の案内を含むunknown_country/unknown_regionエラーになります。有効なコードで空港が見つからない場合は、空の結果を正常に返します。 - デフォルトでは閉鎖された空港を除外します。含めるには
include_closedを指定します。 - 運用中の空港や規模の大きな空港を優先して結果を並べます。各結果には、
ourairports_get_airportに渡すための完全なコードセットと座標が含まれます。 limitは1~100行を受け付け、デフォルトはOURAIRPORTS_DEFAULT_SEARCH_LIMIT(20)です。結果が切り詰められた場合は、一致件数の合計、上限、結果を得るための案内が報告されます。
ourairports_search_runways tool
- 空港ファセット(
country、region、type)で先に空港を絞り込み、その後、滑走路ファセット(surface、min_length_ft、min_width_ft、lighted)で滑走路を絞り込みます。 - 国/地域ファセットには、
ourairports_search_airportsと同じ形式、空文字列の扱い、正規化、同梱データ内の有効性ルールが適用されます。有効な条件で結果が空の場合も、正常に処理されます。 surfaceは、上流データの表面文字列に対する大文字と小文字を区別しない部分一致です(固定の用語一覧はありません。aspのような短い文字列で、ASP、ASPH、Asphalt に一致します)。完全一致コードではありません。- 一致する滑走路ごとに
{ airport, runway }のフラットな行を1件返します。一致する滑走路が3本ある空港は、3行を占めます。 lengthFtとmin_length_ftは、OurAirports が記録した滑走路表面の全長です。変位した滑走路端やオーバーランを含み、使用可能な離着陸距離ではありません。各滑走路にはleDisplacedThresholdFt/heDisplacedThresholdFtも含まれます(記録がない場合はnull)。- 長さまたは幅が不明な滑走路は、該当する
min_*_ftフィルターが指定されている場合に除外されます。データで確認できない閾値を満たすものとは見なしません。 include_closed_airports/include_closed_runwaysを指定しない限り、閉鎖された空港と滑走路の両方を除外します。limitは1~100行を受け付け、デフォルトはOURAIRPORTS_DEFAULT_SEARCH_LIMIT(20)です。結果が切り詰められた場合は、一致件数の合計、上限、結果を得るための案内が報告されます。
ourairports_get_airport tool
- 5種類すべての識別子空間を対象に、単一の
codeを大文字と小文字を区別せずに解決します(優先順位:ident → ICAO → IATA → GPS → local)。前後の空白は無視されます。 - 滑走路と無線周波数をインラインで含みます。
includeを指定すると応答を一部に絞り込めます。出力のincludedフィールドで、includeによって省略された関連データと、該当レコードが実際に存在しない場合を区別できます。 - 空港の完全なコードセットと
resolvedVia/resolutionNoteを返します。同じコードを持つ別の空港がある場合は、各空港(ident、国、コード空間)を注記し、優先順位またはデータセットの行順のどちらによってこの空港が選ばれたかを示します。誤った解決を修正できるよう、別の空港のidentを渡してください。 - 滑走路には、表面全長を示す
lengthFtと、滑走路両端の変位した滑走路端を示すleDisplacedThresholdFt/heDisplacedThresholdFtが含まれます。 - 存在しないコードは
nullとして報告されます。閉鎖された空港も常に解決されます。 - どの識別子空間にも一致しない場合は、再試行方法のヒントを含む
unknown_codeエラーになります。
ourairports_find_airports ツール
- 大圏距離(ハバーサイン)で順位付けし、近い順に並べます。各結果には、クエリ地点からの距離を示す
distanceKmと、真方位(度)を示すbearingDegが含まれます radius_km(1~500、デフォルトは100)。limit(1~50)のデフォルト値はOURAIRPORTS_DEFAULT_SEARCH_LIMITで、このツールの最大値である50に制限されます。typeフィルターは任意で、include_closedは指定した場合にのみ有効です- 座標を入力すると、順位付けされた空港が返されます。ジオコーディングは行われないため、場所の名前は事前に上流で緯度・経度に変換してください
totalCountは、limit適用前の半径内のフィルター済み件数です。結果が上限で切り詰められた場合は、上限と、絞り込み方法(radius_kmを狭める、typeを追加する、またはlimitを上げる)が示されます- 半径内に結果がない場合は、
radius_kmを広げるよう案内します
ourairports_find_navaids ツール
- 座標モード:
latitudeとlongitude(および任意のradius_km、1~500、デフォルトは100)を指定すると、無線航法援助施設を距離と方位で近い順に順位付けします。limit(1~50)のデフォルト値はOURAIRPORTS_DEFAULT_SEARCH_LIMITで、50に制限されます - 空港モード:
airport_codeを指定すると、その空港にサービスを提供する無線航法援助施設が返されます - どちらか一方のモードを完全な形で指定する必要があります。両方のモードを指定した場合、どちらも指定しなかった場合、または座標が不完全な場合は、
mode_conflictが発生します。不完全な座標の場合は、不足しているもう一方の座標がエラーメッセージに示されます frequencyKhzはすべての種類で保存されている値です(114.5 MHz の VOR は 114500 と表示されます)。frequencyMhzには、VOR または VOR-DME の VHF 周波数と、DME、TACAN、または VORTAC のペアとなる VHF 周波数が格納されます。kHz で受信する NDB と NDB-DME の場合はnullです。上流データの-1プレースホルダーはnullとして表示されます- 各無線航法援助施設には、上流データに記録されているサービス範囲のメタデータが含まれます。
usageType(HI、LO、BOTH、TERMINAL、RNAV)、power、magneticVariationDeg(実際の磁気偏差、東偏が正)、slavedVariationDeg(ラジアルに組み込まれた偏差)、dmeFrequencyKhz(DME のペアとなる VHF 周波数)が含まれます。データセットに値がない項目はnullです totalCountは、両方のモードでlimit適用前の一致件数です。結果が上限で切り詰められた場合は、上限と回復方法が示されます- 空港モードでは、「空港が見つからない」場合(
unknown_codeエラー)と、「空港は見つかったが関連する無線航法援助施設がない」場合(注記付きの空のリスト)が区別されます airport_codeがほかの空港のコードとしても使われている場合、空港モードでは、それらの空港を ident で示すresolutionNoteが追加されます。同じ注記はourairports_get_airportでも返されます
ourairports_list_countries ツール
countryとcontinent(AF、AN、AS、EU、NA、OC、SA)は任意で指定でき、両方を指定した場合は AND 条件で適用されます。include_regionsを指定すると、記録された国との関連付けに基づいて地域がネストされます(そのため、KS-U-AはXKに属します)- ある国の地域のみを取得するには、
{ "country": "US", "include_regions": true }を使用します。スコープを指定しないinclude_regionsは地域テーブル全体を返します。スコープを指定しないリクエストや、大陸のみを指定するリクエストも引き続き受け付けます countryには、検索ツールと同じ形式、正規化、メンバーシップのルールが適用されます。""は未設定として扱われ、空白のみの値は無効です。存在しないコードを指定するとunknown_countryが発生します- 空港数には閉鎖済みの空港は含まれません
- 国は名前順に並びます。
ourairports_search_airportsとourairports_search_runwaysのcountry/regionフィルターで有効な値を照合するためのテーブルです - 国と大陸の組み合わせが一致しない場合は、両方のフィルターを示す通知とともに、空の成功結果が返されます。
totalCountは返された国の件数です
airport://{code} リソース
ourairports_get_airportと同じレコードを返し、resolutionNoteも同じです。滑走路と無線周波数は常にインラインで含まれるため、include/includedはありませんcodeは、5つすべての識別子空間を対象に、大文字と小文字を区別せずに解決されます(優先順位:ident → ICAO → IATA → GPS → local)- どの識別子空間にも一致しない場合は、回復方法のヒントを含む
unknown_codeエラーが返されます
特長
@cyanheads/mcp-ts-core を基盤としています。stdio および Streamable HTTP トランスポート、差し替え可能な認証(none / jwt / oauth)、差し替え可能なストレージ(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1)、オプションの OpenTelemetry トレーシングを備えた構造化ログに対応しています。
OurAirports 固有の特長:
- パブリックドメインのデータセットをパッケージと Docker イメージに同梱しています。実行時の API 呼び出し、キー、レート制限、上流の障害は不要です
- 起動時に一度だけインメモリーインデックスを構築します。ID マップ、優先順位付きの統合コードインデックス、滑走路と周波数の空港参照結合、ident をキーにした航法援助施設の結合、座標のフラットな
Float64Array、国/地域マップ、トークン化されたテキスト検索インデックスを含みます - 座標配列に対する総当たりのハバースイン距離による最近傍検索を実行します。8万5千件の空港を数ミリ秒で処理でき、空間インデックスへの依存はありません
- CSV は列位置ではなくヘッダー名で解析するため、上流で列の順序が変わってもフィールドが気付かないうちにずれることはありません
- 空港検索では順位付けされた候補を最大
limit件まで保持します。滑走路検索では先頭からlimit行を保持しますが、どちらも一致件数はすべてカウントします
エージェントに適した出力:
- 実際のデータの疎さをそのまま反映します。上流に存在しないフィールド(IATA なし、標高なし、滑走路寸法が null)は、捏造せず
nullとして返します - 自己修正可能な解決処理:すべての空港レコードにコード一式を含め、同じコードを共有するほかの空港をすべて ident で示す
resolvedVia/resolutionNoteを返します - テキスト出力は構造化出力と一致します。座標は完全な精度で表示し、上流のテキストは
content内でのみ Markdown エスケープするため、GRASS&GRAVELのような名称も記録どおりに表示されます - 切り詰めや検索結果が空の場合も明示します。合計件数、適用された上限、検索範囲を広げる、絞り込む、再検索するといった案内を示すため、呼び出し元は説明文を解析する必要がありません
はじめに
公開ホスト型インスタンス
https://ourairports.caseyjhand.com/mcp で公開インスタンスを利用できます。インストールは不要です。以下のクライアント設定を使い、Streamable HTTP 経由で任意の MCP クライアントから接続してください。
{
"mcpServers": {
"ourairports-mcp-server": {
"type": "streamable-http",
"url": "https://ourairports.caseyjhand.com/mcp"
}
}
}
セルフホスト/ローカル
以下を MCP クライアントの設定ファイルに追加してください。
{
"mcpServers": {
"ourairports-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/ourairports-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、npx を使う方法(Bun は不要です):
{
"mcpServers": {
"ourairports-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/ourairports-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、Docker を使う方法:
{
"mcpServers": {
"ourairports-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/ourairports-mcp-server:latest"
]
}
}
}
API キーは不要です。データセットはパッケージとイメージに同梱されています。
Streamable HTTP を使用するには、トランスポートを設定してサーバーを起動します。
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前提条件
- Bun v1.4.0 以上(または Node.js v24 以上)。
- API キー、アカウント、外部サービスは不要です。すべてのデータが同梱されています。
インストール
- リポジトリをクローンします:
git clone https://github.com/cyanheads/ourairports-mcp-server.git
- ディレクトリに移動します:
cd ourairports-mcp-server
- 依存関係をインストールします:
bun install
- データセットを取得して同梱します(6 つの CSV を
data/に書き込みます):
bun run build:data
データの更新
同梱されるスナップショットは、最後に build:data を実行した時点(Docker イメージの場合は最後にビルドした時点)のデータです。OurAirports ミラーから最新の日次データを取得するには、bun run build:data を再実行してビルドし直してください。ビルドでは、取得したデータ一式を書き込む前に、国/地域コードの形式と空港参照をルックアップテーブルに照らして検証します。既存のデータ一式を検証するには、bun run build:data --check を実行してください。再ビルドせずに既存のローカルデータを指定するには、OURAIRPORTS_DATA_DIR を設定してください。
設定
| 変数 | 説明 | デフォルト |
|---|---|---|
OURAIRPORTS_DATA_DIR | 6つの OurAirports CSV ファイルを格納するディレクトリです。より新しいローカルデータの保存先を指定するために上書きできます。 | 同梱の data/ |
OURAIRPORTS_DEFAULT_SEARCH_LIMIT | 呼び出し側で limit が省略された場合の検索/検索ツールのデフォルト結果数上限(1~100)です。 | 20 |
MCP_TRANSPORT_TYPE | トランスポート:stdio または http。 | stdio |
MCP_HTTP_PORT | HTTP サーバーのポートです。 | 3010 |
MCP_HTTP_ENDPOINT_PATH | サーバーがマウントされる HTTP エンドポイントのパスです。 | /mcp |
MCP_AUTH_MODE | 認証モード:none、jwt、または oauth。 | none |
MCP_SESSION_MODE | HTTP セッションモード:stateful、stateless、または auto。このサーバーでは、ツールリクエストが追加の入力を要求しないため、ステートレスモードを使用します。 | stateless |
MCP_LOG_LEVEL | ログレベル(RFC 5424)です。 | info |
LOGS_DIR | ログファイル用のディレクトリです(Node.js のみ)。 | <project-root>/logs |
STORAGE_PROVIDER_TYPE | ストレージバックエンドです(データパスでは未使用です。インデックスはメモリ内にあります)。 | in-memory |
OTEL_ENABLED | OpenTelemetry インストルメンテーションを有効にします。 | false |
オプションで上書きできる項目の全一覧は、.env.exampleを参照してください。
サーバーの実行
ローカル開発
-
ビルドして実行:
# One-time data fetch + build bun run build:data bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
チェックとテストの実行:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t ourairports-mcp-server .
docker run --rm -i -e MCP_TRANSPORT_TYPE=stdio ourairports-mcp-server
ビルドステージでは bun run build:data を実行し、データセットを取得してイメージに組み込みます。そのため、生成されるコンテナは完全に自己完結しており、実行時にネットワークアクセスを行いません。Dockerfile では、HTTP トランスポート、ステートレスセッションモード、および /var/log/ourairports-mcp-server へのログ出力がデフォルトで設定されています。OpenTelemetry のピア依存関係はデフォルトでインストールされます。省略するには、--build-arg OTEL_ENABLED=false を指定してビルドしてください。
プロジェクト構成
| ディレクトリ | 目的 |
|---|---|
src/index.ts | createApp() のエントリーポイントです。ツール/リソースを登録し、setup() で同梱のインデックスを読み込みます。 |
src/config | サーバー固有の環境変数の解析と、Zod による検証を行います。 |
src/mcp-server/tools | ツール定義(*.tool.ts)です。空港、滑走路、無線航法援助施設に関する6つの読み取り専用ツールがあります。 |
src/mcp-server/resources | リソース定義です。airport://{code} のレコードを提供します。 |
src/services/airport-data | 同梱データのサービスです。CSV の解析、メモリ内インデックス、コードの解決、検索、ハバーサイン距離による地理的スキャンを行います。 |
scripts/build-data.ts | ビルド時に6つの OurAirports CSV を取得し、data/ にまとめるスクリプトです。 |
framework-skills/ | @cyanheads/mcp-ts-core と同期されたプロジェクト開発スキルです。 |
tests/ | src/ に対応する単体テストと統合テストです。 |
開発ガイド
開発ガイドラインとアーキテクチャ上のルールについては、CLAUDE.md/AGENTS.mdを参照してください。要点は次のとおりです。
- ハンドラーは例外をスローし、フレームワークが捕捉します。ツールのロジック内で
try/catchを使わないでください - リクエスト単位のログには
ctx.logを、テナント単位のストレージにはctx.stateを使用してください - 新しいツールとリソースは、
src/mcp-server/*/definitions/index.tsのバレル経由で登録してください - 上流データはそのまま提示してください。不在のフィールドは
nullとして報告し、欠損値を決して捏造しないでください
クレジット
空港、滑走路、無線航法援助施設、および周波数のデータは、OurAirportsから提供されており、パブリックドメインに捧げられています。クレジット表記は礼儀として行うもので、必須ではありません。ソース CSV は毎日 davidmegginson.github.io/ourairports-data で公開されています。
OurAirports はコミュニティによって編集されています。データはそのまま提示され、実際の航空運航における正式な情報ではありません。クラウドソーシングによる参考情報と同様に扱ってください。
コントリビュート
問題の報告を歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
Apache-2.0 — 詳細は LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。