
Swiss Transport Mcp
io.github.malkreide由 GitHub 账号 malkreide 发布v0.5.0更新于 Oct 24, 2026
OJP 2.0 journey planning, SIRI-SX disruptions, occupancy, fares, train formation
概览
本地 MCP 服务器,为助手提供瑞士公共交通数据:行程规划、实时发车、中断信息、载客率、票价和列车编组。
- 可以做什么
- 按名称或坐标搜索车站,并查找附近车站,查看含延误和站台的实时发车信息。规划从 A 到 B 的行程,包含换乘、时长和交通方式。查询实时中断、取消和线路封闭,以及列车载客率预测。查询票价和列车编组详情,如车厢、等级、设施和无障碍信息。搜索并读取约 90 个开放交通数据集的目录。
- 适用场景
- 适合让助手回答瑞士出行问题:下一班发车、车站间换乘、当前中断、列车拥挤程度、票价,或某列车是否有餐车。
- 运行要求
- 需要 Python 3.11+ 或 uvx 在本地以 stdio 运行该包。必须使用 opentransportdata.swiss API 管理平台提供的免费 API 密钥,通过 TRANSPORT_API_KEY 设置;可选密钥 SIRI_SX_API_KEY、OCCUPANCY_API_KEY、FORMATION_API_KEY 和 OJP_FARE_API_KEY 用于启用扩展工具。需要访问 opentransportdata.swiss 的出站 HTTPS 网络。
安装
在 SourceWeft 中
- 打开 控制台中的 Swiss Transport Mcp,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
🇨🇭 Part of the Swiss Public Data MCP Portfolio
🚆 swiss-transport-mcp
[Version] [License: MIT] [Python 3.11+] [MCP] [Data Source] [CI]
MCP server connecting AI models to the Swiss public transport system – journey planning, real-time departures, disruptions, occupancy, ticket prices, train formations and open data from opentransportdata.swiss.
Demo
[Demo: Claude queries disruptions and departures]
Overview
swiss-transport-mcp gives AI assistants like Claude a complete Swiss travel information system – not just timetables, but also real-time disruption alerts, occupancy forecasts, ticket prices, and a full train formation view. All accessible through a single, standardised MCP interface.
The various APIs at opentransportdata.swiss speak different protocols – OJP 2.0 (XML/SOAP), SIRI-SX (XML), REST/JSON. This server translates everything into clean JSON for the AI model, acting as a multilingual protocol interpreter.
Anchor demo query: "Plan a school trip for 25 students from Zurich to the Technorama in Winterthur – check for disruptions and find the best departure." → More use cases by audience →
Features
- 🗺️ Journey planning (A → B with transfers, duration, transport mode) via OJP 2.0
- 🕐 Real-time departures with delays and platform information
- 🔍 Stop search by name or coordinates
- 🚨 Live disruption alerts (cancellations, closures) via SIRI-SX
- 📊 Occupancy forecasts for trains (SBB, BLS, Thurbo, SOB)
- 💰 Ticket prices including class selection
- 🚃 Train formation – coaches, classes, amenities, accessibility
- 📦 Open data catalogue – ~90 transport datasets via CKAN
- 🔑 Graceful degradation – server starts with core tools even without optional API keys
- ☁️ Dual transport – stdio for Claude Desktop, Streamable HTTP/SSE for cloud deployment
Prerequisites
- Python 3.11+
- A free API key from api-manager.opentransportdata.swiss (subscribe to OJP 2.0 as minimum)
- Optional: additional keys for SIRI-SX, Occupancy, Formation, OJP Fare
Installation
Or with uvx (no permanent installation):
Quickstart
Try it immediately in Claude Desktop:
"What are the next departures from Zurich Stadelhofen?" "How do I get from Wädenswil to Bern by train?"
Configuration
Environment Variables
APIs without a key are silently disabled – the server starts fine with just the 6 core tools.
Operational / security variables:
🔒 Egress allow-list: all outbound requests are restricted to
https://onopentransportdata.swisshosts. Any other host is refused before a request is sent (SSRF / egress hardening).
Claude Desktop Configuration
Minimal (core tools only):
Full (all 11 tools):
Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Cloud Deployment (Streamable HTTP)
For use via claude.ai in the browser (e.g. on managed workstations without local software). The cloud transport is Streamable HTTP (MCP_TRANSPORT=streamable-http, endpoint /mcp). SSE (/sse) is still supported but deprecated.
Docker (recommended):
The image is a multi-stage build running as a non-root user; docker-compose.yml adds read_only, no-new-privileges and memory/CPU/PID limits.
Render.com:
- Push/fork the repository to GitHub
- On render.com: New Web Service → connect GitHub repo (Docker runtime)
- Set env
MCP_TRANSPORT=streamable-httpandMCP_HOST=0.0.0.0 - In claude.ai under Settings → MCP Servers, add:
https://your-app.onrender.com/mcp
💡 "stdio for the developer laptop, Streamable HTTP for the cloud."
Scaling horizontally: run with MCP_STATELESS=1. In stateless mode the
server keeps no per-session state, so any instance can serve any request and a
plain round-robin load balancer suffices — no sticky sessions / Mcp-Session-Id
affinity required. If you need stateful streaming instead, route by
Mcp-Session-Id at the edge LB (e.g. HAProxy stick-tables) so each session
stays pinned to one instance.
⚠️ Binding: In a network transport the server binds to
127.0.0.1by default so a locally started server is not exposed to your whole network (e.g. public Wi-Fi). SetMCP_HOST=0.0.0.0only in a container/cloud environment where binding to all interfaces is intended (the Docker image does this for you).
Available Tools
Core Tools (OJP 2.0 / CKAN)
¹ CKAN tools require a separate subscription in the API Manager.
Extension Tools (optional API keys)
Example Use Cases
Architecture
Infrastructure Components
Caching Strategy
Project Structure
Safety & Limits
- Read-only: All tools perform read-only requests (HTTP GET / OJP XML POST for queries only) — no data is written, modified, or deleted on any upstream system.
- No personal data: Journey queries are transient and not stored by this server. The APIs return scheduled timetable and real-time operational data. No personally identifiable information (PII) is processed or retained.
- Rate limits: opentransportdata.swiss enforces per-key rate limits (documented in the API Manager). The server's built-in
RateLimiter(SIRI-SX: 2 req/min, Formation/OJP Fare: 5 req/min) stays within these bounds automatically. Use thelimitparameters conservatively for bulk queries. - API key required: A free key from api-manager.opentransportdata.swiss is mandatory. Keys are bound to your account's subscription — only subscribe to APIs you intend to use.
- Data freshness: Real-time tools (departures, disruptions, occupancy) reflect the upstream source at query time. The server caches responses for short TTLs (120s–1800s) to reduce API load — see the Caching Strategy table above.
- Terms of service: Data is subject to the ToS of opentransportdata.swiss. OJP, SIRI-SX, and the CKAN catalogue are published under open licences (ODbL / CC BY 4.0) for non-commercial and research use.
- No guarantees: This server is a community project, not affiliated with the Federal Office of Transport (BAV/OFT) or SBB. Availability depends on upstream APIs.
Before you install (consent)
Adding this server to your MCP client lets the connected AI model issue Swiss
public-transport queries on your behalf, using your opentransportdata.swiss
API key, and make outbound HTTPS requests to opentransportdata.swiss. Nothing
is written upstream and no PII is stored, but you should review the tool list
above and confirm you are comfortable granting that access before configuring
the server.
Running the HTTP transport safely (no built-in auth)
The server has no authentication of its own. When you run the Streamable
HTTP transport (MCP_TRANSPORT=streamable-http), the MCP SDK issues a
cryptographically random Mcp-Session-Id per session, but there is no user
identity bound to it. Therefore:
- Do not expose a no-auth instance directly to the public internet. Put it behind an authenticating reverse proxy (OAuth2 proxy, mTLS, or your platform's access control), or restrict it to a trusted network.
- Keep the default
MCP_HOST=127.0.0.1for local use; only bind0.0.0.0inside a controlled container/cloud environment (see Deployment). - Scope
MCP_CORS_ORIGINSto the origins you actually trust. - Set
MCP_ALLOWED_HOSTSwhenever you bind beyond loopback. It guards against DNS rebinding: a page on your network resolves its own hostname to this server's address and then talks to it from the browser. CORS does not stop that — from the browser's point of view the request is same-origin — and neither would a token, since the attacking page runs in a context that holds one. Only theHostcheck does. Left unset the check stays off, which is the right default only when something in front of the server validatesHost.
See SECURITY.md for the full security posture and the
accepted-risk decisions (gateway-level controls).
Known Limitations
- OJP Fare: Discounts (Halbtax, GA, regional passes) are not always reflected
- Formation: Stop-based data is only available for TODAY (real-time dependency)
- Occupancy: SBB, BLS, Thurbo and SOB only – no private railways
- SIRI-SX: Returns ALL Swiss disruptions → use the
filter_textparameter - CKAN: Requires a separate subscription in the API Manager
MCP Protocol Version
This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.
Both revisions are pinned in
tests/test_protocol_version.py and asserted
against the installed SDK, so a Dependabot bump of mcp cannot move either one
silently. That pin says which revisions the SDK offers.
That the server actually serves them is measured in
tests/test_modern_wire.py, against the very app
main() hands to uvicorn: real 2026-07-28 single-exchange POSTs — no
initialize, no Mcp-Session-Id — for server/discover, tools/list and a
tools/call, the three rejection rungs (missing envelope, routing header
disagreeing with the body, unserved revision), and a legacy initialize on the
same endpoint to show both eras coexist.
An earlier version of this section claimed the repo built no ASGI app to send a request through, and offered that as the reason the gate could only assert constants. It did build one.
Server identity. 2026-07-28 has no initialize, and so no single place
where a client reads serverInfo. The revision puts the Implementation
(name, title, version, website) into server/discover and into the _meta
of every result instead. This server fills those from its own distribution
metadata, so the version on the wire is the version that was installed — it
cannot drift from pyproject.toml.
Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern
era, not for the handshake era — pinning against it alone would leave the era
that current clients actually negotiate free to drift.
Update policy. When the gate fails, do not edit the constant blindly: read
the spec changelog between the two revisions, verify the server still behaves,
then move the constant, this section, README.de.md and
CHANGELOG.md together.
Testing
Where the test data comes from
All four upstream APIs need a Bearer token from the opentransportdata.swiss
API-Manager, so CI cannot record a real response — measured and kept in
tests/fixtures/upstream_auth_probe.json. The XML payloads in the test modules
are therefore hand-written, not recorded, and cannot refute the production
code: both come from the same reading of the docs, and where both are wrong
they are wrong together.
What can be recorded is the contract. OJP 2.0 is a CEN standard
(CEN/TS 17118) with a public XML schema, and tests/fixtures/ojp_2_0_contract.json
is a dated index derived from it — element names, the structures this server
builds on, the enumerations it sends as values, plus the SHA-256 of every
schema file read. tests/test_ojp_contract.py holds the requests and parsers
against it. The schema itself is deliberately not vendored: the source
repository carries no licence file.
Source, date, selection rule and hashes: tests/fixtures/PROVENANCE.md.
Changelog
See CHANGELOG.md
Contributing
See CONTRIBUTING.md
Security
See SECURITY.md (Deutsch) for the security posture and how to report a vulnerability.
License
MIT License — see LICENSE
Author
Hayal Oezkan · github.com/malkreide
Credits & Related Projects
- Data: opentransportdata.swiss – Federal Office of Transport (FOT/BAV)
- Protocol: Model Context Protocol – Anthropic / Linux Foundation
- Related: zurich-opendata-mcp – MCP server for Zurich city open data
- Portfolio: Swiss Public Data MCP Portfolio
Installation
Run via uv's uvx — no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):
来源:README.md,提交 a2f21b5
工具
0版本历史
2- v0.5.0最新Sep 26, 2026
- v0.4.0Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分