Charlotte Area Transit (CATS) について
QueensCoachは、Charlotte Area Transit Systemのバスとライトレールのデータを提供する、旅行者や交通情報クライアント向けのMCPサーバーです。経路検索とリアルタイム情報に加え、時刻表、路線、車両位置、運行アラートを扱います。
主な機能
- 01徒歩と乗り換えを含む経路検索
- 02リアルタイム到着時刻と遅延の確認
- 03停留所の時刻表と路線情報の閲覧
- 04運行アラートと乱れの確認
- 05停留所の検索と車両位置の追跡
- 06静的・リアルタイムGTFSリソースの提供
活用シーン
- 01地点間のバス・鉄道ルートの検索
- 02停留所の到着予測の確認
- 03指定日の出発時刻の確認
- 04近くの駅や運行中の車両の検索
MCP 対応
公開時刻表とGTFS-Realtimeフィードを基に、CATSの交通ツールとGTFSリソースをMCPクライアントに提供します。stdioとStreamable HTTPに対応し、ホスト版HTTPサーバーではGoogle OAuthを使用します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://queenscoach.adamwanninger.com/mcpclaude mcp add --transport http ajwann-queenscoach https://queenscoach.adamwanninger.com/mcp{"mcpServers":{"ajwann-queenscoach":{"type":"http","url":"https://queenscoach.adamwanninger.com/mcp"}}}Cursor で開く{"servers":{"ajwann-queenscoach":{"type":"http","url":"https://queenscoach.adamwanninger.com/mcp"}}}VS Code で開く{"mcpServers":{"ajwann-queenscoach":{"type":"http","url":"https://queenscoach.adamwanninger.com/mcp"}}}{"mcpServers":{"ajwann-queenscoach":{"serverUrl":"https://queenscoach.adamwanninger.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
QueensCoach ♔♘
QueensCoach は、Charlotte Area Transit System(CATS)のバスとライトレール向けの MCP サーバーです。同機関の公開 GTFS 時刻表フィードと GTFS-Realtime フィードを利用して構築されています。経路を計画し、到着時刻を予測し、時刻表を読み取り、路線を説明し、運行アラートを報告します。MCP クライアントが起動する stdio 経由、または Google OAuth を前段に置いた HTTP 経由で、ホスト型サーバーとして動作します。どちらのトランスポートでも、同じツールとリソースを提供します。
ホスト型サーバー
Google Cloud Run で公開インスタンスが稼働しています。Google アカウントがあればサインインできます。
https://queenscoach.adamwanninger.com/mcp
稼働時間は一切保証されません。 ホスト型サーバーは現状のまま提供されます。遅くなったり、停止したり、利用上限額に達して停止したり、予告なく終了したりする場合があります。頼りにする用途では、ご自身で運用してください。stdio 経由で実行するか、ご自身の Google Cloud プロジェクトで deploy/GCP.md を使ってください。
サインインすると、サーバーには Google アカウントのメールアドレスが通知されます。これはアクセスを許可するかどうかの判定にのみ使用され、保存されることはありません。サーバーが発行するトークンには、Google アカウントの不透明な ID のみが記録され、それ以外の情報は含まれません。ツールに共有した位置情報は、その呼び出しの引数として渡され、応答に使用されますが、保存されません。ホスト型サーバーには、プライバシーポリシーと利用規約が適用されます。
Claude への追加
Claude では、リモート MCP サーバーをコネクタと呼びます。カスタムコネクタは、Claude の有料プランで利用できます。
- 設定 → コネクタを開きます。ウェブではclaude.ai/settings/connectors、デスクトップアプリでは「設定」から「コネクタ」を選びます。
- リストの下部にあるカスタムコネクタを追加をクリックします。
- 名前に
QueensCoachを指定し、上記の URL をリモート MCP サーバーの URL として貼り付けます。高度な OAuth フィールドは空のままにしてください。このサーバーがクライアントを自動的に登録します。 - 追加をクリックし、表示されたコネクタの接続をクリックします。Google サインイン用のブラウザーウィンドウが開くので、承認すると自動的に閉じます。
- チャットでツールメニューを開き、QueensCoach が有効になっていることを確認します。7 つのツールが表示されます。
コネクタは Claude アカウントに紐づくため、ウェブ、デスクトップ、モバイルで利用できます。接続を解除するには、同じ「コネクタ」ページから削除してください。これにより、このサーバーが発行したトークンが無効になります。
Claude Code への追加
claude mcp add --transport http queenscoach https://queenscoach.adamwanninger.com/mcp
次に /mcp を実行し、queenscoach を選んで認証を選択します。同じ Google サインイン画面が開きます。その後、/mcp で接続状態を確認できます。この方法で追加したサーバーは、Claude Code の次回起動時に読み込まれます。
その他のクライアント
OAuth を使用してストリーミング可能な HTTP 経由のリモートサーバーに対応する MCP クライアントであれば、同じ URL を指定するだけで、残りの情報が自動的に検出されます。
ツール
| ツール | 目的 |
|---|---|
plan_trip | バスと電車を使い、徒歩や乗り換えを含めて2地点間を移動します。リアルタイムの遅延に応じて調整されます。 |
get_arrivals | 指定した停留所、または場所に最も近い駅への到着予測をリアルタイムで取得します。 |
get_schedule | 任意の日付について、停留所の公開時刻表を取得します。発車時刻、始発、終発が含まれます。 |
get_route | 指定した日付の1つの路線について、行き先、停留所の順序、運行時間、運行頻度を取得します。 |
get_service_alerts | システム全体または路線、停留所、場所に関する、現在および今後の迂回や運行障害を取得します。 |
list_stops | 停留所や駅と、それぞれに乗り入れる路線を、指定した場所から近い順に取得します。 |
list_vehicles | 運行中のバスや電車のGPS位置を取得します。車両番号、路線単位、またはすべての車両を指定できます。 |
Claude に「自分に一番近い駅はどこ?」「自分の停留所に次の電車が来るのはいつ?」「ここから空港へはどう行けばいい?」などと尋ねると、デバイスの位置情報がツールに渡されます。サーバーは渡されていない位置情報を見ることはありません。そのため、デバイスの位置情報をモデルと共有するクライアントが必要です。
plan_trip
| 引数 | 型 | 備考 |
|---|---|---|
origin_stop | string | 出発地:停留所ID、コード、または名前です。 |
origin_latitude、origin_longitude | number | または、場所から出発して近くの停留所まで歩きます。 |
destination_stop | string | 行き先:停留所ID、コード、または名前です。 |
destination_latitude、destination_longitude | number | または、場所を目的地にします。 |
date | YYYY-MM-DD | シャーロットでの運行日(デフォルトは今日)です。 |
depart_at | HH:MM | この時刻より早く出発しないようにします。デフォルト:現在時刻です。 |
arrive_by | HH:MM | または、この時刻までに到着します。 |
max_transfers | integer | 0〜3(デフォルトは2)です。 |
max_walk_meters | integer | 最初の停留所まで、または最後の停留所から歩く距離の上限です。100〜2000(デフォルトは800)です。 |
徒歩区間と乗車区間からなる最大3件の旅程を返します。各旅程には、路線、車両の実際の行き先、乗車・降車場所、時刻、各乗り換え時の待ち時間、通過する停留所が含まれます。乗り換え回数が多い旅程は、より早く到着する場合(または arrive_by の場合は、より遅く出発できる場合)にのみ提示されます。現在から3時間以内に始まる旅程では、乗車区間にリアルタイムの遅延が反映され、live と表示されます。2つの場所が互いに徒歩圏内にある場合は、walkingIsAnOption が表示されます。
徒歩距離は推定値です。直線距離を30%延長し、時速4.5 kmで計算しています。フィードには道路地図がないため、実際の徒歩距離はさらに長くなる場合があります。乗り換えでは、徒歩距離が最大400 m、乗り換え時間の余裕が2分まで考慮されます。
get_arrivals
| 引数 | 型 | 備考 |
|---|---|---|
stop | string | 停留所ID(02400)、停留所コード、または停留所名の一部(CTC Station)です。 |
latitude、longitude | number | stop の代わりに指定し、この場所に最も近い駅を使います。 |
route | string | 任意の路線フィルターです。 |
mode | bus | train | 任意の交通手段フィルターです。 |
limit | integer | 到着情報の最大件数(デフォルトは10、上限は50)です。 |
stop または場所のいずれかを指定してください。場所を指定した場合、フィルターによって駅も選択されます。たとえば mode: train は、より近いバス停ではなく、電車が停車する最寄りの停留所を検索し、応答には metersAway が含まれます。
到着までの分数、予測時刻と時刻表上の時刻、時刻表からのずれ、車両番号、ホーム(stopId)、車両のリアルタイム位置を返します。名前での検索結果が曖昧な場合は、最も一致する候補が使われ、次点の候補は otherStopsMatchingQuery に一覧表示されます。停留所またはその路線に影響する現在の運行情報は、get_service_alerts と同じ形式で serviceAlerts として付加されます。次の1時間程度を超える先の時刻については、get_schedule を使用してください。
get_schedule
| Argument | Type | Notes |
|---|---|---|
stop | string | 停留所 ID、コード、または名称です。 |
latitude, longitude | number | または、路線や交通モードに対応する最寄りの停留所です。 |
route | string | 任意の路線フィルターです。 |
mode | bus | train | 任意のフィルターです。 |
date | YYYY-MM-DD | 運行日です(デフォルトは今日)。 |
after, before | HH:MM | 時間帯です。after のデフォルトは今日の現在時刻、または運行開始時刻です。 |
limit | integer | 出発便の最大数です(デフォルトは 20、上限は 100)。 |
各便の路線と行き先を含む発車予定に加え、その日の firstDeparture と
lastDeparture を返します。GTFS と同様に、運行日は深夜を越えて続きます。火曜日の
最終列車は水曜日の午前 1 時 31 分に出発し、after または before の 25:30 は
その日の午前 1 時 30 分を意味します。リアルタイムの予測には get_arrivals を
使用してください。
get_route
| Argument | Type | Notes |
|---|---|---|
route | string | 必須です。 9、501、Blue Line、Airport。 |
date | YYYY-MM-DD | 運行日です(デフォルトは今日)。 |
各方向について、行き先、停留所の順序(大半の便が利用する経路に従い、それ以外は まとめて表示)、始発と最終の出発便、早朝、朝のラッシュ時間帯、昼間、午後の ラッシュ時間帯、夕方、深夜の標準的な運行間隔(分)を返します。また、今後 7 日間 それぞれの運行便数と、有効なアラートの数も返します。複数の路線に一致する検索では、 該当する路線を一覧表示します。
get_service_alerts
| Argument | Type | Notes |
|---|---|---|
route | string | 路線名、またはその路線が停車する停留所名が記載されたアラートです。 |
stop | string | 駅名、またはそこに停車する路線名が記載されたアラートです。 |
latitude, longitude | number | 800 m 以内の停留所に影響するアラートです。 |
最大で 1 件のアラートを返します。指定しない場合は、すべてのアラートを返します。
終了したアラートは除外されます。各アラートには、見出し、説明、CATS による詳細文を
含む影響と原因、active または upcoming の状態、期間(終了日未定の場合は
untilFurtherNotice)、およびアラートに記載された路線と停留所が含まれます。
list_stops
| Argument | Type | Notes |
|---|---|---|
latitude, longitude | number | 場所を指定すると、近い順に metersAway を含めて結果を返します。 |
query | string | 停留所 ID、停留所コード、または停留所名の一部です。 |
route | string | この路線が停車する停留所のみを返します。 |
mode | bus | train | 指定した運行サービスがある停留所のみを返します。例:最寄りの鉄道駅には train を指定します。 |
limit | integer | 駅の最大数です(場所を指定した場合のデフォルトは 10、指定しない場合は 250、上限は 250)。 |
各駅には、stopIds、座標、modes、および routes(ID、番号、路線の正式名称、
運行モード)が表示されます。例:501 · Light Rail - Lynx Blue Line、
510 · CityLYNX Gold Line、または 29 などのバス路線。時刻表に運行便がない停留所は
除外され、場所から 50 km を超える停留所は返されません。
list_vehicles
| Argument | Type | Notes |
|---|---|---|
vehicle | string | バスや列車に表示されている車両番号です。例:2301、LRV307。 |
route | string | 路線です:9、501、Blue Line、Mt. Holly Road。 |
mode | bus | train | 任意のフィルターです。 |
limit | integer | 返す車両の最大数です(デフォルトと上限は 250)。 |
すべての引数は任意です。引数を指定しない場合、運行中のすべての車両が返されます。
各車両には、位置、進行方向、速度、乗車率(CATS では現在報告されていません)、
行き先表示、および次の予定停留所が含まれます。リストが途中で切り詰められていても、
matches と countsByMode には合計数が表示されます。
リソース
データそのものを必要とするクライアントやモデル向けの、ツールの基盤となるフィードです。
| URI | 種類 | 内容 |
|---|---|---|
gtfs://static | JSON | 静的 GTFS アーカイブ内のファイル、そのサイズと URI、および取得日時です。 |
gtfs://static/{file} | CSV | CATS が公開しているアーカイブ内の任意のテーブルです。routes.txt、stops.txt、trips.txt、stop_times.txt も個別に一覧表示されます。 |
gtfs://realtime/vehicle-positions | JSON | デコード済みの VehiclePositions フィードです。 |
gtfs://realtime/trip-updates | JSON | デコード済みの TripUpdates フィードです。 |
gtfs://realtime/alerts | JSON | デコード済みの Alerts フィードです。 |
静的テーブルは、ツールが使用するものと同じキャッシュ済みダウンロードから取得されます。リアルタイムリソースには、ツールが追加する時刻表との結合を行わず、GTFS-Realtime のフィールド名、元の ID、Unix タイムスタンプを保持したデコード済みのフィードエンティティが含まれます。各リソースの fetchedAt は、ツールと同様に東部時間です。stop_times.txt はサイズが大きく、ライブフィードでは約 12 MB あります。
インストール
Python 3.11 以降が必要です。
pip install queenscoach
または、インストールせずに実行することもできます。多くの MCP クライアントでは、この方法で起動します。
uvx queenscoach
ソースから開発する場合、または HTTP トランスポートを実行する場合は、クローンから実行します。
python3 -m venv .venv
.venv/bin/pip install . # '.[gcp]' adds the Firestore token store
トランスポート
--transport または QUEENSCOACH_TRANSPORT で選択します。デフォルトは stdio です。
queenscoach # stdio (default)
queenscoach --transport http --port 8000 # streamable HTTP + Google OAuth
stdio
クライアント自身が起動するサーバー向けです。認証は不要です。プロセスはクライアントが所有しているためです。
Claude Code に登録するには、次のようにします。
claude mcp add queenscoach -- uvx queenscoach
または、MCP クライアントの設定ファイルに記述します。
{
"mcpServers": {
"queenscoach": {
"command": "uvx",
"args": ["queenscoach"]
}
}
}
インストール済みのコピーも、絶対パス(/absolute/path/to/.venv/bin/queenscoach)を指定すれば同様に使えます。MCP クライアント間でシェルの PATH が共有されることはほとんどありません。python -m queenscoach を実行すると同じサーバーが起動するため、パッケージがインストールされているインタープリターであれば、どれでもコマンドとして使用できます。
stdout には MCP プロトコルの通信のみが出力され、診断情報はすべて stderr に出力されます。
Google OAuth を使用した HTTP
URL を知っている人なら誰でもアクセスできるホスト型サーバー向けです。/mcp へのすべてのリクエストにはベアラートークンが必要です。トークンを取得する唯一の方法は、許可リストに登録された Google アカウントでサインインすることです。
サインインの仕組み。 MCP クライアントは動的に自身を登録し、MCP サーバー自身のオリジンに認可サーバーがあることを想定しています。Google は動的登録にも、サードパーティのリソースに対象を限定したトークンにも対応していないため、このサーバーは独自の OAuth 2.1 認可サーバーとして動作し、ログインのみを Google に委任します。
MCP client <--OAuth--> queenscoach <--OAuth--> Google
Google からの応答は、サインインしたアカウントを確認するために一度だけ使用します。そのメールアドレスを許可リストと照合し、一致した場合に限り、このサーバーが独自のトークンを発行します。Google のトークンがクライアントに渡されることはありません。
Google Cloud での初回セットアップ。 console.cloud.google.com/auth/clients で、種類が Web アプリケーション の OAuth クライアント を作成し、次のリダイレクト URI を承認済み URI として追加します。
https://your-public-url/auth/google/callback
QUEENSCOACH_PUBLIC_URL と完全に一致する必要があります。サーバーは起動時に、想定する URI をログに出力します。クライアント ID とシークレットを、以下の環境変数に設定してください。
実行方法。 .env.example にすべての設定が記載されています。シェルでの設定方法は次のとおりです。
export QUEENSCOACH_GOOGLE_CLIENT_ID=...apps.googleusercontent.com
export QUEENSCOACH_GOOGLE_CLIENT_SECRET=...
export [email protected]
export QUEENSCOACH_PUBLIC_URL=https://queenscoach.example.com
queenscoach --transport http --port 8000
次に、クライアントを https://queenscoach.example.com/mcp に接続します。クライアントが必要な情報を検出し、Google サインイン用のブラウザーを開きます。Claude Code では次のようにします。
claude mcp add --transport http queenscoach https://queenscoach.example.com/mcp
デフォルトではアクセスが拒否されます。 QUEENSCOACH_ALLOWED_EMAILS、QUEENSCOACH_ALLOWED_DOMAINS、または明示的な QUEENSCOACH_ALLOW_ANY_GOOGLE_ACCOUNT=true によってアクセス可能なユーザーが指定されていない場合、起動に失敗します。そのため、設定ミスのあるデプロイがインターネット上のすべての Google アカウントに開放されるのではなく、アクセス不能になります。Google で未確認のアドレスは常に拒否されます。
エンドポイント。
| パス | 目的 |
|---|---|
/mcp | MCP エンドポイントです。Authorization: Bearer <token> が必要です。 |
/.well-known/oauth-protected-resource/mcp | 認可サーバーの場所をクライアントに知らせます。 |
/.well-known/oauth-authorization-server | このサーバーの OAuth メタデータです。 |
/register | 動的クライアント登録(RFC 7591)です。 |
/authorize、/token、/revoke | OAuth エンドポイントです。 |
/auth/google/callback | Google がユーザーを戻す先です。 |
scripts/install.sh は、/opt 配下のシステムユーザー、API 経由で作成する Cloudflare トンネルと DNS レコード、2 つの systemd ユニット、検証処理まで、デプロイ全体を実行します。ポートフォワーディングは不要なので、CGNAT や制限の厳しいルーターの背後でも動作します。deploy/ を参照してください。
scripts/deploy-gcp.sh は、Google Cloud Run 上で同じ処理を実行します。ご自身の GCP プロジェクト内で、プロジェクト自体、サインイン用の Firestore、Secret Manager 内のクライアントシークレット、Cloud Build でビルドするコンテナ、任意で上限額を設定できる月間予算、同じ検証処理を用意します。ゼロまでスケールするため、個人用サーバーの費用はほとんどかかりません。deploy/GCP.md を参照してください。
デプロイに関する注意事項。
- デフォルトでは、サーバーは通常の HTTP で通信し、トンネルまたはプロキシで TLS を終端することを想定しています。インストールスクリプトはこの構成をセットアップします。代わりに
QUEENSCOACH_TLS_CERTとQUEENSCOACH_TLS_KEYを設定すると、手前に何も置かずにサーバー自身が HTTPS を提供します。 QUEENSCOACH_PUBLIC_URLはクライアントが接続する URL であり、このサーバーの OAuth 発行者識別子でもあります。そのため、バインドアドレスではなく外部向け URL を指定する必要があります。- デフォルトでは、トークンの状態はメモリ上に保存されるため、プロセスごとに管理されます。再起動すると、有効なトークンは無効になります。代わりに
QUEENSCOACH_TOKEN_STORE=firestoreを設定すると、Firestore に保存できます(gcpエクストラをインストールしてください:pip install 'queenscoach[gcp]')。これにより、再起動後もサインイン状態が維持され、すべてのインスタンスで共有されます。どのインスタンスでも任意のリクエストに応答できるよう、QUEENSCOACH_STATELESS_HTTP=trueも併せて設定してください。 - アクセストークンの有効期間は 1 時間、リフレッシュトークンの有効期間は 30 日です。どちらも更新時にローテーションされます。
データソース
リアルタイムデータ(GTFS-Realtime protobuf、20秒ごとに更新):
https://gtfsrealtime.ridetransit.org/GTFSRealTime/Vehicle/VehiclePositions.pbhttps://gtfsrealtime.ridetransit.org/GTFSRealTime/TripUpdate/TripUpdates.pbhttps://gtfsrealtime.ridetransit.org/GTFSRealTime/Alert/Alerts.pb
静的な時刻表(6時間キャッシュ)。フィード識別子を路線名、停留所名、座標に変換するもので、時刻表ツールと経路計画ツールが読み取る時刻表です。
https://gtfsrealtime.ridetransit.org/GTFSStatic/api/GTFSDownload/GTFS.zip
サーバーは、タイムゾーン用の agency.txt、routes.txt、stops.txt、trips.txt、stop_times.txt、および存在する場合は calendar.txt と calendar_dates.txt を読み取ります。stop_times.txt はストリーミングされ、便ごとの配列に格納されます。CATS フィード全体で、メモリ使用量は約 15 MB です。shapes.txt は読み取られません。アーカイブ内のすべてのファイルは、引き続きリソースとして利用できます。
このサーバーが対処するフィードの癖
ライブフィードのキャプチャで確認済みです。
VehiclePosition.stop_idとcurrent_stop_sequenceは使用できません。 サンプルキャプチャ内の車両停留所 ID 158件は、公開時刻表のどの停留所とも一致せず、報告された停留所順序番号は便自体の停留所数を超えていました(例:52停留所の便で順序番号が192)。このサーバーはこれらを一切公開しません。次の停留所のデータは、停留所 ID が100%解決できる TripUpdates フィードから取得します。StopTimeEvent.delayは常に未設定です。 時刻表との差異は、どちらも存在するtimeとscheduled_timeの差から計算されます。- TripUpdates の対象となる稼働中車両は約83%です。 そのため、残りの車両については推測せず、
nextStopを省略します。 - 路線の照合では、完全一致が優先されます。 そのため、
5を検索すると、501や510ではなく路線5が返されます。 - ほとんどの行先表示は方向のみを示します。 64路線中61路線では、便に「Inbound」または「Outbound」とだけ表示されるため、時刻表ツールと経路計画ツールは各便の最後の停留所を
destinationとして報告します。 - 乗車率は報告されません。 すべての車両の
occupancy_statusはNO_DATA_AVAILABLEです。 - 時刻表は数週間先までしか確認できません。 CATS が公開しているのは
calendar_dates.txtのみで、対象期間は約4週間です(確認したフィードでは2026年9月8日から10月4日まで)。時刻表の回答では対象期間をscheduleCoversとして報告し、その範囲外の日付には対応しません。 - 終了日が未設定のアラートは、3000年に終了します。 終了日が5年以上先のアラートは
untilFurtherNoticeとして報告されます。 parent_stationはプラットフォームのグループ化には範囲が広すぎます。 CATS では、最大900 m離れた無関係な停留所にまたがる経路計画上の場所にこの項目を使用しているため、駅は名称と距離に基づいてグループ化されます。
動作に関する注意事項
- 到着予測時刻がすでに過去の場合は除外されます。負の ETA はありません。
- 200 m 以内にある同じ名前の停留所は、1 つの駅として扱われます。たとえば、Gold Line の停留所にある 2 つのホームや、道路を挟んで向かい合うバス停です。
list_stops、get_arrivals、get_schedule、plan_tripは、いずれもこれらを 1 つの場所として扱います。 - フィードの応答サイズには上限があり、時間制限も設けられています。1 つのフィードが遅くても、呼び出し全体が停止することはありません。
- 同時に実行される呼び出しは、フィードごとに進行中の取得を 1 回だけ共有します。1 つの呼び出しが諦めても、ほかの呼び出しが待っている取得は中断されません。
- 更新に失敗してもキャッシュデータがある場合は、エラーではなく最後に正常に取得したデータが返されます。すべての応答に含まれる
feedAgeSecondsで、データの経過時間を確認できます。 - アラートフィードは
get_arrivalsとget_routeの補足情報です。取得に失敗した場合は、アラートなしで応答します。ライブ予測を利用できない場合、plan_tripも時刻表にフォールバックし、その旨を伝えます。 - 引数の日付と時刻は、シャーロットの現地時間です。GTFS と同様に、運行日は深夜を越えて続きます。また、運行日の時刻は、その運行日の正午から 12 時間を引いた時刻を起点とするため、夏時間の切り替え時も正しい時刻が保たれます。
- 時刻表の解析、経路検索、時刻表のスキャンはワーカースレッドで実行されるため、処理が遅くてもほかのリクエストを妨げません。時刻表のダウンロード後、最初の呼び出しでは解析のために 1 秒ほど待ちます。その後の経路検索は 1 秒もかからずに完了します。
- ツールの応答に含まれる時刻はすべて東部時間(
America/New_York)で、ISO 8601 形式です。日付に適用されるオフセットも含まれます。夏時間中は2026-09-08T17:59:48-04:00、それ以外は2026-12-21T19:00:00-05:00となります。時計が戻る夜にある 2 つの午前 1 時 30 分は、オフセットで区別されます。座標は WGS84 の十進度数です。
設定
フィード(両方のトランスポート)
すべて任意です。デフォルトでは、上記の CATS フィードが使用されます。期間の単位はミリ秒です。
| 変数 | デフォルト |
|---|---|
QUEENSCOACH_VEHICLE_POSITIONS_URL | CATS 車両位置フィード |
QUEENSCOACH_TRIP_UPDATES_URL | CATS 便の更新フィード |
QUEENSCOACH_ALERTS_URL | CATS アラートフィード |
QUEENSCOACH_STATIC_GTFS_URL | CATS 静的 GTFS zip |
QUEENSCOACH_REALTIME_TTL_MS | 20000 |
QUEENSCOACH_STATIC_TTL_MS | 21600000 |
QUEENSCOACH_REQUEST_TIMEOUT_MS | 30000 |
QUEENSCOACH_MAX_FEED_BYTES | 33554432 |
QUEENSCOACH_MAX_STATIC_BYTES | 268435456 |
フィード URL は http または https である必要があります。それ以外は起動時に拒否されます。
トランスポート
| 変数 | CLI | デフォルト |
|---|---|---|
QUEENSCOACH_TRANSPORT | --transport | stdio |
HTTP トランスポート
--transport http が選択されている場合にのみ読み込まれます。
| 変数 | CLI | デフォルト | 備考 |
|---|---|---|---|
QUEENSCOACH_HTTP_HOST | --host | 127.0.0.1 | バインドアドレスです。 |
QUEENSCOACH_HTTP_PORT | --port | 8000 | バインドポートです。 |
QUEENSCOACH_PUBLIC_URL | --public-url | http://localhost:<port> | 外部オリジンです。OAuth 発行者として使用されます。 |
QUEENSCOACH_GOOGLE_CLIENT_ID | 必須 | Google Cloud の認証情報から取得します。 | |
QUEENSCOACH_GOOGLE_CLIENT_SECRET | 必須 | Google Cloud の認証情報から取得します。 | |
QUEENSCOACH_ALLOWED_EMAILS | — | 許可するアドレスを、カンマまたはスペースで区切って指定します。 | |
QUEENSCOACH_ALLOWED_DOMAINS | — | 許可するドメインを、example.com のように指定します。 | |
QUEENSCOACH_ALLOW_ANY_GOOGLE_ACCOUNT | false | すべての Google アカウントを許可する場合に有効にします。 | |
QUEENSCOACH_TLS_CERT | --tls-cert | — | HTTPS を直接提供するための PEM 証明書チェーンです。 |
QUEENSCOACH_TLS_KEY | --tls-key | — | PEM 秘密鍵です。上記の証明書と併せて指定する必要があります。 |
QUEENSCOACH_ACCESS_TOKEN_TTL_MS | 3600000 | アクセストークンの有効期間です。 | |
QUEENSCOACH_REFRESH_TOKEN_TTL_MS | 2592000000 | リフレッシュトークンの有効期間です。 | |
QUEENSCOACH_TOKEN_STORE | memory | memory または firestore(gcp エクストラが必要)です。 | |
QUEENSCOACH_FIRESTORE_DATABASE | (default) | トークンストアに使用する Firestore データベースです。 | |
QUEENSCOACH_STATELESS_HTTP | false | MCP セッションを使用せずに提供します。再起動や複数インスタンスでの運用に適しています。 |
上記の許可リスト設定のうち、いずれか 1 つが必須です。
構成
| モジュール | 役割 |
|---|---|
config.py | 環境変数の解析と検証 |
feed_http.py | 件数を制限し、時間制限を設けた HTTP フェッチ |
cache.py | TTL キャッシュと単一フライト更新 |
gtfs_csv.py | GTFS 形式の CSV 読み込み |
static_gtfs.py | 静的な運行スケジュール:路線、停留所、便、時刻表、運行日カレンダー |
realtime.py | GTFS-Realtime protobuf のデコード |
transit.py | ドメイン層:リアルタイム情報と運行スケジュールを結合し、クエリを解決 |
timetable.py | 公開時刻表のドメイン層:運行日、出発、路線パターン |
planner.py | 旅行計画:時刻表に対する Connection Scan と、リアルタイムの遅延情報 |
tools.py | ツールの動作と JSON ペイロード |
resources.py | MCP リソースとしての GTFS フィード |
server.py | MCP ツールとリソースの登録、およびスキーマ |
oauth.py | Google をログインに使用する OAuth 認可サーバー |
token_store.py | OAuth 状態の保存先と、デフォルトのインメモリストア |
token_store_firestore.py | Firestore トークンストア(gcp エクストラのみ) |
http.py | Streamable HTTP トランスポートと Google コールバックルート |
main.py | CLI エントリーポイントとトランスポートの選択 |
また、HTTP トランスポートを Debian ホストにデプロイする
scripts/install.sh と、Dockerfile とともに Google Cloud Run にデプロイする
scripts/deploy-gcp.sh があります。
開発
.venv/bin/pip install -e '.[dev]'
.venv/bin/pytest # offline, against recorded feed fixtures
.venv/bin/mypy # strict
.venv/bin/ruff check .
.venv/bin/ruff format .
テストでは、ライブフィードから取得した protobuf と GTFS のフィクスチャを使用するため、決定的に実行され、ネットワークへの呼び出しは発生しません。GTFS フィクスチャは実際のアーカイブから抜粋したもので、路線 29、Blue Line、Gold Line の便、それらが停車する停留所、および完全な運行カレンダーが含まれています。リアルタイムデータのキャプチャは平日の夕方のものなので、これを使って Blue Line から Gold Line への乗り換えを計画できます。例外は tests/test_feed_http.py で、ループバックソケットから既定のレスポンスを返し、バイト数の上限とタイムアウトを実際に検証します。
tests/test_http.py では、Google のトークンエンドポイントをスタブに置き換えたうえで、実際の ASGI アプリに対して OAuth ハンドシェイク全体(登録、/authorize、Google コールバック、/token、認証済みの tools/list)を実行するため、アカウントもネットワークも必要ありません。
tests/test_token_store.py では、すべてのトークンストアテストを両方のストアに対して実行します。Firestore のテストにはエミュレーター(gcloud emulators firestore start を実行し、FIRESTORE_EMULATOR_HOST を設定)が必要で、エミュレーターがない場合はスキップされます。tests/test_stdio.py では、実際の stdio サーバーを子プロセスで起動します。CI でも通常の pip install . でインストールした環境に対してテストを実行し、stdio にオプションの追加依存関係が不要であることを確認します。
ライセンス
MIT ― LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。