Connects Claude to Switzerland's road and mobility infrastructure through six official data sources. Exposes 15 tools covering GBFS shared mobility feeds (bikes, scooters, cars), EV charging station locations and real-time availability, DATEX II traffic incidents from ASTRA, vehicle counting stations, SBB Park & Rail facilities, and Swiss address geocoding via geo.admin.ch. The standout tools are road_mobility_snapshot for aggregated views and road_multimodal_plan for combined car-to-train journey planning. Most tools work without authentication; only the traffic event feeds need a free opentransportdata.swiss API key. Supports both stdio for Claude Desktop and SSE for browser deployments with rate limiting and auth token protection built in.
🇨🇭 Part of the Swiss Public Data MCP Portfolio
MCP Server for Swiss road mobility — shared vehicles, EV charging, traffic alerts, Park & Rail, and multimodal trip planning
swiss-road-mobility-mcp provides AI-native access to Swiss road and mobility data sources:
| Source | Data | API | Auth |
|---|---|---|---|
| sharedmobility.ch | Bikes, e-scooters, cars (GBFS) | REST/JSON | None |
| ich-tanke-strom.ch | EV charging stations | GeoJSON | None |
| opentransportdata.swiss | Traffic events, counting stations | DATEX II / SOAP+XML | Free key |
| data.sbb.ch | Park & Rail facilities | REST/JSON (Opendatasoft) | None |
| transport.opendata.ch | Public transport connections | REST/JSON | None |
| geo.admin.ch | Address geocoding, road classification | REST/JSON | None |
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?"
road_mobility_snapshot — aggregated mobility overview for any locationroad_multimodal_plan — car + Park & Rail + public transport in one plan# Clone the repository
git clone https://github.com/malkreide/swiss-road-mobility-mcp.git
cd swiss-road-mobility-mcp
# Install
pip install -e .
# or with uv:
uv pip install -e .
Or with uvx (no permanent installation):
uvx swiss-road-mobility-mcp
# stdio (for Claude Desktop)
swiss-road-mobility-mcp
# or:
python -m swiss_road_mobility_mcp.server
# SSE (for cloud / Render.com)
MCP_TRANSPORT=sse 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 →
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"swiss-road-mobility": {
"command": "uvx",
"args": ["swiss-road-mobility-mcp"],
"env": {
"OPENTRANSPORTDATA_API_KEY": "<your-token>"
}
}
}
}
Or with python:
{
"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:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonFor use via claude.ai in the browser (e.g. on managed workstations without local software):
Render.com (recommended):
MCP_TRANSPORT=sse MCP_PORT=8001 swiss-road-mobility-mcphttps://your-app.onrender.com/sseA public SSE endpoint is reachable by anyone. To protect it (and your upstream API quota), configure these environment variables on the host:
| Variable | Effect |
|---|---|
MCP_AUTH_TOKEN | When 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_LIMIT | Max requests per client IP per window (default 60, 0 disables). |
MCP_RATE_WINDOW | Window length in seconds (default 60). |
ALLOWED_ORIGINS | Comma-separated CORS origins for browser clients (default *). |
The local stdio transport needs none of this — it runs in the user's trusted context.
| Variable | Effect |
|---|---|
MCP_LOG_LEVEL | Log level: DEBUG / INFO (default) / WARNING / ERROR. |
MCP_LOG_FORMAT | text (default) or json for structured logs. All logs go to stderr. |
MCP_TRACING_ENABLED | true enables OpenTelemetry tracing (off by default). |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP 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.
| Tool | Description | Cache |
|---|---|---|
road_find_sharing | Shared mobility nearby (bikes, e-scooters, cars) | 60s |
road_search_sharing | Search sharing stations by name | 5min |
road_sharing_providers | All sharing providers in Switzerland | 1h |
road_find_charger | EV charging stations nearby | 5min |
road_charger_status | Real-time availability of charging stations | 1min |
road_check_status | Server & API health check | - |
| Tool | Description | Cache |
|---|---|---|
road_traffic_situations | Accidents, roadworks, congestion from ASTRA/VMZ-CH | 2min |
road_traffic_counters | Vehicles/h + km/h at counting stations near a position | 1min |
road_counter_sites | List counting stations nearby | 24h |
| Tool | Description | Cache |
|---|---|---|
road_park_rail | Find SBB Park+Rail facilities nearby | 5min |
road_mobility_snapshot | Complete mobility overview for a location | - |
road_multimodal_plan | Plan car -> Park+Rail -> public transport -> destination | - |
| Tool | Description | Cache |
|---|---|---|
road_geocode_address | Swiss address -> GPS (official building address register) | - |
road_reverse_geocode | GPS -> official address with EGID/EGAID (GWR) | - |
road_classify_road | Road classification via swissTLM3D | - |
| Query | Tool |
|---|---|
| "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 |
export OPENTRANSPORTDATA_API_KEY=<your-token>
Without a key, the traffic tools return a descriptive error message including the exact registration link — no crash.
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
| Source | Protocol | Coverage | Auth |
|---|---|---|---|
| sharedmobility.ch | REST/JSON (GBFS) | All CH sharing providers | None |
| ich-tanke-strom.ch | GeoJSON | All public EV chargers | None |
| opentransportdata.swiss | DATEX II / SOAP+XML | ASTRA traffic data | Free key |
| data.sbb.ch | REST/JSON (Opendatasoft) | SBB Park & Rail | None |
| transport.opendata.ch | REST/JSON | Public transport schedules | None |
| geo.admin.ch | REST/JSON | Official addresses, roads | None |
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).
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
sharedmobility.ch API does not enforce strict radius filtering; vehicles slightly outside the specified radius may appear# All tests
pytest tests/ -v
# Quick check (without pytest)
python tests/test_phase3.py
See CHANGELOG.md
See CONTRIBUTING.md
See SECURITY.md for the security posture and vulnerability reporting.
MIT License — see LICENSE
Hayal Oezkan · malkreide
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):
{
"mcpServers": {
"swiss-road-mobility-mcp": {
"command": "uvx",
"args": [
"swiss-road-mobility-mcp"
]
}
}
}