内容
# db-fahrplan-mcp
一款(非官方)适用于 [德意志铁路时刻表 API](https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables) 的 MCP 服务器 — 站点搜索、计划出发时间以及实时更改(延误、站台更改、取消)作为 Claude 和其他 MCP 客户端的工具。
使用 Python 和 [FastMCP](https://github.com/modelcontextprotocol/python-sdk) 编写。API 的 XML 响应在服务器端被解析为紧凑的 JSON,以便工具输出保持小巧且易读。
## 工具
| 工具 | API 端点 | 描述 |
|---|---|---|
| `find_station` | `/station/{pattern}` | 按名称、EVA 号码或 DS100 代码搜索站点 |
| `get_departures` | `/plan/…` + `/fchg/…` (合并) | 一个小时时间片的时刻表(默认为当前时间),包含实时数据:延误、站台更改、取消、新增行程 |
| `get_live_changes` | `/fchg/{eva}` | 当前日期的所有已知实时更改 |
| `get_recent_changes` | `/rchg/{eva}` | 仅限过去 2 分钟的更改(廉价轮询) |
典型流程:`find_station("Aachen Hbf")` → EVA 号码 → `get_departures(eva_no)`。
## 设置
要求:Python ≥ 3.10,[uv](https://docs.astral.sh/uv/),免费的 DB API 凭证。
**1. 获取凭证** — 在 [DB API 市场](https://developers.deutschebahn.com) 注册,创建应用程序,并将其订阅到 **时刻表** API。这将为您提供客户端 ID 和 API 密钥。
**2. 克隆和配置:**
```bash
git clone https://github.com/eric134422/db-fahrplan-mcp.git
cd db-fahrplan-mcp
uv sync
cp .env.example .env # 然后将您的凭证粘贴到 .env 中
```
**3. 在您的 MCP 客户端中注册** — 例如 Claude Code(`.mcp.json`):
```json
{
"mcpServers": {
"db-fahrplan": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/db-fahrplan-mcp", "run", "server.py"]
}
}
}
```
## 架构
```
server.py MCP 层:FastMCP 实例 + 四个 @mcp.tool()(stdio 传输)
api.py HTTP 层:httpx 客户端,身份验证标头,错误映射
parser.py 翻译层:DB 的 XML → 紧凑的 JSON 字典
```
各层之间故意保持独立:`api.py` 不了解 MCP,`parser.py` 不了解 HTTP。可以单独交换或测试每个模块。
### 为什么需要解析层?
时刻表 API 返回 XML,具有单字母属性(`pt` = 计划时间,`ct` = 更改时间,`pp`/`cp` = 计划/更改站台,`ppth` = 路线)。直接将其传递给 LLM 会浪费上下文并容易导致误读 — 一个 `/fchg` 响应对于主要枢纽可以超过 800k 个字符。`parser.py` 将属性映射到命名 JSON 字段,计算 `delay_minutes`,从路线路径解析起始/终止站点,并删除空字段。`get_live_changes` 还会限制站点列表(`limit` 参数,默认为 30)并报告总计数。
属性语义来自官方 OpenAPI 规范 — 从 [DB API 市场](https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables) 下载 `Timetables-*.json` 以获取完整字典。
## 值得了解的 API 怪癖
- **EVA 号码** 是所有事物的主键(`8000001` = 亚琛 Hbf)。德国站点以 `80` 开头。
- **站点搜索** 是基于德意志铁路精确命名的前缀匹配:`Stolberg(Rheinl)Hbf` 有效,`Stolberg Hbf` 无效。变音符号通常失败;`*` 作为通配符有效。
- **原始 API 中的时间** 是 `YYMMddHHmm` 字符串,位于德国本地时间;解析器将其转换为 ISO (`2026-07-13T14:47`)。
- **`/plan` 时间片是静态的** — 它们永远不包含延误。实时数据仅存在于 `/fchg` 和 `/rchg` 中,这就是为什么 `get_departures` 获取两者并在服务器端合并它们。
- **长途交通(ICE/IC/EC/NJ)包含在内**,不仅是区域 RE/RB/S — 但是在 `/fchg` 中,准点的长途列车可以显示为一个裸站点(仅时间戳,没有 `line`/`train` 字段),因为名称仅附加到包含实际延误/中断的记录。如果您需要长途列车的可靠名称,请使用 `/plan`(`get_departures`)。
## 路线图
- [ ] 测试(pytest,模拟 API 响应)
- [ ] `get_train` — 跟随单个行程穿越站点
- [ ] 可选的完整路线(`via` 站点)在出发输出中
- [ ] MCPB 打包
欢迎贡献 — 代码库故意保持小巧和易读。问题和问题也欢迎用德语提出。
## 许可证
[MIT](LICENSE)。不隶属于德意志铁路股份公司。API 数据受 [DB API 条款](https://data.deutschebahn.com/nutzungsbedingungen.html) 的约束。