tfl-ts について
tfl-tsはTransport for Londonのデータを読み取り専用で扱う、型定義付きのTypeScriptクライアントです。RESTラッパーとオフラインの駅構内データを備え、エージェント向けのローカルMCPサーバーも含みます。
主な機能
- 01型定義付きTfL APIクライアント
- 0284個のRESTエンドポイントのラッパー
- 03オフラインの駅構内データ
- 04路線状況と到着情報の照会
- 05経路計画
活用シーン
- 01現在の地下鉄運行状況の確認
- 02停留所の到着情報の照会
- 03TfLを利用した経路の計画
MCP 対応
`npx tfl-ts mcp`で読み取り専用のローカルMCPサーバーを起動できます。路線状況、到着情報、経路計画、ID解決、同梱ドキュメント用のツールを提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y tfl-tsTFL_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 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
7掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
TfL API TypeScript クライアント
型付きの TfL クライアントです。使いやすいラッパー、84 個の生 REST エンドポイント、20 路線のオフライン駅構成データを提供します。
tfl-ts で構築 → Board
比較
| tfl-ts | tfl-unified-api | tfl-journey-planner | tfl-mcp | mcp-tfl | |
|---|---|---|---|---|---|
| TypeScript 型定義 | あり | なし | なし | ソースのみ | あり(src/index.ts) |
| 依存関係ゼロ | あり | なし | なし | なし | なし |
| 生エンドポイントの対応数 | 84 | 84 件中 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.raw | 84 個すべての REST エンドポイント(pnpm exec tfl list は JSON を出力します。--text は従来の行形式です) |
client.realtime | REST の到着情報を使った即時取得ポーリング |
実行時の依存関係はありません(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.md | v1 → v2 の移行 |
| examples/ | ライブラリから UI へのマッピング(地下鉄+バス) |
| docs/design/agent-friendly-cli.md | tfl docs と MCP docs が存在する理由 |
| docs/design/evals.md | pnpm 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 とは提携していません。
| npm | tfl-ts |
| GitHub | ghcpuman902/tfl-ts |
| Issues | バグを報告 |
| ライブデモ | tfl.manglekuo.com |
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。