用 12306 MCP Server 打造自己的火车票查询机器人

“不用打开 App,也能查到最新余票”——这可能是开发者最优雅的出行方式。


为什么值得读这篇文章?

如果你经常出差、旅行,或者正在做一个需要火车票信息的自动化项目,你一定遇到过这些尴尬:

  • 12306 官方接口文档散落在各处,拼拼凑凑很费劲。
  • 想写个脚本定时查票,却被验证码、登录态、反爬策略拦住。
  • 老板临时要求“把火车票查询嵌进我们 AI 助手”,只剩两周时间。

这篇文章会告诉你:
如何在一台普通的笔记本上,10 分钟内跑起一个高性能的 12306 查询后端,并通过标准化协议(MCP)与 AI、自动化脚本、甚至微信小程序无缝衔接。


一、12306 MCP Server 是什么?

一句话解释:
12306 MCP Server 是一个帮你把 12306 官方数据“翻译”成标准接口的轻量级后端。

它用 FastAPI 写成,运行在 Python 3.10+ 上,支持官方余票、车站、经停、一次中转等查询,并通过 MCP(Model Context Protocol) 暴露给外部调用。

你可以把它理解成“火车票版的小爱同学底座”:

  • 前端(AI、脚本、App)只要会说 MCP,就能查票。
  • 后端替你处理 12306 的反爬、数据格式差异、缓存等问题。

二、10 行命令让它跑起来

下面给出两条路径:

  • 本地源码——适合想改代码的同学。
  • Docker 镜像——适合“拿来就用”的同学。

以下命令都在 macOS、Linux、Windows WSL 中实测通过;如果你用纯 Windows,请把 uv 换成 pip 即可。

路径 A:本地源码(推荐开发者)

步骤 命令 说明
1. 克隆源码 git clone https://github.com/drfccv/12306-mcp-server.git 代码不到 3 MB
2. 进入目录 cd 12306-mcp-server
3. 安装依赖 uv sync 自动创建虚拟环境并锁定版本
4. 更新车站库 uv run python scripts/update_stations.py 首次必须,后续每周跑一次即可
5. 启动服务 uv run python scripts/start_server.py 默认端口 8000

看到 INFO: Uvicorn running on http://0.0.0.0:8000 就成功了。

路径 B:Docker 一行搞定(推荐运维 / 产品同学)

docker pull drfccv/12306-mcp-server:latest
docker run -d -p 8000:8000 --name 12306-mcp-server drfccv/12306-mcp-server:latest

浏览器打开 http://localhost:8000/docs 就能看到 Swagger 界面,点击即可在线调试。


三、5 个核心工具速览

项目把常见需求拆成 5 个独立工具,每个工具都对应一个 MCP 接口,方便按需组合。

工具名 一句话作用 典型场景示例
query_tickets 查余票、车次、座席、时刻 “明天北京到上海,最早一班高铁”
search_stations 车站模糊搜索 “深圳北是‘SZN’还是‘IZQ’?”
get_station_info 车站详情(坐标、拼音) 在地图上标出车站
query_transfer 一次中转换乘 “没有直达,如何先到武汉再转长沙?”
get_train_route_stations 列车完整时刻表 “G1 次列车到底停几站?”
get_current_time 当前时间与相对日期 “帮我算三天后的日期,别填错”

每个工具都有独立 Markdown 文档,位于项目 /docs 目录,包含请求示例、返回字段含义、常见报错排查,建议收藏。


四、FAQ:新手最常问的 10 个问题

Q1:我需要登录 12306 账号吗?
A:不需要。项目只调用 12306 公开接口,不触碰任何需要登录的私密数据。

Q2:多久更新一次车站数据?
A:官方偶尔新增或改名车站。建议每周跑一次 update_stations.py,脚本会自动下载最新版。

Q3:会不会被封 IP?
A:官方公开接口没有严格频率限制,但出于礼貌,建议每秒不超过 3 次请求。项目内部已做指数回退,可放心使用。

Q4:我要在服务器上长期运行,需要 supervisord 吗?
A:Docker 方式已内置健康检查;源码方式可用 systemd/supervisord,示例配置在 /examples 目录。

Q5:如何接入我的 AI 助手?
A:只要你的助手支持 MCP,把下面 JSON 片段写进配置即可:

{
  "mcpServers": {
    "12306": {
      "url": "http://<你的服务器>:8000/mcp"
    }
  }
}

Q6:支持哪些城市三字码?
A:全国所有客运车站,包括港澳台高铁车站。可用 search_stations 实时查。

Q7:能查学生票、儿童票吗?
A:目前只返回成人票余量。学生、儿童票价计算规则复杂,官方未公开,暂不支持。

Q8:中转方案多久算一次?
A:实时计算,平均 200 ms 内返回。中转城市默认选官方推荐,也可手动指定。

Q9:如何贡献代码?
A:Fork 后提 PR,CI 会自动跑单测。贡献前请阅读 CONTRIBUTING.md

Q10:商业项目能用吗?
A:项目采用 MIT 许可证,可商用。但请自行评估 12306 官方政策及法律风险。


五、动手实验:用 curl 查一张票

假设你已经在本地跑起了服务,我们来查一张“明天北京南→上海虹桥”的 G 字头车票。

  1. 先搜车站代码
curl -s "http://localhost:8000/search_stations?keyword=北京南" | jq

返回:

[{"name":"北京南","code":"VNP"}]
  1. 再查余票
curl -s "http://localhost:8000/query_tickets?from=VNP&to=AOH&date=2025-07-17" | jq '.[].train_no'

你会看到类似 G1, G3, G101 这样的车次列表,附带余票数、座席等级、出发到达时间。

  1. 想看中转?
    query_tickets 换成 query_transfer,其余参数不变即可。

六、目录结构速读(便于二次开发)

12306-mcp-server/
├─ src/mcp_12306/
│  ├─ server.py        # FastAPI 入口,所有路由集中注册
│  ├─ services/        # 真正干活的代码
│  │  ├─ ticket.py     # 余票逻辑
│  │  ├─ station.py    # 车站逻辑
│  │  └─ transfer.py   # 中转换乘
│  ├─ models/          # Pydantic 数据模型,自动校验入参
│  └─ utils/           # 日志、缓存、异常统一处理
├─ scripts/
│  ├─ update_stations.py
│  └─ start_server.py
├─ docs/               # 每个工具的独立文档
└─ tests/              # pytest 单测,覆盖率 90%+

如果你只想改业务逻辑,直接看 services/ 目录即可;想加新接口,在 server.py 中新增路由,再写个单测就能提 PR。


七、测试与持续集成

项目内置 pytest 单测,跑一遍不到 10 秒:

uv run pytest

CI 会在每次 push 时自动执行:

  • Python 3.10 与 3.11 双版本测试
  • 代码格式(ruff)
  • 类型检查(mypy)

绿色 ✅ 后才允许合并,保证主干始终可运行。


八、常见集成场景示例

场景 技术栈 集成要点
企业微信机器人 Python + Flask 监听群消息 → 调用 MCP → 返回车次卡片
语音助手 Node.js + MCP SDK 把自然语言转成参数,再查票
小程序 云开发 + 云函数 云函数内请求 MCP,返回给前端
自动化抢票 cron + curl 定时查余票,有余票就发邮件

所有场景都遵循同一套 MCP 协议,换语言、换平台都不需要改后端。


九、写在最后:如何优雅地遵守规则

12306 的数据属于公开信息,但接口并不对外承诺 SLA。为了长期稳定运行,请记住三条底线:

  1. 合理频率:每秒 ≤ 3 次,高峰时段再降一半。
  2. 不存储隐私:不要把乘客姓名、身份证落库。
  3. 不误导用户:展示数据时注明“来自 12306 公开接口,仅供参考”。

项目作者在免责声明里写得很清楚:

“使用本项目造成的任何后果均由使用者本人承担。”

把技术用在让生活更美好的地方,而不是和系统对抗,这才是开发者应有的优雅。


附录:一分钟速查表

任务 一条命令
本地启动 uv run python scripts/start_server.py
更新车站 uv run python scripts/update_stations.py
Docker 启动 docker run -d -p 8000:8000 drfccv/12306-mcp-server:latest
跑测试 uv run pytest
查看文档 打开 /docs/*.md 或使用 Swagger

祝你旅途愉快,也祝你的机器人永不宕机。