Skip to main content
Glama

nagoya-bus-mcp

PyPI - Version PyPI - Python Version CI

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-mcp

For developers

# Use MCP Inspector
$ npx @modelcontextprotocol/inspector uv run nagoya-bus-mcp

# Try API client
$ uv run python -m nagoya_bus_mcp.client

Data 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 tools
get_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
route_codeYesThe route code (keito) to query (e.g., "1123002").

Output Schema

ParametersJSON Schema
NameRequiredDescription
bus_stopsYes通過時間を含む、系統のバス停のリスト
bus_positionsYes現在走行中のバスの位置のリスト

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
station_numberYesThe station number to query (e.g., 22460).

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesバス停の接近情報のURL
routesYes接近情報のある系統のリスト

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
station_nameYesThe station name to look up (e.g., "名古屋駅").

Output Schema

ParametersJSON Schema
NameRequiredDescription
station_nameYesバス停名
station_numberYesバス停番号

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
station_numberYesThe station number to query (e.g., 22460).

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes系統別の時刻表一覧のURL
timetablesYes
station_numberYesバス停番号

TDQS

B3.1/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 4 tool updatesv1.0.1
    • Addedget_approach_for_route
    • Addedget_approach_for_station
    • Changedget_station_number11 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / station_name / description
        Added value: +"The station name to look up (e.g., \"名古屋駅\")."
      • removedInput schema / properties / station_name / title
        Removed value: -"Station Name"
      • removedOutput schema / $defs
        Removed 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"
        -  }
        -}
      • addedOutput schema / description
        Added 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."
      • removedOutput schema / properties / result
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "$ref": "#/$defs/StationNumberResponse"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ]
        -}
      • addedOutput schema / properties / station_name
        Added value: +{
        +  "description": "バス停名",
        +  "type": "string"
        +}
      • addedOutput schema / properties / station_number
        Added value: +{
        +  "description": "バス停番号",
        +  "type": "integer"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "result"
        -]New value: +[
        +  "station_name",
        +  "station_number"
        +]
      • removedOutput schema / title
        Removed value: -"_WrappedResult"
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
    • Changedget_timetable12 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / station_number / description
        Added value: +"The station number to query (e.g., 22460)."
      • removedInput schema / properties / station_number / title
        Removed value: -"Station Number"
      • removedOutput schema / $defs
        Removed 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"
        -  }
        -}
      • addedOutput schema / description
        Added 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."
      • removedOutput schema / properties / result
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "$ref": "#/$defs/TimeTableResponse"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ]
        -}
      • addedOutput schema / properties / station_number
        Added value: +{
        +  "description": "バス停番号",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / timetables
        Added 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"
        +}
      • addedOutput schema / properties / url
        Added value: +{
        +  "description": "系統別の時刻表一覧のURL",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "result"
        -]New value: +[
        +  "station_number",
        +  "timetables",
        +  "url"
        +]
      • removedOutput schema / title
        Removed value: -"_WrappedResult"
      • removedOutput schema / x-fastmcp-wrap-result
        Removed value: -true
  2. 2 tool updatesv1.0.0
    • First observedget_station_number
    • First observedget_timetable

TDQS

A3.8/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a distinct operation: route-level approach, station-level approach, station number lookup, and timetable retrieval. No overlap in purpose.

Naming Consistency5/5

All tools follow a consistent 'get_X_for_Y' pattern with clear verb_noun structure, using snake_case throughout.

Tool Count4/5

4 tools is slightly low but acceptable for a focused bus information server. Each tool serves a clear purpose without being redundant.

Completeness3/5

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

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers