{
  "markdown": "# China 12306 Train Tickets MCP\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![MCP](https://img.shields.io/badge/MCP-Server-blue)](https://modelcontextprotocol.io)\n[![Remote](https://img.shields.io/badge/Streamable%20HTTP-hosted%20free-success)](https://mcp.pianam.cn/train-mcp/mcp)\n\nQuery **China Railway 12306 ticket availability** from any MCP client — train schedules and remaining seats by Chinese station name and date. Read-only, no booking, no account.\n\n- **Try it in 30 seconds**: a free public MCP endpoint is already running — just paste the URL into your MCP client (no install, no API key).\n- **Or self-host**: a single Python file, stdlib HTTP + FastMCP, zero paid dependencies.\n\n## ⚡ Use the hosted endpoint (no setup)\n\n```\nhttps://mcp.pianam.cn/train-mcp/mcp\n```\n\nTransport: **Streamable HTTP** (MCP 2025-03-26 compatible). No authentication required.\n\n## 🔌 Client configuration\n\nAdd this to your MCP client's `mcpServers` configuration (Claude Desktop `claude_desktop_config.json`, Cursor `mcp.json`, Cline, Cherry Studio, etc.):\n\n```json\n{\n  \"mcpServers\": {\n    \"12306-train\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.pianam.cn/train-mcp/mcp\"\n    }\n  }\n}\n```\n\n> Clients that do not accept `\"type\": \"http\"` (some Cherry Studio / older\n> Cline versions) accept the same entry with just `\"url\"`.\n\n## 🧰 Tools\n\n| Tool | Parameters | Returns |\n|---|---|---|\n| `query_train_tickets(from_city, to_city, date=\"\")` | `from_city` / `to_city`: Chinese city or station names, e.g. `\"青岛\"`, `\"北京南\"`.<br>`date`: `YYYY-MM-DD`; empty defaults to **tomorrow**. 12306's booking window is usually 15 days. | Train list with train number, departure/arrival stations & times, duration, and remaining seats per class (business/first/second class, soft/hard sleeper, hard seat, no-seat). |\n| `search_station(keyword)` | `keyword`: e.g. `\"北京\"`. | Fuzzy-matches station names (returns up to 30: 北京, 北京南, 北京西, 北京北 …) when you are not sure which station to use. |\n\n## 📡 Data sources, caching & limits\n\n- Data comes from **12306's own public query endpoints** (`kyfw.12306.cn/otn/leftTicket/...`) — read-only queries only; **this server cannot book tickets**, please buy via the official 12306 app/website.\n- Station code table cached locally for 7 days; ticket queries cached for **300 seconds**.\n- No API key, no login required.\n- The hosted endpoint is rate-limited to **200 requests / minute / IP**.\n\n## 🐢 Self-hosting\n\n```bash\ngit clone https://github.com/boy-373/12306-train-mcp.git\ncd 12306-train-mcp\npip install -r requirements.txt\npython train_mcp_server.py\n# the server listens on 127.0.0.1:8003 by default; override with:\n#   MCP_HOST=0.0.0.0 MCP_PORT=9000 python train_mcp_server.py\n#   MCP_ALLOWED_HOSTS=\"your-domain.com,127.0.0.1:*\"\n#   MCP_ALLOWED_ORIGINS=\"https://your-domain.com\"\n```\n\nThen point your MCP client at `http://127.0.0.1:8003/mcp`.\nNo API keys or accounts are ever required.\n\n\n- `train_stations.json` — bundled 12306 station name → telegraph-code table (auto-refreshed from 12306 every 7 days).\n\n## 🗂️ Files\n\n- `train_mcp_server.py` — the MCP server (FastMCP, Streamable HTTP transport).\n- `rate_limit.py` — lightweight per-IP sliding-window rate-limit middleware (200 req/min default).\n- `requirements.txt` — `mcp`, `uvicorn`, `starlette`.\n- `server.json` — official MCP Registry manifest (remote server entry, ready to publish with `mcp-publisher`).\n- `smithery.yaml` / `glama.json` — directory listing metadata.\n\n---\n\n## 🧯 Parameter guide & common errors (read this if a call fails)\n\n**`query_train_tickets(from_city, to_city, date=\"\")`**\n\n| Parameter | What to pass | Notes |\n|---|---|---|\n| `from_city` / `to_city` | **Chinese station or city names**, e.g. `\"青岛\"`, `\"北京\"`, `\"上海虹桥\"` | A city name works when the city has one main station; for multi-station cities use the exact station name. Not sure? Call `search_station(\"北京\")` first — it returns 北京/北京南/北京西/北京北… |\n| `date` | `YYYY-MM-DD`, e.g. `\"2026-09-20\"` | Optional — **defaults to tomorrow** when empty. 12306's pre-sale window is **15 days** (dates further out return an error or empty results). |\n\n**Why you may get an HTTP 400 / error result:**\n\n1. **Bad date format** — must be exactly `YYYY-MM-DD` (`2026/09/20`, `2026年9月20日`, `Sep 20` all fail).\n2. **Station name not found** — typo, pinyin (`\"qingdao\"`), or a vague nickname the code table doesn't contain. Fix: call `search_station` with a keyword and copy the exact name.\n3. **City-level name for a multi-station city** — e.g. `\"北京\"` usually resolves to 北京 station, but if you want a specific station pass `\"北京南\"` / `\"北京西\"` explicitly.\n4. **Date outside the 15-day pre-sale window** — 12306 has not released those tickets yet.\n\n**Correct call examples:**\n\n```\nquery_train_tickets(from_city=\"青岛\", to_city=\"北京\", date=\"2026-09-20\")\nquery_train_tickets(from_city=\"北京南\", to_city=\"上海虹桥\")        # date omitted -> tomorrow\nsearch_station(keyword=\"上海\")                                   # -> 上海/上海南/上海虹桥/上海西…\n```\n\nA successful response returns `车次总数` plus a `车次` list (train number, departure/arrival station & time, duration, and remaining seats per class). An unrecognized station returns `{\"error\": \"出发站「…」无法识别，可用 search_station 工具查车站名\"}` — simply re-call with the exact name.\n\n---\n\n## 🧯 参数说明与常见错误（调用失败先看这里）\n\n**`query_train_tickets(from_city, to_city, date=\"\")` 参数说明**\n\n| 参数 | 填什么 | 注意 |\n|---|---|---|\n| `from_city` / `to_city` | **中文车站名或城市名**，如 `\"青岛\"`、`\"北京\"`、`\"上海虹桥\"` | 城市只有一个主车站时填城市名即可；多车站城市建议填具体车站名。不确定时先调 `search_station(\"北京\")`，会返回 北京/北京南/北京西/北京北 等准确站名 |\n| `date` | `YYYY-MM-DD` 格式，如 `\"2026-09-20\"` | 可留空，**留空默认查明天**；12306 预售期通常为 **15 天**，超出预售期的日期会查询失败或无结果 |\n\n**返回 400 / 错误结果的常见原因：**\n\n1. **日期格式错误**：必须严格为 `YYYY-MM-DD`，`2026/09/20`、`2026年9月20日`、`Sep 20` 等写法都会失败；\n2. **站名不存在**：错别字、拼音（如 `\"qingdao\"`）、或码表中没有的俗称都会无法识别。解决方法：先用 `search_station` 关键词搜索，复制返回的准确站名；\n3. **多车站城市用了城市通称**：如 `\"北京\"` 一般能匹配到「北京」站，但要去特定车站请明确传 `\"北京南\"`、`\"北京西\"` 等；\n4. **日期超出 15 天预售期**：12306 尚未放票，查询会返回失败提示。\n\n**正确调用示例：**\n\n```\nquery_train_tickets(from_city=\"青岛\", to_city=\"北京\", date=\"2026-09-20\")\nquery_train_tickets(from_city=\"北京南\", to_city=\"上海虹桥\")        # date 留空 -> 默认明天\nsearch_station(keyword=\"上海\")                                   # 返回 上海/上海南/上海虹桥/上海西…\n```\n\n调用成功会返回 `车次总数` 和 `车次` 列表（车次号、出发/到达站与时间、历时、各席别余票）；站名无法识别时返回 `{\"error\": \"出发站「…」无法识别，可用 search_station 工具查车站名\"}`，换成准确站名重试即可。\n\n## 🇨🇳 中文使用说明\n\n**一句话**：直接用中文站名查 12306 余票，数据来自 12306 官方公开查询接口，纯只读。\n\n**在线直连地址（免费、无需 Key、开箱即用）**：`https://mcp.pianam.cn/train-mcp/mcp`\n\n在 MCP 客户端（Claude Desktop / Cursor / Cherry Studio / Cline 等）的配置里加入：\n\n```json\n{\n  \"mcpServers\": {\n    \"12306-train\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.pianam.cn/train-mcp/mcp\"\n    }\n  }\n}\n```\n\n**工具**：\n\n- `query_train_tickets(from_city, to_city, date)`：查余票。出发/到达站直接给中文城市或车站名（如「青岛」「北京南」），日期格式 `YYYY-MM-DD`，留空默认明天；返回车次、出发到达时间、历时及商务座/一等座/二等座/软卧/硬卧/硬座/无座等余票。\n- `search_station(keyword)`：不确定城市有哪些车站时模糊搜索站名（如「北京」返回 北京/北京南/北京西/北京北 等）。\n- 仅查票，不能购票；12306 预售期通常 15 天。\n\n**服务特性**：数据源全部为公开接口、无需注册/付费；服务端内存缓存、失败自动降级/切换备用通道；单 IP 限流 200 次/分钟。\n\n**本地部署**：\n\n```bash\ngit clone https://github.com/boy-373/12306-train-mcp.git\ncd 12306-train-mcp\npip install -r requirements.txt\npython train_mcp_server.py\n# 默认监听 127.0.0.1:8003，可用环境变量 MCP_HOST / MCP_PORT / MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINS 覆盖\n```\n\n## 📄 License\n\n[MIT](LICENSE) © 2026 boy-373\n\n[![12306-train-mcp MCP server](https://glama.ai/mcp/servers/boy-373/12306-train-mcp/badges/score.svg)](https://glama.ai/mcp/servers/boy-373/12306-train-mcp)\n\n## Install via Smithery\n\nOne-click install for [Smithery](https://smithery.ai)-supported clients (Claude Desktop, Cursor, etc.):\n\n[![Smithery](https://smithery.ai/badge/1561852680/12306-train-mcp)](https://smithery.ai/servers/1561852680/12306-train-mcp)\n\nOr run:\n\n```bash\nnpx -y @smithery/cli install 1561852680/12306-train-mcp --client claude\n```\n\n---\n\n## 🔌 Use with Any AI Client — One-Click MCP Gateway\n\nWe host a free **MCP aggregation gateway**: your AI assistant (Cherry Studio, Claude Desktop, Cursor, Cline — any MCP client) discovers and uses MCP tools through a single URL:\n\n```\nhttps://mcp.pianam.cn/ai/mcp\n```\n\nAdd it once, then talk in plain language — the AI automatically **searches → inspects → calls** the right MCP for you.\n\n- 🔍 Search across **22,000+** indexed MCP servers (Chinese & English)\n- ⚡ **50+ live hosted MCPs** callable directly out of the box (weather, exchange rates, hot trends, IP geo, train tickets…)\n- 📦 GitHub-based MCPs: search finds them with links to install locally\n- ✅ Servers health-checked weekly — alive ones ranked first\n- 🆓 Free to use, no key required\n\n**📖 3-step setup guide / 中文接入教程**: https://mcp.pianam.cn/ai-gateway\n",
  "bytes": 8643,
  "sha": "05ee07ccf033f78efc2ac0beaa27ee8ba3df4a97cd0b1fd8d9d997240b5ad715",
  "repo_slug": "boy-373/12306-train-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_cn_pianam_mcp_12306_train_mcp_4e6261b7/readme"
}