Swiss Road Mobility Mcp

io.github.malkreide由 GitHub 帳號 malkreide 發布v0.6.1更新於 Oct 24, 2026

GBFS shared mobility, EV charging, DATEX II traffic, Park & Rail

概覽

AI 產生的概覽

為助理提供瑞士道路交通行動力資料:共享運具、充電樁、交通事件、Park & Rail、地理編碼與多運具行程規劃。

可以做什麼
  • 尋找附近的共享單車、電動滑板車與汽車,依名稱搜尋共享站點,並列出瑞士共享運具業者
  • 定位電動車充電站並查詢即時可用狀況
  • 讀取交通事故、施工與壅塞資訊,查詢車輛計數站資料
  • 尋找 SBB Park & Rail 停車轉乘設施,並規劃汽車、停車轉乘與大眾運輸的組合行程
  • 對瑞士地址進行地理編碼、將座標反查為官方地址,並查詢道路分類
  • 產生某地點的行動力概況快照,並檢查伺服器與 API 健康狀態
適用情境
適合在瑞士開車出行時查詢停車、充電、共享運具或路況資訊,或把開車與鐵路轉乘結合起來規劃行程。也適用於詢問某條高速公路的事故狀況,或某個瑞士地址、車站周邊的交通選項。
執行需求
本機 Python 3.11+ 程序,通常以 uvx 或 pip 執行。多數工具不需金鑰;DATEX II 交通類工具需要來自 opentransportdata.swiss 的 OPENTRANSPORTDATA_API_KEY。需要連線至瑞士公開資料 API 的網路。選用的 HTTP/SSE 部署使用 MCP_AUTH_TOKEN、MCP_RATE_LIMIT 與 ALLOWED_ORIGINS。
安裝前請注意
交通類工具需要免費的 OPENTRANSPORTDATA_API_KEY,以環境變數方式傳入,並受合理使用條款約束。工具宣稱為唯讀 GET 請求,但位置座標會傳送給第三方瑞士公開資料 API。公開暴露的 HTTP/SSE 端點若未設定 MCP_AUTH_TOKEN 則無驗證。快取資料可能與即時路況有落差。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Swiss Road Mobility Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

🇨🇭 Part of the Swiss Public Data MCP Portfolio

🚗 Swiss Road & Mobility MCP Server

[Version] [License: MIT] [Python 3.11+] [MCP] [CI]

MCP Server for Swiss road mobility — shared vehicles, EV charging, traffic alerts, Park & Rail, and multimodal trip planning

🇩🇪 Deutsche Version


Demo

[Demo: Claude using road_mobility_snapshot at Zürich HB]


Overview

swiss-road-mobility-mcp provides AI-native access to Swiss road and mobility data sources:

SourceDataAPIAuth
sharedmobility.chBikes, e-scooters, cars (GBFS)REST/JSONNone
ich-tanke-strom.chEV charging stationsGeoJSONNone
opentransportdata.swissTraffic events, counting stationsDATEX II / SOAP+XMLFree key
data.sbb.chPark & Rail facilitiesREST/JSON (Opendatasoft)None
transport.opendata.chPublic transport connectionsREST/JSONNone
geo.admin.chAddress geocoding, road classificationREST/JSONNone

If the Swiss Transport MCP is the GA pass for rail, this server is the vignette + Park & Rail card + sharing subscription for the road — together they paint the complete multimodal picture of Swiss mobility.

Anchor demo query: "I'm in Dietikon with my car. I need to get to Bern. Where can I park? Which train should I take?"


Features

  • 15 tools across six data sources (Phase 1–4)
  • road_mobility_snapshot — aggregated mobility overview for any location
  • road_multimodal_plan — car + Park & Rail + public transport in one plan
  • No API key required for 12 of 15 tools
  • Dual transport — stdio (Claude Desktop) + SSE (cloud)
  • Rate limiting + caching for all endpoints

Prerequisites

  • Python 3.11+
  • uv (recommended) or pip

Installation

bash
# Clone the repositorygit clone https://github.com/malkreide/swiss-road-mobility-mcp.gitcd swiss-road-mobility-mcp
# Installpip install -e .# or with uv:uv pip install -e .

Or with uvx (no permanent installation):

bash
uvx swiss-road-mobility-mcp

Quickstart

bash
# stdio (for Claude Desktop)swiss-road-mobility-mcp# or:python -m swiss_road_mobility_mcp.server
# Streamable HTTP (for cloud / Render.com) — serves MCP 2026-07-28 at /mcp# and keeps the legacy SSE routes alongside.MCP_TRANSPORT=http MCP_PORT=8001 swiss-road-mobility-mcp

Try it immediately in Claude Desktop:

"Show me everything mobility-related at Zurich HB." "Find shared bikes near Bern Bahnhof." "Where can I charge my EV near Lucerne?"

→ More use cases by audience →


Configuration

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

json
{  "mcpServers": {    "swiss-road-mobility": {      "command": "uvx",      "args": ["swiss-road-mobility-mcp"],      "env": {        "OPENTRANSPORTDATA_API_KEY": "<your-token>"      }    }  }}

Or with python:

json
{  "mcpServers": {    "swiss-road-mobility": {      "command": "python",      "args": ["-m", "swiss_road_mobility_mcp.server"],      "env": {        "OPENTRANSPORTDATA_API_KEY": "<your-token>"      }    }  }}

Shared mobility, EV charging, Park & Rail, and the multimodal planner work without an OPENTRANSPORTDATA_API_KEY. The key is only required for the DATEX II traffic tools.

Config file locations:

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

Cloud Deployment (SSE for browser access)

For use via claude.ai in the browser (e.g. on managed workstations without local software):

Render.com (recommended):

  1. Push/fork the repository to GitHub
  2. On render.com: New Web Service -> connect GitHub repo
  3. Set start command: MCP_TRANSPORT=http MCP_PORT=8001 swiss-road-mobility-mcp
  4. In claude.ai under Settings -> MCP Servers, add https://your-app.onrender.com/mcp — or .../sse for a client that still speaks the SSE transport; http serves both.
SSE security (SEC-009)

A public SSE endpoint is reachable by anyone. To protect it (and your upstream API quota), configure these environment variables on the host:

VariableEffect
MCP_AUTH_TOKENWhen set, every SSE request must send Authorization: Bearer <token>. Unset = unauthenticated (the server logs a loud warning at startup). Strongly recommended for any public deployment.
MCP_RATE_LIMITMax requests per client IP per window (default 60, 0 disables).
MCP_RATE_WINDOWWindow length in seconds (default 60).
ALLOWED_ORIGINSComma-separated CORS origins for browser clients. Empty by default: no cross-origin access. * allows any origin and is logged as a warning. Does not affect stdio or other non-browser clients.

The local stdio transport needs none of this — it runs in the user's trusted context.

Observability (OBS-003 / OBS-006)
VariableEffect
MCP_LOG_LEVELLog level: DEBUG / INFO (default) / WARNING / ERROR.
MCP_LOG_FORMATtext (default) or json for structured logs. All logs go to stderr.
MCP_TRACING_ENABLEDtrue enables OpenTelemetry tracing (off by default).
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector URL; setting it also enables tracing. Standard OTEL_* vars are honoured by the SDK.

Tracing needs the optional extra: pip install 'swiss-road-mobility-mcp[tracing]'. Once enabled, every upstream API call is traced automatically (httpx instrumentation) and SSE requests get server spans with W3C trace-context propagation.


Available Tools

Shared Mobility & EV Charging (no API key required)

ToolDescriptionCache
road_find_sharingShared mobility nearby (bikes, e-scooters, cars)60s
road_search_sharingSearch sharing stations by name5min
road_sharing_providersAll sharing providers in Switzerland1h
road_find_chargerEV charging stations nearby5min
road_charger_statusReal-time availability of charging stations1min
road_check_statusServer & API health check-

Traffic (free API key required)

ToolDescriptionCache
road_traffic_situationsAccidents, roadworks, congestion from ASTRA/VMZ-CH2min
road_traffic_countersVehicles/h + km/h at counting stations near a position1min
road_counter_sitesList counting stations nearby24h

Park & Rail + Multimodal (no API key required)

ToolDescriptionCache
road_park_railFind SBB Park+Rail facilities nearby5min
road_mobility_snapshotComplete mobility overview for a location-
road_multimodal_planPlan car -> Park+Rail -> public transport -> destination-

Geography & Addresses — Phase 4 (no API key required)

ToolDescriptionCache
road_geocode_addressSwiss address -> GPS (official building address register)-
road_reverse_geocodeGPS -> official address with EGID/EGAID (GWR)-
road_classify_roadRoad classification via swissTLM3D-

Example Use Cases

QueryTool
"Find shared bikes near Zurich HB"road_find_sharing
"Where can I charge my EV near Bern?"road_find_charger
"Any traffic incidents on the A1?"road_traffic_situations
"Where can I park near Winterthur station?"road_park_rail
"Plan my trip from Dietikon to Bern by car + train"road_multimodal_plan

API Key for Traffic Tools

  1. Register: https://api-manager.opentransportdata.swiss
  2. Create a new application -> subscribe to the "Strassenverkehr" API
  3. Copy the token
bash
export OPENTRANSPORTDATA_API_KEY=<your-token>

Without a key, the traffic tools return a descriptive error message including the exact registration link — no crash.


Architecture

swiss_road_mobility_mcp/├── server.py             # FastMCP server, 15 tools├── api_infrastructure.py # Rate limiter, cache, HTTP client, geo utilities├── shared_mobility.py    # sharedmobility.ch├── ev_charging.py        # ich-tanke-strom.ch├── traffic_situations.py # DATEX II traffic alerts (SOAP/XML)├── traffic_counters.py   # DATEX II counting stations (SOAP/XML)├── park_rail.py          # SBB Open Data Park & Rail├── multimodal.py         # Snapshot + trip planner (cross-source)└── geo_admin.py          # geo.admin.ch geocoding + road classification

Data Source Characteristics

SourceProtocolCoverageAuth
sharedmobility.chREST/JSON (GBFS)All CH sharing providersNone
ich-tanke-strom.chGeoJSONAll public EV chargersNone
opentransportdata.swissDATEX II / SOAP+XMLASTRA traffic dataFree key
data.sbb.chREST/JSON (Opendatasoft)SBB Park & RailNone
transport.opendata.chREST/JSONPublic transport schedulesNone
geo.admin.chREST/JSONOfficial addresses, roadsNone

In-depth docs: docs/ARCHITECTURE.md (MCP primitives, tool namespacing, use-case catalogue, phase roadmap) · docs/SECURITY.md (credential model, egress allow-list, auth, MCP conformance table) · docs/OPERATIONS.md (resource limits, restart policy, health).


Project Structure

swiss-road-mobility-mcp/├── src/swiss_road_mobility_mcp/│   ├── __init__.py              # Package│   ├── server.py                # FastMCP server, 15 tools│   ├── api_infrastructure.py    # Rate limiter, cache, HTTP client│   ├── shared_mobility.py       # Shared vehicles│   ├── ev_charging.py           # EV charging stations│   ├── traffic_situations.py    # Traffic events│   ├── traffic_counters.py      # Vehicle counting│   ├── park_rail.py             # Park & Rail│   ├── multimodal.py            # Snapshot + trip planning│   └── geo_admin.py             # Geocoding + roads├── tests/│   ├── test_integration.py      # Live API tests│   └── test_phase3.py           # Park & Rail + multimodal tests├── .github/workflows/ci.yml     # GitHub Actions (Python 3.11/3.12/3.13)├── pyproject.toml├── CHANGELOG.md├── CONTRIBUTING.md               # Contribution guide (English)├── CONTRIBUTING.de.md            # Contribution guide (German)├── SECURITY.md                   # Security policy (English)├── SECURITY.de.md                # Security policy (German)├── LICENSE├── README.md                    # This file (English)└── README.de.md                 # German version

Known Limitations

  • Shared Mobility: The sharedmobility.ch API does not enforce strict radius filtering; vehicles slightly outside the specified radius may appear
  • EV Charging: Station naming conventions vary between operators; some stations may appear without detailed names
  • Traffic (DATEX II): Requires a free API key; without it, traffic tools return helpful error messages
  • Park & Rail: SBB occasionally renames endpoints; the server includes a fallback chain
  • Multimodal Planner: Response time depends on the slowest of the queried sources

MCP Protocol Version

This server speaks two protocol eras. The client's first request on a connection decides which one applies; a later claim from the other era is refused.

EraRevisionWho reaches it
initialize handshake2024-11-05 … 2025-11-25What today's clients speak. The server answers with the revision asked for, or with the 2025-11-25 ceiling when the request asks for something newer.
Per-request envelope2026-07-28A request carrying the 2026-07-28 _meta envelope opens a modern connection.

The era depends on the transport, not only on the request. An earlier version of this section said "over the same endpoint", and that was wrong in a way nothing caught: the modern single-exchange delivery lives behind StreamableHTTPSessionManager, which only the Streamable HTTP app reaches. The shipped transport was SSE, and SSE requires a session while a modern request is session-less by construction.

MCP_TRANSPORTEndpointHandshake era2026-07-28
stdio (default)–yesyes
http/mcp, plus /sse + /messages/ alongsideyesyes
sse (legacy)/sse + /messages/yesno

MCP_TRANSPORT=http serves both: the SSE routes run next to /mcp rather than being replaced, so an existing client does not break because the server gained a revision. Containers (Dockerfile, docker-compose.yml, render.yaml) ship http.

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. Since that gate can only read SDK constants, tests/test_spec_2026_07_28.py sits next to it and measures the wire instead: a real 2026-07-28 envelope against the assembled ASGI app, with the same envelope against SSE as the counter-control.

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

bash
# All testspytest tests/ -v
# Quick check (without pytest)python tests/test_phase3.py

Safety & Limits

  • Read-only: All tools perform HTTP GET requests only — no data is written, modified, or deleted on any upstream system.
  • No personal data: Location coordinates passed as tool inputs are not stored, logged, or forwarded beyond the immediate API request. API responses contain no PII — only vehicle counts, charger availability, traffic events, and geographic metadata.
  • Rate limiting: The server enforces client-side rate limits (Shared Mobility: 30 req/60s; EV Charging: 10 req/60s) to protect upstream APIs. The DATEX II key is subject to opentransportdata.swiss fair-use terms.
  • Caching: Responses are cached in-process (Sharing: 60s · EV: 5 min · Park+Rail: 5 min · Traffic: 1–2 min). Real-time data reflects the cache age, not necessarily the current second.
  • Terms of service: Data is subject to the ToS of each upstream source — sharedmobility.ch, ich-tanke-strom.ch, opentransportdata.swiss, data.sbb.ch (CC BY), geo.admin.ch (BGDI).
  • No guarantees: This server is an independent community project, not affiliated with SBB, ASTRA, sharedmobility.ch, or any API provider. Availability depends on upstream services.

Changelog

See CHANGELOG.md


Contributing

See CONTRIBUTING.md


Security

See SECURITY.md for the security posture and vulnerability reporting.


License

MIT License — see LICENSE


Author

Hayal Oezkan · malkreide


Credits & Related Projects

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):

json
{  "mcpServers": {    "swiss-road-mobility-mcp": {      "command": "uvx",      "args": [        "swiss-road-mobility-mcp"      ]    }  }}

來源:README.md,提交 74460ff

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

3
  1. v0.6.1最新Oct 14, 2026
  2. v0.6.0Sep 27, 2026
  3. v0.5.4Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分