Nagoya Bus MCP
The Nagoya Bus MCP server lets you query real-time and scheduled bus information for Nagoya City's public bus network, sourced live from the official Nagoya City bus website.
Look up bus stop numbers (
get_station_number): Find a bus stop's number by name, with fuzzy matching support.Get timetables (
get_timetable): Retrieve full departure timetables for all routes at a given bus stop, organized by day of week, including route names, directions, and departure times.Check real-time bus positions for a route (
get_approach_for_route): Get live bus position data for a specific route, including which stops buses have recently passed and where currently running buses are located.Check real-time approaching buses at a stop (
get_approach_for_station): See all buses currently approaching a specific stop across all routes, sorted by nearest approaching bus.Use prompt templates (
ask_timetable,ask_bus_approach): Built-in templates for common natural-language queries about timetables and bus approach information.
Click on "Deploy 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., "@Nagoya Bus MCPwhen is the next bus from Nagoya Station to Sakae?"
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.
nagoya-bus-mcp
English | 日本語
Overview
Nagoya Bus MCP is a Model Context Protocol (MCP) server that lets LLMs query Nagoya City bus information. Built with FastMCP, it exposes tools and prompts for looking up bus stops, reading timetables, and checking real-time bus approach and position information. Data is sourced from the public Nagoya City bus website.
Once connected to an MCP client such as Claude Desktop, you can ask questions like "When is the next bus from Nagoya Station?" in natural language and get answers backed by live data.
Related MCP server: Singapore Bus MCP Server
Features
The server exposes the following tools:
get_station_number— find a bus stop number from a stop name (with fuzzy matching).get_timetable— departure timetables for every route at a bus stop, organized by day of week.get_approach_for_route— real-time bus positions and latest passage times along a route.get_approach_for_station— real-time approaching buses for all routes at a bus stop.
It also provides prompt templates ask_timetable and ask_bus_approach for common questions.
Example queries
Bus data is in Japanese, so queries work best in Japanese:
「名古屋駅のバスの時刻表を教えて」 (What's the bus timetable at Nagoya Station?)
「栄のバスの接近情報を教えて」 (Show real-time bus approach info at Sakae.)
「新栄町のバス停番号を教えて」 (What's the bus stop number for Shin-sakaemachi?)
Getting started
The Nagoya Bus MCP server is published to PyPI.
Claude Desktop
Add the following configuration to claude_desktop_config.json.
{
"mcpServers": {
"nagoya-bus": {
"command": "uvx",
"args": ["nagoya-bus-mcp"]
}
}
}Visual Studio Code
Add the following configuration to .vscode/mcp.json.
{
"servers": {
"nagoya-bus": {
"type": "stdio",
"command": "uvx",
"args": ["nagoya-bus-mcp"],
"env": {}
}
}
}Manual
# Using uvx
$ uvx nagoya-bus-mcp
# Using Docker
$ docker run -i --rm ghcr.io/ymyzk/nagoya-bus-mcpFor developers
# Use MCP Inspector
$ npx @modelcontextprotocol/inspector uv run nagoya-bus-mcp
# Try API client
$ uv run python -m nagoya_bus_mcp.clientData source
This project queries the public Nagoya City bus website (https://www.kotsu.city.nagoya.jp). It is an unofficial project and is not affiliated with or endorsed by the City of Nagoya.
Available Tools
4 toolsget_approach_for_routeA
Get real-time bus approach and position information for a route.
Provides both historical data (latest bus passages at stops) and current position data for buses actively running on the route.
| Name | Required | Description | Default |
|---|---|---|---|
| route_code | Yes | The route code (keito) to query (e.g., "1123002"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| bus_stops | Yes | 通過時間を含む、系統のバス停のリスト |
| bus_positions | Yes | 現在走行中のバスの位置のリスト |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It mentions both historical and current data but does not disclose read-only nature, rate limits, data freshness, or other behavioral traits. Adequate but not comprehensive.
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?
Two concise sentences, first stating the core function and second adding context. No redundant information.
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?
The description is fairly complete for a simple tool with one parameter and an output schema. It covers both historical and current aspects but could mention limitations or expected usage scenarios.
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% with a clear description for route_code. The tool description adds no additional parameter semantics beyond what the schema already provides, so baseline 3 is appropriate.
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 it gets real-time approach and position information for a route, distinguishing it from the sibling tool get_approach_for_station. It also specifies that it provides both historical and current data.
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 use for route-level data but does not explicitly provide when to use this tool versus the sibling get_approach_for_station or other tools. It lacks guidance on exclusions or context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_approach_for_stationA
Get real-time bus approach information for all routes at a station.
Provides a list of routes that currently have activity at the specified station (either a recent passage time or at least one approaching bus), along with a URL for more details.
Routes that have neither a latest pass time nor any approaching buses are filtered out and are not included in the result. The remaining routes are sorted by the proximity of their approaching buses so that routes with the nearest approaching vehicles appear first.
| Name | Required | Description | Default |
|---|---|---|---|
| station_number | Yes | The station number to query (e.g., 22460). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | バス停の接近情報のURL |
| routes | Yes | 接近情報のある系統のリスト |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description effectively discloses key behavioral traits: it filters out routes without recent activity, sorts by proximity, and includes a URL. This goes beyond basic functionality and helps an agent understand the tool's behavior.
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 with three sentences, front-loading the main purpose and then providing clear details about filtering and sorting. Every sentence adds value without redundancy.
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 a simple parameter and the presence of an output schema, the description covers all essential aspects: what it does, what is filtered, sorting order, and the inclusion of a URL. It is fully complete for an agent to use correctly.
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% with a clear parameter description. The tool description does not add additional meaning beyond the schema's existing description, so it meets the baseline without extra value.
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 it gets real-time bus approach information for all routes at a station, distinguishing it from siblings like get_approach_for_route (specific route) and get_timetable (timetable). The verb 'Get' and resource 'approach for station' are specific and unambiguous.
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 provides clear context on when to use (to get approach info for all routes at a station) and what the output contains. However, it does not explicitly exclude use cases or mention alternatives, leaving some ambiguity for agents to infer from sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_station_numberA
Get station number for a given station name using fuzzy matching.
Attempts exact match first, then falls back to fuzzy matching with 60% similarity threshold if no exact match is found.
| Name | Required | Description | Default |
|---|---|---|---|
| station_name | Yes | The station name to look up (e.g., "名古屋駅"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| station_name | Yes | バス停名 |
| station_number | Yes | バス停番号 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the fuzzy matching behavior and the fallback from exact match, which is transparent. It does not mention error handling or read-only nature, but for a simple lookup, the disclosed behavior 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 very concise, consisting of two short sentences. The first sentence states the purpose and method, and the second elaborates on the algorithm. There are no superfluous words, and the information is front-loaded.
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 tool has only one parameter and an output schema (though not shown), the description is fairly complete. It explains the input, the algorithm, and the purpose. It does not mention the output format or error handling, but the output schema likely covers the return value. For its simplicity, it is adequate.
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?
The input schema has 100% coverage for the single parameter, with a description. The tool description adds details about the matching algorithm beyond the schema, providing context on how the parameter is used. This adds value beyond the schema's built-in description.
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's purpose: to get a station number from a station name using fuzzy matching. It specifies the verb 'get', the resource 'station number', and adds detail about the matching logic. It distinguishes itself from siblings by being a lookup tool, while siblings are for routes and timetables.
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 explains when to use the tool: when you have a station name and need its number. It provides context about the matching algorithm (exact then fuzzy with 60% threshold), which guides usage. However, it does not explicitly state when not to use or mention alternatives, but the sibling tools are clearly different, so this is acceptable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_timetableB
Get formatted timetable information for all routes at a station.
Retrieves and formats timetable data including routes, directions, boarding locations, and departure times organized by day of week.
| Name | Required | Description | Default |
|---|---|---|---|
| station_number | Yes | The station number to query (e.g., 22460). |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | 系統別の時刻表一覧のURL |
| timetables | Yes | |
| station_number | Yes | バス停番号 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It mentions retrieval and formatting but does not clarify if it is read-only, what happens if the station does not exist, or any other important side effects or constraints.
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?
Two concise sentences: the first states the primary action, the second elaborates on the content. No redundant or unnecessary information.
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 existence of an output schema, the description sufficiently covers the tool's functionality. However, it lacks usage guidance and differentiation from sibling tools, which would improve completeness.
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?
The schema covers the only parameter (station_number) with a description including an example. The tool description does not add extra meaning beyond what the schema already provides, so it meets the baseline for high coverage.
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 it retrieves formatted timetable information for all routes at a station, using a specific verb and resource. However, it does not explicitly distinguish itself from sibling tools like get_approach_for_route, which fetch more specific data.
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 provides no guidance on when to use this tool versus alternatives (e.g., getting approach info for a specific route). It only describes what it does, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.1- Added
get_approach_for_route - Added
get_approach_for_station - Changed
get_station_number11 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / station_name / descriptionAdded value: +"The station name to look up (e.g., \"名古屋駅\")." - removed
Input schema / properties / station_name / titleRemoved value: -"Station Name" - removed
Output schema / $defsRemoved value: -{ - "StationNumberResponse": { - "properties": { - "station_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Station Name" - }, - "station_number": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Station Number" - }, - "success": { - "title": "Success", - "type": "boolean" - } - }, - "required": [ - "success" - ], - "title": "StationNumberResponse", - "type": "object" - } -} - added
Output schema / descriptionAdded value: +"Response model for station number lookup by name.\n\nUsed by the get_station_number tool to return station lookup results,\nincluding fuzzy matching outcomes." - removed
Output schema / properties / resultRemoved value: -{ - "anyOf": [ - { - "$ref": "#/$defs/StationNumberResponse" - }, - { - "type": "null" - } - ] -} - added
Output schema / properties / station_nameAdded value: +{ + "description": "バス停名", + "type": "string" +} - added
Output schema / properties / station_numberAdded value: +{ + "description": "バス停番号", + "type": "integer" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "station_name", + "station_number" +] - removed
Output schema / titleRemoved value: -"_WrappedResult" - removed
Output schema / x-fastmcp-wrap-resultRemoved value: -true
- Changed
get_timetable12 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / station_number / descriptionAdded value: +"The station number to query (e.g., 22460)." - removed
Input schema / properties / station_number / titleRemoved value: -"Station Number" - removed
Output schema / $defsRemoved value: -{ - "TimeTable": { - "properties": { - "direction": { - "description": "方面", - "title": "Direction", - "type": "string" - }, - "pole": { - "description": "乗り場", - "title": "Pole", - "type": "string" - }, - "route": { - "description": "路線", - "title": "Route", - "type": "string" - }, - "stop_stations": { - "description": "停車バス停のリスト", - "items": { - "type": "string" - }, - "title": "Stop Stations", - "type": "array" - }, - "timetable": { - "additionalProperties": { - "items": { - "type": "string" - }, - "type": "array" - }, - "description": "曜日別の時刻表", - "title": "Timetable", - "type": "object" - }, - "url": { - "title": "Url", - "type": "string" - } - }, - "required": [ - "route", - "direction", - "pole", - "stop_stations", - "timetable", - "url" - ], - "title": "TimeTable", - "type": "object" - }, - "TimeTableResponse": { - "properties": { - "station_number": { - "title": "Station Number", - "type": "integer" - }, - "timetables": { - "items": { - "$ref": "#/$defs/TimeTable" - }, - "title": "Timetables", - "type": "array" - }, - "url": { - "title": "Url", - "type": "string" - } - }, - "required": [ - "station_number", - "timetables", - "url" - ], - "title": "TimeTableResponse", - "type": "object" - } -} - added
Output schema / descriptionAdded value: +"Response model for station timetable queries.\n\nContains all timetables for different routes operating at a given station,\nalong with the station identifier and reference URL." - removed
Output schema / properties / resultRemoved value: -{ - "anyOf": [ - { - "$ref": "#/$defs/TimeTableResponse" - }, - { - "type": "null" - } - ] -} - added
Output schema / properties / station_numberAdded value: +{ + "description": "バス停番号", + "type": "integer" +} - added
Output schema / properties / timetablesAdded value: +{ + "items": { + "description": "Timetable information for a single route at a station.\n\nContains route details, direction, boarding location, and departure times\norganized by day of week.", + "properties": { + "direction": { + "description": "行き先", + "type": "string" + }, + "pole": { + "description": "のりば", + "type": "string" + }, + "route": { + "description": "系統", + "type": "string" + }, + "route_codes": { + "description": "系統コードのリスト", + "items": { + "type": "integer" + }, + "type": "array" + }, + "stop_station_names": { + "description": "停車バス停名のリスト", + "items": { + "type": "string" + }, + "type": "array" + }, + "timetable": { + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": "曜日別の時刻表", + "type": "object" + }, + "url": { + "description": "系統の時刻表のURL", + "type": "string" + } + }, + "required": [ + "route", + "route_codes", + "direction", + "pole", + "stop_station_names", + "timetable", + "url" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / urlAdded value: +{ + "description": "系統別の時刻表一覧のURL", + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "station_number", + "timetables", + "url" +] - removed
Output schema / titleRemoved value: -"_WrappedResult" - removed
Output schema / x-fastmcp-wrap-resultRemoved value: -true
2 tool updates
v1.0.0- First observed
get_station_number - First observed
get_timetable
TDQS
Scored across 4 tools
Each tool targets a distinct operation: route-level approach, station-level approach, station number lookup, and timetable retrieval. No overlap in purpose.
All tools follow a consistent 'get_X_for_Y' pattern with clear verb_noun structure, using snake_case throughout.
4 tools is slightly low but acceptable for a focused bus information server. Each tool serves a clear purpose without being redundant.
Missing tools to list available routes or stations, which may create dead ends for agents that don't know route or station names in advance. Core real-time and timetable queries are covered.
Maintenance
Related MCP Connectors
Real-time transit stops, routes, arrivals, vehicle positions, and schedules via OneBusAway APIs.
Provide real-time transportation data including bus arrivals, train service alerts, carpark availa…
Read-only public transit departures, stop search, and city coverage for bus and train users.
Get real-time bus arrival times for any Singapore bus stop by code, with optional service filterin…
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides Matsumoto city community bus information via GTFS data, enabling stop search, departure times, nearby stops, and route details.1-
- FlicenseNot gradedqualityDmaintenanceProvides real-time Singapore bus information, including arrival times, routes, and stop details via the LTA DataMall API.1-
- AlicenseNot gradedqualityBmaintenanceMCP server for Japanese public transit journey planning with interactive map UI, enabling station search, route planning, and departure lookups via natural language.MIT
- AlicenseBqualityCmaintenanceEnables route planning and transit information retrieval for Japan using the public Transit API. Supports searching stations, planning routes, and checking departures.101MIT