otp-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@otp-mcpHow long does it take from Shinjuku to Shibuya?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
otp-mcp
セルフホストした OpenTripPlanner (OTP) を MCP(Model Context Protocol)サーバー越しに使えるようにするツール。Claude Code や claude.ai から「AからBは電車で何分?」を、自分の手元のOTPが持つ正確な経路データで聞けるようにする。
作った背景
きっかけは、ある公開の経路検索API(MCP付き)を触ったこと。MCP越しに plan_journey を叩いて経路が返ってくる体験はとても便利だった一方、そのAPIは「力技で集めた時刻表のパッチワーク」で、JRの直通・乗継系統(上野東京ライン・京浜東北快速など)を取りこぼし、関東の所要時間を実態の約2倍に誤ることがあった(飲み会場所最適化アプリ arigatai-score の経路エンジン選定の中で実測)。
一方で、自分は arigatai-score 用に 関東全域のOTP(TokyoGTFS + OSM からビルドしたグラフ)を既にセルフホストしている。これは Yahoo!乗換案内とほぼ一致する精度(平均誤差 約3分)を持つ。
だったら「便利なMCPの体験」を「自前OTPの正確なデータ」で実現すればいい——というのがこのツール。
トレードオフはこうなる:
公開API(パッチワーク) | otp-mcp(自前OTP) | |
カバレッジ | 全国だが穴が多い | 関東のみ |
精度 | 平均誤差 約17分 | 平均誤差 約3分 |
「狭いが正確な経路MCP」を狙ったツール。
Related MCP server: openroute-mcp
設計思想
薄いラッパーに徹する: 経路検索のロジックはOTPに任せ、このサーバーはOTPのGraphQL(
planConnection/stops)を叩いて結果を読みやすく整形するだけ。stdio / HTTP 両対応: ローカルの Claude Code は stdio、claude.ai のリモートコネクタは HTTP(Streamable HTTP + 任意のBearer認証)。1つの実装で両方をカバーする。足場は自分がフォークして使っている scrapbox-cosense-mcp の構成を下敷きにした。
経路の見せ方: leg(区間)ごとに「路線名・駅・所要分」を並べ、出発/到着時刻と乗換回数を添える。
提供ツール
plan_journey(from, to, numItineraries?)— 経路検索。from/toは駅名(例:新宿)か"緯度,経度"。ランク付けされたルートを返す。suggest_stations(q, limit?)— 駅名サジェスト。座標付きで返す。
出力例(plan_journey 新宿 渋谷):
新宿 → 渋谷
【ルート1】15:26 → 15:34 所要8分 乗換0回
🚶 徒歩 4分 → 新宿
🚃 JR湘南新宿ライン 新宿 → 渋谷 4分
🚶 徒歩 1分 → 渋谷前提
経路検索の本体である OTP が動いていて、このサーバーから到達できること。本リポジトリ自体はOTPを含まない。
既定では arigatai-score の docker compose で動くOTP(サービス名
otp、http://otp:8080)を想定別構成のOTPに繋ぐ場合は
OTP_BASE_URLを設定
使い方
Claude Code(ローカル / stdio)
ビルドして、.mcp.json に登録する:
npm install
npm run build{
"mcpServers": {
"otp": {
"command": "node",
"args": ["/home/kouki/dev/otp-mcp/build/index.js"],
"env": { "OTP_BASE_URL": "http://localhost:8080" }
}
}
}OTP_BASE_URL はOTPに到達できるURLにする(OTPのポートをホスト公開している場合は http://localhost:8080 など)。
claude.ai / リモート(HTTP)
Docker Compose で HTTP サーバーとして起動し、Cloudflare Tunnel 等で公開して claude.ai のカスタムコネクタに登録する:
cp .env.example .env # MCP_AUTH_TOKEN を設定推奨
docker compose up -d --buildエンドポイント:
https://<公開ホスト>/mcpMCP_AUTH_TOKENを設定した場合はAuthorization: Bearer <token>が必要既定の compose は arigatai-score の Docker ネットワーク(
arigatai-score_internal)に相乗りしてhttp://otp:8080に到達する
CLI(動作確認用)
node build/index.js plan 新宿 渋谷
node build/index.js suggest 新宿今後の展望
station_departures(発車標)の追加(OTPのstoptimesクエリ)出発/到着時刻の指定
運賃・乗換回数のメタ情報付与
OTPのカバレッジを関東以外へ広げたら、そのまま全国対応に
関連
arigatai-score — このOTPを使う、飲み会場所最適化アプリ
Available Tools
3 toolsplan_journeyA
Plan a public-transit (rail/subway) journey using a self-hosted OpenTripPlanner instance (self-hosted OTP (Kanto rail/subway)). 'from' and 'to' are each a station name (e.g. "新宿") or a "lat,lon" coordinate. Returns ranked itineraries with per-leg lines (line name, stations, minutes), departure/arrival times, and transfer count. Accurate within the covered area (Kanto); returns no route for places outside coverage.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Destination: a station name or a "lat,lon" coordinate. | |
| from | Yes | Origin: a station name or a "lat,lon" coordinate. | |
| numItineraries | No | Number of itineraries to return (default 3). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description adequately discloses that this is a read-only query to a self-hosted OTP instance, returns ranked itineraries with detailed per-leg information, and fails gracefully for out-of-coverage locations. It does not mention any side effects or rate limits, but given the read-only nature, the transparency is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (4 sentences) and front-loaded with the core purpose. While a more structured format (e.g., bullet points) could improve readability, the current paragraph is clear and efficient with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema, the description covers the return format (ranked itineraries, per-leg details, times, transfer count) and a failure scenario. It does not address error handling for invalid station names, but for a simple tool with 3 parameters, it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains each parameter. The description reiterates that 'from' and 'to' can be station names or coordinates, and mentions the default for 'numItineraries', which is already in the schema. Thus, the description adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool plans a public-transit journey using a specific self-hosted OTP instance for the Kanto area. It distinguishes from siblings by focusing on rail/subway journey planning, while 'plan_route_map' likely handles map-based routes and 'suggest_stations' provides station suggestions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for journey planning within Kanto but does not explicitly guide when to use this tool versus alternatives like 'plan_route_map' or 'suggest_stations'. It provides a limitation (covers only Kanto) but no direct comparison or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_route_mapA
Plan a rail/subway journey and render it as a Yahoo!乗換案内-style vertical timeline (an inline interactive view on claude.ai). The view shows stations, departure/arrival times, line names in their official colors, and transfer points stacked vertically; the same itinerary is also returned as text. 'from' and 'to' are each a station name (e.g. "新宿") or a "lat,lon" coordinate. By default shows the best (fastest) itinerary; use 'routeIndex' to pick another. Prefer this over plan_journey when a visual route is helpful.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Destination: a station name or a "lat,lon" coordinate. | |
| from | Yes | Origin: a station name or a "lat,lon" coordinate. | |
| routeIndex | No | Which itinerary to show, 0 = best/fastest (default 0). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description discloses key behaviors: returns both visual timeline and text, shows stations, times, line colors, transfer points, accepts station names or coordinates. It could mention potential limitations like API availability or language support.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and concise, with the main purpose in the first sentence. It avoids redundancy and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, it adequately explains return format (visual timeline and text) and covers all parameters. Could briefly mention error handling or supported regions, but overall complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so baseline is 3. Description adds meaning by explaining 'from' and 'to' can be station names or 'lat,lon' coordinates, and routeIndex selects itinerary (0=best). This goes beyond the schema's short descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Plan a rail/subway journey and render it as a Yahoo!乗換案内-style vertical timeline' with specific verb-resource pairing and distinguishes from sibling 'plan_journey' by emphasizing the visual output.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises 'Prefer this over plan_journey when a visual route is helpful', providing clear when-to-use guidance. Also explains default best itinerary and routeIndex for alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_stationsA
Autocomplete station names against the self-hosted OpenTripPlanner instance (self-hosted OTP (Kanto rail/subway)). Returns matching stations with coordinates. Use to resolve or disambiguate a name before plan_journey.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Station name prefix or substring. | |
| limit | No | Max results (default 10). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must cover behavioral traits. It indicates the tool returns matching stations with coordinates and references a specific instance, but does not mention authentication, rate limits, or that it is a read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences. The first sentence delivers the core purpose, and the second provides usage guidance. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple autocomplete tool with only two parameters and no output schema, the description covers the essential aspects: what it does, what it returns, and its intended use case. Minor missing details about error handling or behavior for exact matches.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description adds context for the 'q' parameter by stating it expects a station name prefix or substring. However, it does not elaborate on the 'limit' parameter beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool autocompletes station names against a specific OTP instance, returns matching stations with coordinates, and is meant to resolve names before using plan_journey. It distinguishes itself from siblings by specifying its role as a preliminary step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises using this tool before plan_journey, providing clear context. However, it does not mention when not to use or alternative approaches for disambiguation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a clearly distinct purpose: plan_journey for text itineraries, plan_route_map for visual timelines, and suggest_stations for name resolution. There is no overlap in functionality.
All tools follow a verb_noun pattern with consistent prefixes (plan_, suggest_). The naming is predictable and clear.
Three tools is slightly minimal but covers the core workflow: suggest stations, plan text journey, plan visual journey. The scope is focused and each tool earns its place.
The core journey planning is covered, but there are notable gaps such as missing tools for station details, line information, or schedule data, which agents might need.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Transitland MCP — global GTFS aggregator
Swiss Transport MCP — wraps Transport Open Data API (free, no auth)
SEPTA MCP — Philadelphia SEPTA real-time transit (www3.septa.org/api, keyless)
TomTom MCP — wraps the TomTom Search & Routing APIs (api.tomtom.com)
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that provides tools for querying live transit data (stops, departures, routes, vehicles, alerts) from any WP GTFS Pro site, enabling AI assistants to answer rider questions.21GPL 2.0
- AlicenseAqualityDmaintenanceMCP server for planning routes (hiking, biking, driving, etc.) using the OpenRouteService API. Provides tools to find coordinates, create routes with GPX/PNG/HTML output, search POIs, and compute reachable areas.62MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying Swiss public transport data (stations, departures, connections) from the Transport Open Data API via natural language through an MCP gateway.5MIT
- AlicenseNot gradedqualityAmaintenanceEnables querying stops, routes, real-time arrivals, vehicle positions, and schedules from OneBusAway transit APIs via MCP, supporting STDIO or Streamable HTTP.1711Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ojimpo/otp-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server