A 17-file server covers the useful search path
The 17-file checkout exposes eight MCP tools around China's 12306 rail system. Five resolve the current date or map cities, station names, and telecodes. Three do the work a traveler cares about: direct-ticket search, transfer search, and route-stop lookup. Results can include train times, fares, seat availability, and filtered train types. There is no purchase tool. That boundary makes the project useful for research and comparison, without pretending an AI agent can complete a booking.
The documentation is Chinese-first. An English paragraph explains the purpose, and the README includes usable installation and configuration snippets in English. The principle guide and architecture guide are Chinese, as are most issue discussions. A maintainer who reads Chinese gets a detailed map of the station indexes, cookie flow, and upstream endpoints. An English-only team can start the server, but will have more source reading to do when a query breaks.
The 21-second install hides a live-service dependency
Our sandbox installed 240 npm packages in 21 seconds and occupied 231 MB. The TypeScript build finished in 5 seconds. Those are friendly numbers for an MCP adapter, especially beside a 0.5 MB checkout. The README offers npx -y 12306-mcp for stdio, a port flag for HTTP, and Docker commands for both modes. Node.js 18 is the normal floor, while the MCP Inspector debug command requires Node.js 22.19.0.
Startup is coupled to the public rail service. The server opens the 12306 home page, finds the current station-data JavaScript file, downloads it, and builds four lookup maps before serving useful calls. Ticket, transfer, and route tools then obtain cookies and call live 12306 endpoints. You do not need an API token according to the documented flow, but DNS, outbound access, page shape, cookies, and upstream availability all sit in the request path.
What happened when we ran it
Our run at commit ff6439d completed installation in 21 seconds, the build in 5 seconds, and the test step in 45 seconds. All three commands exited successfully in a fresh unprivileged Debian container with 3 CPUs and 8 GB of RAM. The repository occupied 0.5 MB before dependencies, then 231 MB after 240 packages were installed. That is a clean first launch, and it is the strongest reason to try the project before writing your own adapter.
The word "tests" needs context here. The package script runs TypeScript compilation and then starts build/index.js; the repository has no tests directory. Our lab also found no CI workflow. The passing 45-second result proves that the checked-out code compiled and its server command completed under the harness. It does not tell you how station parsing behaves after a page change, or whether every ticket field survives an upstream response change.
Npm audit reported 5 known vulnerabilities: 3 high and 2 moderate, with none rated critical or low. The checkout includes a Dockerfile, so packaging is available even though automated repository checks were absent from our scan. Before exposing HTTP transport, inspect the advisory paths, decide how the endpoint will be authenticated, and run a real query from the deployment network. The README does not describe a production access-control layer around that HTTP mode.
Two open reports question MCP handshake behavior
The source supports stdio plus SSE and Streamable HTTP through a port option, while version v0.3.10 depends on the 1.x MCP TypeScript SDK. Open issue 67 reports 10 failed requirements against the 2026-07-28 protocol revision. Issue 68 reports 5 against the 2025-11-25 revision. Both reports say initialization or discovery timed out and the official SDK connection closed before downstream checks could run.
Those reports also state their limit: the server contacts live 12306 during startup, so the test container's network or startup delay may have contributed. That caveat prevents a clean protocol-bug verdict. It does not make the reports irrelevant. If your client needs quick initialization, reproduce the issue from your own network and pin the MCP SDK behavior you have verified. The open pull request to move to MCP SDK v2 shows that protocol maintenance is still in motion.
Search remains the product boundary in v0.3.10
Release v0.3.10 was published on July 30, 2026, and the last repository push was July 31. The release changed how the ticket-query URL is obtained and updated dependencies. GitHub showed 1,604 stars and 7 open issues and pull requests on September 17, 2026. New issue activity continued into September, so an older release date alone does not describe a dormant project. The queue includes feature requests as well as the protocol reports.
Ticket buying is still outside the documented feature set. Open issue 60 asks whether ordering can be added, while the README describes the repository as a learning project and lists other interfaces only as hoped-for work. Treat returned availability as information to verify in the official service. If the assistant must take payment, manage passengers, hold inventory, or change a booking, the official 12306 app is the appropriate handoff.
A 45-second pass is only a launch check
A 45-second successful launch check is enough to make 12306-mcp cheaper to try than to re-create. The server already handles station codes, Shanghai-time dates, cookies, filters, transfers, and route stops. That is a useful slice of the rail-search problem. Its 240-package dependency tree and 5 audit findings are still real operating costs, and the absence of a conventional test suite leaves upstream parsing changes exposed.
Use it behind an MCP client when the user is searching, comparing, or planning Chinese rail travel. Keep the official booking flow in view, pin v0.3.10 or another tested release, and add a startup probe that confirms station data loaded before the agent receives traffic. The decision turns on a simple trade: the 21-second install saves adapter work, while live-service coupling and unresolved handshake reports become yours to monitor.

