mcpField
S
sbb-opendata-mcp

sbb-opendata-mcp

本地服务
github.com地图与出行25 周前更新

关于 sbb-opendata-mcp

sbb-opendata-mcp 通过 OpenDataSoft API 向 AI 应用和兼容 MCP 的客户端提供瑞士联邦铁路公开数据。数据涵盖铁路运营、车站、基础设施和房地产,并同时返回结构化结果与可读内容。

主要功能

  1. 01按车站查询客流
  2. 02获取当前铁路中断信息
  3. 03查询基建与房地产项目
  4. 04查询列车数量和站台数据
  5. 05比较车站并搜索停靠点
  6. 06浏览数据集目录

适用场景

  1. 01查看瑞士铁路当前中断情况
  2. 02比较主要车站的客流
  3. 03查找站台信息和附近停靠点

MCP 相关

提供读取 SBB 开放数据的 MCP 工具,支持 stdio 和 Streamable HTTP 传输。结果包含结构化内容,并可输出 Markdown 或 JSON。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"malkreide-sbb-opendata": {
"command": "uvx",
"args": [
"sbb-opendata-mcp"
]
}
}
}
启动命令uvx sbb-opendata-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypisbb-opendata-mcp0.4.0

工具

9

收录的工具列表 · 更新于 2 周前

参数类型必填说明
paramsany是

详细介绍

🚆 sbb-opendata-mcp

🇨🇭 属于 瑞士公共数据 MCP 项目组合

PyPI License: MIT Python 3.11+ MCP Data Source CI

将 AI 模型连接到瑞士联邦铁路(SBB)开放数据的 MCP 服务——包括客流量、铁路实时中断、基础设施与房地产项目、列车数量、站台数据、车辆信息,以及来自 data.sbb.ch 的车站搜索。无需 API 密钥。

🇩🇪 德语版本

演示

演示:Claude 查询 SBB 客流量


概述

sbb-opendata-mcp 让 Claude 等 AI 助手能够直接访问 SBB 公共数据,无需复制粘贴或手动调用 API。诸如 “2024 年每天有多少乘客经过 Zürich HB?” 这样的问题,可以通过真实测量数据得到解答。

SBB 开放数据门户使用 OpenDataSoft REST API(v2.1)。此服务会将数据转换为简洁的 Markdown 和 JSON,供 AI 模型使用;还会在便于阅读的文本之外提供 MCP structuredContent,让程序化客户端无需重新解析即可使用底层记录。此服务与模型无关,可与任何兼容 MCP 的客户端配合使用。

示例查询: “比较 Zürich HB、Bern 和 Basel SBB 的客流量与站台容量。” → 按受众分类的更多使用场景 →


功能

  • 📊 客流量 – 按车站和年份统计上车/下车人数(日均值)
  • 🚨 铁路实时中断 – 交通通知,每 5 分钟更新一次
  • 🏗️ 基础设施项目 – 车站和线路建设
  • 🏢 房地产项目 – SBB 房地产开发(每日更新)
  • 🚆 分路段列车数量 – 按线路统计列车数量(SBB、BLS、SOB 等)
  • 🛤️ 站台数据 – 长度、类型、面积、无障碍通行
  • 🚃 车辆信息 – 运力和建造年份
  • 🔁 车站对比 – 跨多个数据集比较多达 10 个车站
  • 🔍 车站搜索 – 瑞士 DiDok 注册库(覆盖整个瑞士)
  • 📦 数据集目录 – 列出全部约 89 个 SBB 开放数据集
  • 🔑 无需 API 密钥 – 所有数据均为公开数据,可免费使用
  • ☁️ 双传输方式 – 使用 stdio 连接 Claude Desktop,使用 Streamable HTTP 部署到云端

前提条件

  • Python 3.11+
  • 无需 API 密钥——所有数据均来自公共门户 data.sbb.ch

安装 uv(推荐):

curl -LsSf https://astral.sh/uv/install.sh | sh

安装

从 PyPI 安装:

pip install sbb-opendata-mcp

或使用 uvx(无需永久安装):

uvx sbb-opendata-mcp

进行本地开发时,从克隆的仓库以可编辑模式安装:

git clone https://github.com/malkreide/sbb-opendata-mcp.git
cd sbb-opendata-mcp
pip install -e ".[dev]"

快速开始

# Start the server (stdio mode for Claude Desktop)
sbb-opendata-mcp

在 Claude Desktop 中立即试用:

“2024 年每天有多少人在 Zürich HB 上车?” “瑞士铁路网络当前是否有中断?”


配置

环境变量

服务器通过 stdio 运行时无需配置。以下变量用于调整可选的 Streamable HTTP 传输、日志和可观测性。

变量作用默认值
MCP_HOSTHTTP 传输的绑定主机。在本地使用时保持为 127.0.0.1;只有在受控的容器/云环境中才绑定到 0.0.0.0。127.0.0.1
MCP_PORTHTTP 传输的端口。8000
MCP_ALLOWED_HOSTS以逗号分隔的主机允许列表,用于防范 DNS 重绑定(例如 your-app.onrender.com,your-app.onrender.com:*)。仅 localhost
MCP_ALLOWED_ORIGINS以逗号分隔的浏览器来源允许列表(例如 https://your-app.onrender.com)。(none)
LOG_LEVEL日志详细程度(DEBUG/INFO/WARNING/…)。INFO
LOG_FORMAT使用 json 输出结构化日志;其他值则输出便于阅读的文本。始终写入 stderr。text

🔒 DNS 重绑定/Origin 防护始终启用;localhost 已加入允许列表,因此本地 HTTP 开发开箱即用。日志写入 stderr——stdout 留作 stdio JSON-RPC 通道使用。

Claude Desktop 配置
{
  "mcpServers": {
    "sbb-opendata": {
      "command": "uvx",
      "args": ["sbb-opendata-mcp"]
    }
  }
}

配置文件位置:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json

重启 Claude Desktop——首次使用时会自动下载服务器。

其他 MCP 客户端

适用于 Cursor、Windsurf、VS Code + Continue、LibreChat、Cline,以及通过 mcp-proxy 使用的可自托管模型——配置与上述相同。

云端部署(Streamable HTTP)

适用于通过浏览器中的 claude.ai 或远程服务使用(例如 Render.com)。云端传输使用 Streamable HTTP(端点 /mcp)。

Docker(推荐):

# Build + run with explicit resource limits (see docker-compose.yml)
docker compose up --build
# → http://127.0.0.1:8000/mcp

该镜像采用多阶段构建,并以非 root 用户身份运行;docker-compose.yml 添加了 read_only、no-new-privileges 以及内存/CPU/PID 限制。

手动部署/Render.com:

pip install -e .

# Bind publicly (behind a rate-limiting reverse proxy) and configure
# DNS-rebinding / Origin protection for your hostname:
export MCP_HOST=0.0.0.0
export MCP_ALLOWED_HOSTS="your-app.onrender.com,your-app.onrender.com:*"
export MCP_ALLOWED_ORIGINS="https://your-app.onrender.com"
python -m sbb_opendata_mcp.server --http --port 8000

⚠️ 绑定: 在网络传输中,服务器默认绑定到 127.0.0.1,因此本地启动的服务器不会暴露给整个网络。仅在容器/云环境中,当确实需要绑定所有接口时,才设置 MCP_HOST=0.0.0.0(Docker 镜像会自动设置此项),并将服务器置于实施速率限制的反向代理之后(若端点不应公开,还需进行身份验证)。详见 SECURITY.md。


可用工具

工具描述数据更新频率
sbb_get_passenger_frequency按车站和年份统计的上下车人数(每日平均值)每年
sbb_get_rail_disruptions实时铁路交通消息每 5 分钟
sbb_get_real_estate_projectsSBB 房地产开发项目每日
sbb_get_trains_per_segment按路线区段统计的列车数量(SBB、BLS、SOB …)每年
sbb_get_platform_data站台数据(长度、类型、面积)持续更新
sbb_get_rolling_stock车辆数据(载客量、建造年份)持续更新
sbb_compare_stations比较最多 10 个车站(多数据集)–
sbb_search_stations搜索站点(瑞士 DiDok 登记册,涵盖全瑞士)持续更新
sbb_list_datasets列出全部约 89 个 SBB 开放数据集–

所有工具都支持 response_format: "markdown"(便于阅读)和 "json"(便于机器读取),并支持分页。每个工具还会在渲染后的文本旁返回 MCP structuredContent(底层记录/元数据),并通过 outputSchema 声明其结构。错误结果会设置 isError: true,并返回 {error, upstream_unavailable}。

示例用例
查询工具
“2024 年每天有多少人在 Zürich HB 上车?”sbb_get_passenger_frequency
“瑞士铁路网目前有哪些运营中断?”sbb_get_rail_disruptions
“比较 Zürich HB、Bern 和 Basel SBB”sbb_compare_stations
“SBB 有哪些正在进行的房地产建设项目?”sbb_get_real_estate_projects
“Zürich–Winterthur 路线上每年有多少列火车运行?”sbb_get_trains_per_segment
“Wädenswil 有哪些站点?”sbb_search_stations

→ 按受众分类的更多用例


架构

┌─────────────────┐     ┌───────────────────────────┐     ┌──────────────────────────┐
│   Claude / AI   │────▶│   SBB Open Data MCP       │────▶│       data.sbb.ch        │
│   (MCP Host)    │◀────│   (MCP Server)            │◀────│                          │
└─────────────────┘     │                           │     │  OpenDataSoft REST v2.1  │
                        │  9 Tools                  │     │  (public, no API key)    │
                        │  Stdio | Streamable HTTP  │     │                          │
                        │                           │     │  passagierfrequenz       │
                        │  Shared httpx client      │     │  rail-traffic-information │
                        │  (pooled, lifespan-managed)│    │  construction-projects   │
                        │  ODSQL escaping + Pydantic │     │  perron · rollmaterial   │
                        │  validation               │     │  zugzahlen · dienststellen│
                        └───────────────────────────┘     └──────────────────────────┘

项目结构

sbb-opendata-mcp/
├── src/sbb_opendata_mcp/
│   ├── __init__.py
│   └── server.py                   # FastMCP server, all 10 tool definitions
├── tests/
│   └── test_server.py              # Unit + live API smoke tests
├── audits/                         # MCP best-practice audit evidence
├── docs/assets/demo.svg            # README demo asset
├── .github/workflows/ci.yml        # GitHub Actions (Python 3.11/3.12/3.13)
├── Dockerfile                      # Multi-stage, non-root runtime image
├── docker-compose.yml              # Local run with resource limits
├── claude_desktop_config.json      # Example Claude Desktop config
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── EXAMPLES.md
├── LICENSE
├── README.md                       # This file (English)
└── README.de.md                    # German version

安全与限制

  • **只读:**所有 9 个工具都只执行只读 HTTP GET 请求,不会在上游写入、修改或删除数据。
  • **不涉及个人数据:**查询仅临时处理,不会存储。门户返回的是汇总统计、基础设施和运营元数据,不会处理或保留 PII。
  • **无需 API 密钥:**数据公开且免费,无需身份验证,也无需管理密钥。
  • 防注入:year/canton 会经过正则表达式验证,插入 ODSQL where 子句的每个值都会通过中央辅助函数进行转义。
  • **数据时效性:**实时工具(运营中断)会反映查询时的上游数据源;统计数据集每年/每天更新(参见工具表)。
  • **服务条款:**数据依据 data.sbb.ch 许可证发布(允许非商业用途、允许商业用途、要求注明出处)。
  • **不作保证:**此服务是社区项目,与 SBB 无关联。服务可用性取决于上游 API。

完整的安全说明请参阅 SECURITY.md。


已知限制

  • **客流量:**每年更新;最新完整年度的数据可能会延迟数月。
  • **铁路运营中断:**返回所有当前的瑞士铁路消息 → 使用 limit 和分页。
  • **区间列车数量:**数量为年度汇总数据,并非实时数据。
  • **车站搜索:**覆盖完整的瑞士 DiDok 注册表(所有运营商),而不仅仅是 SBB。
  • **自身不进行速率限制:**请将公开的 HTTP 部署置于具备速率限制功能的反向代理之后。

MCP 协议版本

此服务通过同一个端点支持两个协议时代。客户端在连接上的第一个请求决定采用哪个时代;之后若再声明另一个时代,则会被拒绝。

时代修订版本使用者
initialize 握手2024-11-05 … 2025-11-25当今客户端使用的版本。服务会以请求的修订版本作答;若请求的版本更新,则会以 2025-11-25 这一上限作答。
每请求封套2026-07-28携带 2026-07-28 _meta 封套的请求会开启现代连接。

两个修订版本都固定在 tests/test_protocol_version.py 中,并与已安装的 SDK 进行断言比对,因此 Dependabot 升级 mcp 时不会悄然改变其中任一版本。两项线上协议测试会通过 mcp.streamable_http_app()(--http 提供的应用)针对每个时代发送真实请求,并从响应中读取修订版本:一项是无会话的 2026-07-28 server/discover POST,另一项是请求 2026-07-28 的 initialize,其响应会限制在 2025-11-25。

除了 SDK 自身的功能外,此服务为 2026-07-28 提供的内容固定在 tests/test_spec_2026_07_28.py 中:完整的 serverInfo(现代时代会在每个结果中附上此信息;如果没有 version,读取结果就是 "")、每个工具顶层的 title、每个工具的 outputSchema(服务和 SDK 客户端都会根据它进行验证),以及列表方法上的 ttlMs/cacheScope。

请注意,SDK 的 LATEST_PROTOCOL_VERSION 是现代时代的别名,而不是握手时代的别名——若只根据它固定版本,当前客户端实际协商的时代仍会任其漂移。

更新策略。 门禁失败时,不要盲目修改常量:先阅读两个修订版本之间的规范变更日志,确认服务仍正常运行,然后一并更新常量、本节、README.de.md 和 CHANGELOG.md。


测试

无需 API 密钥。

# Unit tests (no network required)
PYTHONPATH=src pytest tests/ -m "not live"

# Live API smoke tests (require network access to data.sbb.ch)
PYTHONPATH=src pytest tests/ -m live

# Re-record the fixtures from data.sbb.ch (writes tests/fixtures/PROVENANCE.md)
python scripts/record_fixtures.py

单元测试的负载均为实录,并非杜撰。每个文件的来源、检索日期、筛选规则和 SHA-256 值记录在 tests/fixtures/PROVENANCE.md 中。

tests/fixtures/dataset_fields.json 不是数据摘录,而是契约: Explore v2.1 API 会声明每个数据集的字段名称;如果 select 或 order_by 使用了该数据集不存在的字段,API 会返回 HTTP 400,而不是减少列数。TestFieldContract 会根据这份声明核对服务使用的每个字段名称,因此下一次重命名会导致测试失败,而不是让用户的请求失败。截至 2026-08-08,十个工具中有三个正是因此一直无法正常工作。

CI 不会运行线上测试(-m "not live")。这三个故障工具中有两个曾经有覆盖它们的线上测试——test_live_search_waedenswil 和 test_live_list_datasets。测试覆盖确实存在,但测试并未运行。


更新日志

参见 CHANGELOG.md


贡献

参见 CONTRIBUTING.md


安全

有关安全状况和漏洞报告方式,请参见 SECURITY.md (Deutsch)。


许可证

MIT License — 参见 LICENSE


作者

Hayal Oezkan · github.com/malkreide


致谢与相关项目

安装

通过 uv 的 uvx 运行——无需克隆或手动安装。将其添加到 MCP 客户端配置中(Claude Desktop、Cursor 和 Windsurf 使用 mcpServers;VS Code 在 .vscode/mcp.json 中使用顶层 servers 键):

{
  "mcpServers": {
    "sbb-opendata-mcp": {
      "command": "uvx",
      "args": [
        "sbb-opendata-mcp"
      ]
    }
  }
}

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。