mcp-server-12306: an MCP server for China Railway 12306 ticket queries
12306 MCP Server 是一个基于 Model Context Protocol (MCP) 的高性能火车票查询后端系统。它通过标准化接口提供官方 12306 的实时数据服务,包括余票查询、车站信息、列车经停站、中转换乘方案等核心功能。
At a glance
- What is it?
- A Python MCP server that wraps 12306's public endpoints as seven callable tools, exposing live seat availability, prices, stations, transfer plans and train stop schedules to any MCP client. It is aimed at developers wiring Chinese rail travel into an AI assistant or an automation script.
- Who is it for?
- Adopt it if you are building an MCP client that needs Chinese rail data and you accept that the upstream interface is unofficial and can change without notice. Do not adopt it if you need ticket booking, refunds or account operations, since the tool list covers queries only, or if you cannot run a process that reaches 12306 directly.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap mcp-server-12306 fills between an AI assistant and 12306
An AI assistant asked to plan a trip from Beijing to Shanghai has no way to read the railway timetable. The 12306 site is built for browsers, and its query endpoints are not published as a documented public API. This project packages those queries behind the Model Context Protocol, so a client that already speaks MCP gets seven callable tools instead of a scraping script. The README lists the capabilities as seat availability, ticket price, station search, transfer plans, train stop schedules and a time helper. The audience is narrow and specific: developers running a local MCP client such as Claude Desktop or Cursor, or teams standing up a shared HTTP endpoint that other agents call. It is not a consumer app and it does not sell tickets. The project description calls it a high performance backend; the concrete claim in the README is broader, that it serves real time data from the official 12306 source through a standardised interface.
One core server, two transports, seven tools
The architecture separates transport from business logic. src/mcp_12306/server.py holds tool registration in a TOOL_HANDLERS mapping and dispatch through call_tool, and both the stdio and HTTP entry points reuse that same instance. The README states this keeps behaviour identical across modes. Tool schemas come from a single source, ticket_service.MCP_TOOLS, and the HTTP /schema/tools endpoint serves the same definitions, so a schema cannot drift between the two transports. Business logic lives in two services: station_service.py loads and searches station data and converts between Chinese names, pinyin, initials and three letter codes, while ticket_service.py implements the seven tools. Station data ships as a static resource, station_name.js, and scripts/update_stations.py refreshes it. The HTTP layer adds endpoints the stdio mode has no use for: /health reports loaded station count and active sessions, /schema/tools returns the JSON Schema, and / returns version and protocol information. The README also notes protocol negotiation against MCP SDK v2, covering both the 2025-11-25 handshake era and a later 2026-07-28 protocol revision.
Installing mcp-server-12306 and making a first query
Python 3.10 through 3.13 is required, and the README recommends uv for isolation. The fastest path is uvx, which runs the package without a persistent install. The stdio mode communicates over standard input and output and occupies no network port, which is why the README recommends it for local clients.
uvx mcp-server-12306For a persistent install, pip or pipx work the same way.
pip install mcp-server-12306A local MCP client is configured by pointing at the command. The README gives this example for claude_desktop_config.json.
{
"mcpServers": {
"12306": {
"command": "uvx",
"args": ["mcp-server-12306"]
}
}
}If you prefer a network service, the HTTP transport starts on port 8000 by default and exposes the MCP endpoint at /mcp.
mcp-12306{
"mcpServers": {
"12306": {
"url": "http://localhost:8000/mcp"
}
}
}A Docker image is published as drfccv/mcp-server-12306:latest, and the README's run command maps port 8000 and names the container mcp-server-12306. Once connected, the first useful call is a seat query: query-tickets takes from_station, to_station and train_date, and returns trains, seat classes and times in one response. Station names do not have to be exact, because search-stations accepts Chinese, pinyin, initials or the three letter code, and the README puts the station set at 3382 or more entries.
Where mcp-server-12306 stops: queries, not transactions
The tool table is the boundary. Every tool reads: availability, price, station lookup, transfers, stop schedules, train number resolution, current time. There is no booking, no order, no refund, no passenger or account operation. If your agent needs to actually buy a seat, this server is the wrong component and no configuration flag changes that. The second limitation is the data source itself. The README's environment requirements simply say the host must be able to reach 12306's official interface. There is no documented retry policy, no rate limit guidance and no caching layer described, so a deployment that fans many concurrent queries at the upstream service is operating outside anything the project documents. The disclaimer section exists in the README for a reason. Third, station data is a shipped file. If a station opens or a code changes and the resource is stale, search results will be wrong until scripts/update_stations.py is run, and the README does not describe a scheduled refresh. Finally, the project is published as version 0.5.0.post20260822 and classified as Development Status 4 - Beta, so interface changes between minor versions are a reasonable thing to plan for.
How mcp-server-12306 differs from calling the 12306 API yourself
The obvious alternative is a direct HTTP client against 12306's query endpoints: a few functions in your own codebase, no extra process. The difference is what you inherit. A hand-rolled client owns the request signing, the response shape, the station code table and the retry logic, and it must be updated whenever the upstream changes. This project moves that into a maintained package with a station dataset of 3382 or more entries and a pinyin search layer you would otherwise have to build. The cost is a process boundary and a dependency on MCP as the calling convention. If your consumer is not an MCP client, you pay for a protocol you do not use, though the HTTP mode's /schema/tools and /health endpoints make it scriptable over plain HTTP. A second alternative is a general purpose scraping or travel API service. Those typically cover multiple transport modes and charge per call, while this project is MIT licensed, self-hosted and limited to 12306. The trade is breadth against control: you run the process, you own the network path to 12306, and you get no vendor support.
Maintenance, releases and what the MIT licence leaves you
The last push to the repository was on 2026-08-22, so the project is current. There are no retrieved releases, and versioning lives in pyproject.toml as 0.5.0.post20260822, a scheme that appears to embed the build date and produces no GitHub release objects to watch. Upgrades therefore mean tracking the package on PyPI or the Docker tag drfccv/mcp-server-12306:latest, and the Docker tag is mutable, so a pinned digest is the only way to make a container build reproducible. The dependency set is small: httpx2, pydantic-settings, mcp, aiofiles and pytz, with the HTTP transport dependencies arriving transitively through mcp. The uv configuration points at the Tsinghua mirror by default with Aliyun as a second index, which is convenient inside China and worth knowing if you build outside it. The MIT licence permits commercial use and modification, and there is no separate terms file beyond the LICENSE entry. The README carries a disclaimer section, which is the project's own acknowledgement that the upstream data relationship is not something it controls. That is a factual statement about the licence and the code, not legal advice about your obligations to 12306.
Editorial conclusion
Adopt it if you are building an MCP client that needs Chinese rail data and you accept that the upstream interface is unofficial and can change without notice. Do not adopt it if you need ticket booking, refunds or account operations, since the tool list covers queries only, or if you cannot run a process that reaches 12306 directly. Before wiring it into anything user-facing, verify the station dataset is current by running scripts/update_stations.py, and confirm your deployment's network path to 12306 from the host that will run the server.
Frequently asked questions
What is an MCP server and how does mcp-server-12306 work as one?
MCP is the Model Context Protocol, and a server implementing it exposes tools that a client can call. mcp-server-12306 registers seven tools in a TOOL_HANDLERS mapping inside server.py and dispatches calls through call_tool, reusing the same core instance for both its stdio and HTTP transports.
Can mcp-server-12306 be hosted as a remote service?
Yes. The Streamable HTTP mode starts a web service on port 8000 by default, with the MCP endpoint at /mcp plus /health, /schema/tools and / endpoints, and a Docker image is published as drfccv/mcp-server-12306:latest.
How is MCP different from a plain API in this project?
The README describes the server as providing 12306 data through a standardised MCP interface, so an MCP-aware client discovers and calls tools without bespoke request code. The HTTP transport still speaks JSON-RPC over POST, GET and DELETE, so the underlying calls remain scriptable.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/drfccv-mcp-server-12306)