mcpField
T
tfl-ts

tfl-ts

ローカル
github.com/ghcpuman902地図・旅行22 日前に更新

tfl-ts について

tfl-tsはTransport for Londonのデータを読み取り専用で扱う、型定義付きのTypeScriptクライアントです。RESTラッパーとオフラインの駅構内データを備え、エージェント向けのローカルMCPサーバーも含みます。

主な機能

  1. 01型定義付きTfL APIクライアント
  2. 0284個のRESTエンドポイントのラッパー
  3. 03オフラインの駅構内データ
  4. 04路線状況と到着情報の照会
  5. 05経路計画

活用シーン

  1. 01現在の地下鉄運行状況の確認
  2. 02停留所の到着情報の照会
  3. 03TfLを利用した経路の計画

MCP 対応

`npx tfl-ts mcp`で読み取り専用のローカルMCPサーバーを起動できます。路線状況、到着情報、経路計画、ID解決、同梱ドキュメント用のツールを提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"ghcpuman902-tfl-ts": {
"command": "npx",
"args": [
"-y",
"tfl-ts"
],
"env": {
"TFL_APP_KEY": "<TFL_APP_KEY>",
"TFL_MCP_MIN_INTERVAL_MS": "<TFL_MCP_MIN_INTERVAL_MS>"
}
}
}
}
起動コマンドnpx -y tfl-ts
設定が必要な環境変数
TFL_APP_KEYシークレットTfL API primary key. Live tools need it. Static tools (docs, resolve_line_id, get_supported_modes) do not.
TFL_MCP_MIN_INTERVAL_MSMinimum milliseconds between outbound TfL requests. Default 250. Cache hits do not count.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmtfl-ts2.15.2

ツール

7

掲載時のツール一覧 · 2 週間前に更新

このツールにパラメーターはありません。

詳細

TfL API TypeScript クライアント

npm version License: MIT TypeScript Node.js CI

型付きの TfL クライアントです。使いやすいラッパー、84 個の生 REST エンドポイント、20 路線のオフライン駅構成データを提供します。

tfl CLI で central と victoria を確認し、journey エンドポイントの一覧を表示 tfl.manglekuo.com のボード。路線状況とリアルタイムの到着情報を表示

tfl-ts で構築 → Board

比較

tfl-tstfl-unified-apitfl-journey-plannertfl-mcpmcp-tfl
TypeScript 型定義ありなしなしソースのみあり(src/index.ts)
依存関係ゼロありなしなしなしなし
生エンドポイントの対応数8484 件中 10 件84 件中 1 件84 件中 59 件84 件中 8 件
オフライン駅データありなしなしなしなし
MCP 対応ありなしなしありあり

件数は、コミット済みの OpenAPI スナップショットにある 84 個の操作を基準にしています(src/generated/endpoints.ts の ENDPOINT_COUNT、src/generated/openapi/spec.meta.json の pathCount)。各リポジトリのソースと、2026 年 10 月 16 日に npm で公開された package.json を照合しました。

tfl-ts は .d.ts ファイルを公開しています。実行時の依存関係はありません。型定義を使ってコンパイルする場合は、typescript がピア依存関係となります。駅の順序とハブの情報は tfl-ts/meta に含まれており、ネットワーク呼び出しは不要です。tfl mcp はローカル MCP サーバーです。

tfl-unified-api 2.0.2 は JavaScript 製で、types フィールドはありません。moment、request、request-promise-native に依存しています。Line モジュールは 84 個のパスのうち 10 個を呼び出します。対象は、メタモード、重要度、運行障害のカテゴリ、サービスタイプ、ルートシーケンス、ID によるルート、モードによる路線、ID による状況、期間指定の状況、モードによる状況です。getRoutesByServiceType は /Line/Route/{types} を構築しますが、これは 84 個のパスには含まれません。db/lineColors.json は路線の色であり、駅データではありません。

tfl-journey-planner 1.1.2 は JavaScript にコンパイルされた LiveScript 製で、types フィールドはありません。request と querystring に依存しています。このモジュールが呼び出すのは GET /Journey/JourneyResults/{from}/to/{to} のみです。

@daanrongen/tfl-mcp 1.4.3 は TypeScript で記述されています。公開された tarball には dist/main.js、package.json、README.md が含まれ、package.json に types フィールドはありません。@modelcontextprotocol/sdk、effect、zod に依存しています。ツールは 84 個のパスのうち 59 個を呼び出します。また、/Road/all/Disruption(スナップショット上のパスは /Road/all/Disruption/{disruptionIds})、/Vehicle/EmissionSurcharge、/Vehicle/UlezCompliance も呼び出します。

@pipeworx/mcp-tfl 0.1.2 は "types": "src/index.ts" を設定しており、そのファイルは tarball に含まれています。@modelcontextprotocol/sdk と tsx に依存しています。6 つのツールが 84 個のパスのうち 8 個を呼び出します。

駅の順序は tfl-ts に含まれており、tfl-ts/meta にあります。

インストールと最初の呼び出し

TfL API PortalからPrimary keyを取得します。「500 Requests per min」に登録してから、Profile → Showを選択します。

pnpm add tfl-ts
export TFL_APP_KEY=your-primary-key
pnpm exec tfl raw line.statusByIds --ids victoria
[
  {
    "id": "victoria",
    "name": "Victoria",
    "lineStatuses": [{ "statusSeverityDescription": "Good Service" }]
  }
]

路線名、駅の順序、色はパッケージに含まれています。運行状況、到着情報、経路は実行時にTfLへアクセスします。

ポータルには2つのキー(PrimaryとSecondary)が表示されます。どちらも使用できます。app_idは2021年1月以降、使用されていません。

代わりにコンストラクターに認証情報を渡す
const client = new TflClient({
  appKey: 'your-primary-key',
});

クイックスタート

Node
import TflClient from 'tfl-ts';

const client = new TflClient(); // reads TFL_APP_KEY from process.env

const status = await client.line.getStatus({ modes: ['tube'] });

const arrivals = await client.stopPoint.getArrivals({
  stopPointIds: ['940GZZLUOXC'], // Oxford Circus
});

const journey = await client.journey.plan({
  from: '940GZZLUOXC',
  to: '940GZZLUBND',
});

const { matches } = await client.stopPoint.search({
  query: 'Oxford Circus',
  modes: ['tube'],
});

const busStops = await client.stopPoint.searchBusStops('Trafalgar Sq');
Next.js

ISR(約60秒)を使用するサーバーコンポーネントです。ボードとエクスプローラーについては、tfl-components · tfl.manglekuo.com/docs/explorerを参照してください。地下鉄のボードでは公式の路線カラーを使用し、バスのボードでは路線番号チップを使用します。パターンを混在させないでください。examples/README.mdを参照してください。

import TflClient, { sortLinesBySeverityAndOrder } from 'tfl-ts';

export const revalidate = 60;

const client = new TflClient();
const tube = await client.line.getStatus({ modes: ['tube'] });
const sorted = sortLinesBySeverityAndOrder(tube);
pnpm dlx shadcn@latest add https://tfl.manglekuo.com/r/tube-status-board.json
pnpm dlx shadcn@latest add https://tfl.manglekuo.com/r/tfl-roundel.json

NEXT_PUBLIC_ALLOW_TFL_ROUNDEL=trueを指定しない限り、ラウンデルにはプレースホルダーが表示されます(商標に関する責任はご自身で負うことになります)。

エージェント / MCP

読み取り専用のMCP(npx tfl-ts mcp)で、キャッシュとレート制限が適用されます。静的ツールはTfLにアクセスしません。npmの実行ファイルはtfl(dist/cjs/bin/tfl.js)で、mcpはstdioサブコマンドです。セットアップについてはdocs/mcp.mdを参照してください。

{
  "mcpServers": {
    "tfl-ts": {
      "command": "npx",
      "args": ["-y", "tfl-ts@latest", "mcp"],
      "env": {
        "TFL_APP_KEY": "your-primary-key"
      }
    }
  }
}

ツール:get_supported_modes、resolve_line_id、docs、resolve_stop_id、get_line_status、get_arrivals、plan_journey。

リポジトリにアクセスできない場合や、コンテキストを失った場合は、npx tfl-ts docs lsで同梱されているエージェント向けドキュメント(このREADME、CLAUDE.md、docs/agent.md、docs/mcp.mdなど)をすべて一覧表示できます。docs cat <id>でドキュメントを1つ表示し、docs find <query> / docs grep <pattern>で全ドキュメントを検索できます。オフラインで動作し、APIキーは不要です。ローカルのMCP docsツールも同じカタログを読み取ります。

注意点

  • 路線IDは小文字のスラッグです。例:'central'、'victoria'、'elizabeth'。'Central'のような表示名ではありません。
  • 停留所IDは'940GZZLUOXC'のような形式です。stopPoint.search()またはplace.search()で解決してください。
  • バス停留所は、検索時に5桁のNaPTAN形式コードを使用できます(例:'51800')。
  • ライブ呼び出しの前に、静的定数(LINE_NAMES、STATION_SEQUENCES、モード一覧)を優先してください。
  • 運行状況は約30~60秒キャッシュしてください。停留所ごとの到着情報を約10~15秒より短い間隔でポーリングしないでください。
  • accidentStatsとairQualityは非推奨です。
  • National Railの到着情報はTfL経由ではリアルタイムではありません。STATION_HUBSは、トポロジー情報としてSoutheastern、South Western Railwayなどの事業者を追跡しますが、これらの事業者に対するgetArrivals()はエラーではなく空の配列を返します。
  • 地下鉄のボードでは公式の路線カラーを使用し、バスのボードでは路線番号チップを使用します。パターンを混在させないでください。
  • ラウンデルの商標:利用側がオプトインしない限り、プレースホルダーが表示されます。
  • 1つの路線に複数のlineStatusesが含まれる場合があります。[0]を読み取らないでください。対象となる行にはgetWorstCurrentStatus(line.lineStatuses)を使用してください。
  • validityPeriods[].isNowはdisruption.category === 'RealTime'に従います。時刻のチェックではありません。計画済みの工事が今日実施されていても、isNow: falseになることがあります。
  • validityPeriods[].toDateは期間の終了時刻であり、列車の運行再開時刻ではありません。週末の工事は00:29Z(ロンドン時間01:29、運行日の終了時刻)に終了することがよくあります。同じ行にある深夜をまたぐ区間は1つの運休作業です。最初に重複するtoDateを次の列車の時刻として扱わないでください。
  • Severity 20は予定された運休(Waterloo & City線の週末、運行日の終了時刻)を示すもので、予定外のClosed (1)ではありません。sortLinesBySeverityAndOrderでは、インシデントより後に並びます。
  • Circle / H&C / Metでは、共有線路に沿ってlineIdが切り替わります。withSharedTrackIdentityを使用してください。元のlineIdを書き換えないでください。

変更前と変更後

getDetailedStatus()は、TfLの生成された型ではなく、短縮された型と名称を変更したフィールド(severity、from、closureType、originName)を返します。

const lines = await client.line.getDetailedStatus({
  lineIds: ['bakerloo'],
  dateRange: { startDate: '2026-08-08', endDate: '2026-08-10' },
});
const s = lines[0]?.statuses?.[0];
s?.severity;
s?.severityDescription;
s?.validityPeriods?.[0]?.from;
s?.disruption?.closureType;

TfLの正確なフィールド名が必要な場合は、getStatus({ detail: true })またはclient.raw.line.*を使用してください。

駅の路線順

地下鉄、Elizabeth line、DLR、Overground、Tram、リバーバスの桟橋のトポロジーです。認証情報もネットワークも必要ありません。路線の識別、順序、分岐のみを扱います(運行状況や到着情報は含みません)。リバー桟橋は STATION_HUBS に含まれないため、NaptanFerryPort の ID をポーリングしてください。ライブのトポロジーは client.line.getRouteSequence() で取得できます。クライアントには client.line.STATION_SEQUENCES もあります。

import { LINE_STATION_SEQUENCES } from 'tfl-ts/meta';

const bakerloo = LINE_STATION_SEQUENCES.bakerloo;
const outbound = bakerloo.orderedRoutes.find(
  (route) => route.direction === 'outbound' && route.serviceType === 'Regular',
);
console.log(outbound?.stationIds, bakerloo.branches);

駅ハブと正規化された到着情報

STATION_HUBS は、各物理駅を同駅の StopPoint ID 群と、各路線の到着情報を提供する特定の ID に対応付けます。たとえば、Liverpool Street の地下鉄 ID(940GZZLULVT)と鉄道 ID(910GLIVST)は、どちらも 1 つの HUBLST エントリーに解決されます。Central は地下鉄 ID、Elizabeth line は鉄道 ID を使用します。認証情報もネットワークも必要ありません。

import { STATION_HUBS, resolveArrivalsStopId } from 'tfl-ts/meta';

const hub = STATION_HUBS['940GZZLULVT']; // any sibling id works
const elizabethStopId = hub && resolveArrivalsStopId(hub, 'elizabeth'); // '910GLIVST'

resolveArrivalsStopId は、そのハブに該当路線がない場合、乗換駅の ID ではなく undefined を返します。乗換駅の ID 自体をポーリングしても、TfL からの到着情報は 0 件です。第三者の National Rail 運行事業者(Southeastern、South Western Railway、c2c など)はハブのトポロジーには表示されますが、ライブ予測情報は返しません。TfL の Arrivals API が対応するのは、地下鉄、DLR、tram、Overground、Elizabeth line のみです。

client.stopPoint.getNormalizedArrivals() は getArrivals() に、整形された destination(towards が空、またはリテラルの "null" の場合に destinationName を使用します。これは Elizabeth line、Overground、一部のバスターミナルでよく見られます)と platform(方角、整形されたラベル、TfL のリテラル "Platform Unknown" に対する isUnknown)を加えたものです。

const arrivals = await client.stopPoint.getNormalizedArrivals({
  stopPointIds: ['940GZZLUOXC'],
});
arrivals[0]?.destination.name;
arrivals[0]?.platform.label;

getArrivals() と client.raw.* は変更されていません。

client.stopPoint.get と getByGeoPoint は、Direction の追加プロパティ towards、compassPoint、compassBearingDegrees を停留所に引き上げます。smsCode は、第一級フィールドまたはバッグの SmsCode から設定されます。施設キーは TfL の文字列のまま additionalProperties に保持されます。parseAdditionalPropertyValue は、バッグの value を null/boolean/number/date/text に変換します("yes"、"null"、Unix ミリ秒の InstallDate など)。client.raw.stopPoint.* では引き上げ処理を行いません。Prediction の bearing(車両の進行方向)を停留所のフラグとして使用しないでください。塗装された stopLetter が W なら、それは Stop W であり、西を意味するものではありません。

const [stop] = await client.stopPoint.get({ stopPointIds: ['490013766E'] });
stop.towards; // 'Aldwych'
stop.compassPoint; // 'E'
stop.compassBearingDegrees; // 90

Circle/Hammersmith & City/Metropolitan の共用線路では、TfL は列車ごとではなく駅ごとに lineId を割り当てます。同じ vehicleId が Victoria では circle、Liverpool Street では hammersmith-city になる場合があります。withSharedTrackIdentity(stopRows, lineIds, networkArrivals) は sharedTrackIdentity を追加します(専用区間での一致に基づく canonicalLineId、または ambiguous と rawLineIds)。生の lineId は書き換えません。証拠として必要なのは、stopPointId を指定せずに実行するネットワーク全体のポーリング、line.getArrivals({ lineIds }) です。

色、重要度、詳細な型

import type {
  DetailedLine,
  DetailedLineStatus,
  DetailedDisruption,
  AffectedRoute,
  AffectedStop,
} from 'tfl-ts';
import {
  getLineColor,
  getLineInlineStyles,
  getLineCssProps,
  getLineDarkReadableStyles,
  sortLinesBySeverityAndOrder,
  getLineStatusSummary,
  getWorstCurrentStatus,
  getStatusKind,
} from 'tfl-ts/ui';

const { hex } = getLineColor('central'); // #E32017
const styles = getLineInlineStyles('central');
const cssProps = getLineCssProps('northern');

const tube = await client.line.getStatus({ modes: ['tube'] });
const sorted = sortLinesBySeverityAndOrder(tube);
const worst = getWorstCurrentStatus(sorted[0]?.lineStatuses);
getStatusKind(worst ?? 10);

Northern はデフォルトで、コントラストを高めた暗色の outline になります。白い塗りと文字を使用するには { darkContrastMode: 'white' } を渡してください。CHANGELOG.md(2.4.0)を参照してください。生データに直接アクセスするには、client.raw.line.statusByIds({ ids: ['central'] }) を使用します。

リアルタイム

REST と同じ app_key で到着情報をポーリングしてください。SignalR は使用しません。詳細は docs/REALTIME.md を参照してください。

const stop = client.realtime.pollArrivals(
  {
    stopPointIds: ['940GZZLUOXC'],
    sortBy: 'timeToStation',
    intervalMs: 30_000,
  },
  (arrivals, meta) => console.log(`[tick ${meta.tick}]`, arrivals.length),
  (error, meta) => console.error(meta.tick, error),
);
stop();

モジュール一覧

モジュール主な用途
client.line運行状況、詳細な運行状況、運行障害、路線、路線別の到着情報、静的な LINE_NAMES/STATION_SEQUENCES
client.stopPoint検索、到着情報、正規化された到着情報、停留所のメタデータ、静的な STATION_HUBS
client.journey経路検索
client.mode交通手段の一覧と交通手段別の到着情報
client.search/place/road/vehicle/occupancy/bikePoint/cabwise/travelTimes各種 API
client.raw84 個すべての REST エンドポイント(pnpm exec tfl list は JSON を出力します。--text は従来の行形式です)
client.realtimeREST の到着情報を使った即時取得ポーリング

実行時の依存関係はありません(Node、ブラウザー、fetch 対応のエッジ環境で動作します)。

詳細なドキュメント

リソース目的
CLAUDE.md / AGENTS.mdエージェント向けクイックスタート:静的データとライブデータ
docs/agent.mdモジュールリファレンス、キャッシュ、Next.js のパターン
.claude/skills/tfl-ts/SKILL.md使用パターンと注意点
docs/mcp.mdローカル MCP サーバー(オフラインの docs ツールを含む)
CHANGELOG.mdリリースノート
docs/MIGRATION-v2.mdv1 → v2 の移行
examples/ライブラリから UI へのマッピング(地下鉄+バス)
docs/design/agent-friendly-cli.mdtfl docs と MCP docs が存在する理由
docs/design/evals.mdpnpm run eval が Jest のゲートではなくレートである理由

上記のすべては npm パッケージに含まれており、npx tfl-ts docs ls|cat|find|grep または MCP の docs ツールを使ってオフラインで参照できます。クローンは不要です。

playground/demo/ 以下のプレイグラウンドデモは、クローン用であり、パッケージの利用者向けではありません。

アーキテクチャ

OpenAPI snapshot (committed)
  → types.ts        (swagger-typescript-api, types only)
  → rawClient.ts    (owned generator, uniform object-param API)
  → client.raw.*    (public escape hatch)
  → wrappers        (line, stopPoint, …)

pnpm run build は TypeScript を CJS と ESM にコンパイルします。ネットワーク接続は不要で、OpenAPI の再生成も行いません。

コントリビューション

git clone https://github.com/ghcpuman902/tfl-ts.git
cd tfl-ts
pnpm install
pnpm run build
pnpm run test

便利なスクリプト:pnpm run generate、pnpm run check、pnpm run check -- --only=drift、pnpm exec tfl list。LLM_context.md と .cursor/skills/tfl-ts-maintainer/SKILL.md を参照してください。

ライセンス

MIT。Transport for London とは提携していません。

npmtfl-ts
GitHubghcpuman902/tfl-ts
Issuesバグを報告
ライブデモtfl.manglekuo.com

コメント

MCP は初めてですか?

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

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