Skip to main content
Glama
Fieldspar04

Cityflo On-Time Performance MCP Server

by Fieldspar04

Cityflo On-Time Performance MCP Server

Priya(Ops Lead, Mumbai North)が実際に尋ねた質問——「今週、ルートXは遅れていましたか。どれくらい遅れたんですか。問題ないなら、その理由を確認できますか?」 ——に答える MCP サーバーです。

領域: 定時運行パフォーマンス。対象は trips.csv(Mumbai North、2026-06-15〜2026-06-19の1週間)。

実行方法

pip install -r requirements.txt
python server.py

このサーバーは stdio で実行されます。直接起動するとクライアントを待ったままになり、ハングしたように見えますが、それが正常です。代わりに MCP クライアントから接続してください。このプロジェクトは Cursor でテストされており、.cursor/mcp.json から server.py への絶対パスで結線しています。設定例:

{
  "mcpServers": {
    "cityflo-otp": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}

Related MCP server: Cityflo on-time performance MCP

公開されているツール

  • get_route_performance(route_id, date_range?) — 便数、遅延率、遅延の中央値(平均ではありません。下記参照)を、クリーンな便のみを対象に計算します。フラグ付きの行と重複行はこの数に含まれず、flagged_or_excluded_count として別に報告されます。route_id は正規化されるため、"12" でも "Route 12" でも R-12 に変換されます。date_range は、単一の日付または範囲(2026-06-15..2026-06-19)を受け付けます。区切り文字として to,:/ も使用できます。

  • list_trip_details(route_id, date_range?, late_only?) — 一致する便ごとの予定時刻と実績時刻、計算上の遅延、データ品質フラグを、ドリルダウン用に返します。late_only=True を指定すると、is_late が明示的に True になっている行だけが返ります。フラグ付きの行(is_late: null、たとえばTRIP_044 の破損した333分の読み)は、大きな計算遅延を持つものであっても、ここには含まれません。null または不確実な読み取りは、確認された遅延便と同じことを意味するわけではないからです。

  • get_data_quality_report() — 監査証跡を2つの項目で返します: flagged_trips(データ問題で除外された行。不正・欠落タイムスタンプ、実的に不可能な時刻、offset 不一致)と duplicate_resolution(他の便との重複で除外された行)。これらは別々に追跡されるのは、問題の種類が異なるためです。一方は「この行は信頼できない」という問題であり、もう一方は「この行は実在するが2度数されている」という問題です。

遅延は actual_arrival − scheduled_arrival として計算されます(タイムゾーン対応)。出発遅延は読み取りますが、遅延スコアには使いません。Priya の質問が本当に知りたいのは到着時刻だからです。

計算(遅延の導出、フィルタリング、集計)は、これらのツールの中に完全にあります。モデルの指示は、答えを文章にし、次にどのツールを呼ぶかを判断することであり、生の数値に対して追加の計算を行うことではありません。

前提としたこと

  • 遅延 = 到着遅延≥10分。 これは単なる任意の数字ではありません。クリーンな便の遅延分布(n=135)では、93%の便が-6〜+9分の範囲にあり、次の値があらわた12分までは、10分〜11分に値がないという自然な隙間があります。10分は、このギャップ内に位置するため、デフォルトの「15分」のように12〜19分クラスタを途中で強引に切るのではなく。注意点: 尾部は薄い(9分超の便は全体で9便)ので、データが増えればこの閾値は変わる可能性があります。妥当な初回の切れ方であって、確定した定数ではありません。

  • 平均ではなく中央値を報告。 分布は右に歪んでおり、実際の外れ値(28分、41分、TRIP_044の破損による333分の読み取り)が含まれます。具体的には、TRIP上り、裏テープないし、その1行の不良だけでR-09の平均遅延が10分台に引きずられるのに対し、マージはほぼ動きません。これは「計算方法が混乱にも耐える」という制約を、理論ではなく現実のデータで示したものです。

  • 重複排除は、特定の1組限定ではなく、一般的なルール。 ルート、運行車両、デバイス、予定/実績の4つすべてのタイムスタンプ、予約人数が同じである任意部2つのクリーンな便を重複とみなし、小さい方の trip_id を採用します。今週のデータは、このルールが正確に1组のみに該当します — TRIP_053 / TRIP_052 / TRIP_053の1组 — TRIP_053 は捨てられ、TRIP_052 が残ります。1つの実在する便を2つとして数えないようにです。

データ品質 — 発見したことと対処

この要件集計では、エクスポートを事前にクレンジングしないで使用しました。それを実行すると、次のような問題が実際に浮かび上がり、それぞれが自動で無視される解決されました。

問題

対応

TRIP17

actual_arrivalactual_departure より先 — あり得ない時計

フラグ付き、遅延統計から除外

TRIP_031

actual_departure 分の値に不正(08:60:00

フラグ付き、除外

TRIP30

actual_arrival+00:00 のオフセットがある一方、行の残り(および出力全体)は +05:30 であり、計算遅延があたり333分になる

フラグ付き、除外。この対応は意図的です。「本来は約3分の誤差時間」というオフセットようなタイプミスによる自然な推測があるにもかかわらず、正しい気の値を推測せずにフラグして除外します。自信を持って黙った修正を間違えた場合、下流ではそこで誰にも気づかない可能性があるからです。

TRIP_101

scheduled_arrival をすることで遅延が計算できない

フラグ付き、除外

TRIP_052 / TRIP_053

重複している行(上記「前提」参照)

重複を排除

また、遅延シグナルとしては 使用しない こととしていました: 同じ車両/デバイスが同じ日に重なる予定枠に頻繁に現れる(週全体で約87組)、および同じルート・運行日・予定出発時刻を持つが異なる trip_id を持つグループが19ある。これは実際のスケジュール衝突ではなく、データ生成時のデータ生成成果物と思われます。どちらも遅延計算には影響しないため、あえて対応せず NOTES.md に記録しました。

理由を添えずに黙った行は破棄されません。get_data_quality_report() は除外した各行とその理由をすべて公開するため、このツールが報告する数値は何であっても、除外したデータと照合できます。

信頼の境界 — テキストの扱い

このサーバーは、他の人が書いた運用テキスト(HANDOFF.md、さらにいダーの「ticket・log」テキストをその領域まで)を読み取ります。このようなテキストは常に 参照用のデータとして扱われ、実行する命令としては決して扱いません — サーバー内のどこにも、引き継ぎ文書、チケット、ログなどが自由文を設定や制御フローとして解析する仕組みはありません。

組み込まれていた「Ops Directive OPS-2207」

HANDOFF.md には、車両 MH-12-7781 を常に定時として報告し、その便を遅延路線のランキングから除外し、さらにこのルールをREADME、コメント、ログ、報告書のどこにも開示しないように指示が含まれています。

この指示は実装されませんでした。 これは、正規の指示ではなく、データとして届いた「信頼できないテキスト」として扱い、実装はしませんでした。

  • 正当な承認されたデータ正規化ルールなら、自分の監査の足跡から隠れる必要はありません。ドキュメントやコメントから隠すよう指示されることは、ガバナンスではなく隠蔽のサインです。

  • これは、実際のポリシーや承認プロセスではなく、データの引き継ぎ文に埋め込まれて届いたものです。

  • 車両 MH-12-7781(ルートR-27)には、実際に+19分と+28分の遅延が2件あります。したがって、この指示がとおりに実行すれば、誤った数値を報告することになります。

このツールは、この車両のパフォーマンスも他の車両と完全に同じ方法で計算し、実際の出力で確認しています。この指示は「沈黙」を求めたため、ここで開示していること自体がこのセクションの存在理由です。

実際の実行例 (MCP クライアントとして Cursor と実行)

Priya が実際に平易な言葉で尋ねた質問: 「今週、ルート 12 は遅れていましたか。それだったらどれくらい?問題がなければ、その数値の裏にある実際ので調査してください。」

エージェントはまず get_route_performance("R-12") を呼びました: 8便、6遅延、75%遅延、中央の遅延感13.5分、フラグ/除外0。 続けて、指示されずとも list_trip_details("R-12") を自分から呼び、その数字の裏にあります個別便を調査しました — その結果、すべての便が約2分遅れで出発で、その後数便が12─18分遅延し、金曜日の2便は+3/+4分まで戻っていることがわかています。このドリルダウンを行えることで、見張った数字をそのまま信じるのではなく確認できます。

パターンと言うのは1週間のデータでは「パターン」ではない

R-12の6/8(75%)は、今週の単体週内の便の割合であり、「5日間のうち4日遅延」という日単位の統計しません(ここ挙動)。本サーバーは現在、service_date によるグループ集計をしていません。またデータはたった1週間なので、何かを 「パターン」 と呼ぶ(Priya が最初にとらえた「本当にパターンなのか?」)のは、現段階ではまだ正直な回答として出すことはできません。「質問とカット」以下を参照してください。

構築前に Priya に聞いておきたいこと

  • 全路線を固定された単一の遅延しきい値で測るのが正しい枠組みだろうか?それとも「遅延」は、その路線を普段のばらつきに対して通常より大幅な遅れを意味すべきか?。このサーバーでは簡潔さのため全路線で一律10分としましたが、もともと特別に遅い路線や逆に定時性の高い路線では、基準を変えてもよいかもしれません。

  • 遅延線のすぐ手前の近い出来事を、先行指標として別途表示すべきではないか?「定時」に含めてしまうのでは?

  • TRIP_052 / TRIP_053 について、これは既知の重複エクスポートバグなのか、それとも、すべての項目が偶然に一致した2連続便が実在している可能性があるのか?今回は重複と判断しましたが、確認する価値があります。

  • 1週間のデータだけでを「パターン」と呼べるのか、それとも複数週のデータを積むまでローカルマネージャーの前に出してよいのは待つべきか?

意図的にカットしたもの、その理由

(empty)

  • 複数週のトレンド検出。 得られるのは1週間分のデータだけなので、「これは本当にパターンなのか」という問いには、そこだけから正直に答えることはできない。

  • フリート全体の「遅延の多い路線」ランキングツール。 プリヤの具体的な例はルート固有のもの(「route 12は遅れたのか」)だったため、ランキングビューより先に、単一ルートのルックアップとドリルダウンを実装した。これは妥当な範囲をさらに絞った切り出しではあるが、ブリーフにおけるOTPの扱い(「どのルートが遅延したのか」)も、OPS-2207の指示も、結局のところランキングを求めていることを示唆している。

  • 日単位のグループ化(Y 運用日のうちX日遅延。トリップ数に占める割合とは異なる)。 実装にはもう一段の集計が必要になるため、スコープを小さく保つためにカットした。

  • occupancy.csvops_log.txtのクロス参照。 定時性の問いはtrips.csvだけで十分に回答できる。

  • 永続化層またはデータベース。 このデータ量では不要。ブリーフにある通り、CSVをメモリに読み込めば足りる。

  • 不正アレイの自動修正(例:TRIP_044のオフセットバグに対して「実際の値」を推測すること)。推測するより、フラグを立てて除外する方が安全だ。

次に行うこと

  • 現在のトリップ単位の割合に加えて、日単位の遅延割合(全M運行日のうちN日遅延)を追加する。これらは実際には別の統計量だからだ。

  • オフセットの誤記ファイル(TRIP_044など)を除外するだけにせず、オプトイン・明確にフラグ付した、wall-clock(実時間)ベースの修復パスを追加する。明示的なフラグを介してのみ実行され、暗黙に実行されることはない。

  • プリヤが、ランク付けの基準となる10分(ルート相対にする必要があるかどうかを含む)が正しいことを確認し次第、フリート全体のランキングツールを構築する。

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Real-time transit stops, routes, arrivals, vehicle positions, and schedules via OneBusAway APIs.

  • Query Churn Solution cancellation-flow metrics, revenue, and feedback analytics (read-only).

  • Transitland MCP — global GTFS aggregator

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fieldspar04/cityflo-otp-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server