Skip to main content

MCP Server for Swiss road mobility โ€” shared vehicles, EV charging, traffic alerts, Park & Rail, multimodal trip planning

Project description

๐Ÿ‡จ๐Ÿ‡ญ 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:

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?"


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

# 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

Quickstart

# 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 โ†’


Configuration

Claude Desktop

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:

  • 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=sse MCP_PORT=8001 swiss-road-mobility-mcp
  4. In claude.ai under Settings -> MCP Servers, add: https://your-app.onrender.com/sse

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:

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.

Observability (OBS-003 / OBS-006)

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.


Available Tools

Shared Mobility & EV Charging (no API key required)

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 -

Traffic (free API key required)

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

Park & Rail + Multimodal (no API key required)

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 -

Geography & Addresses โ€” Phase 4 (no API key required)

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 -

Example Use Cases

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

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

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


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

Testing

# All tests
pytest 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swiss_road_mobility_mcp-0.5.3.tar.gz (127.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swiss_road_mobility_mcp-0.5.3-py3-none-any.whl (72.8 kB view details)

Uploaded Python 3

File details

Details for the file swiss_road_mobility_mcp-0.5.3.tar.gz.

File metadata

  • Download URL: swiss_road_mobility_mcp-0.5.3.tar.gz
  • Upload date:
  • Size: 127.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for swiss_road_mobility_mcp-0.5.3.tar.gz
Algorithm Hash digest
SHA256 6a2b4562fb366fbb156eba582e4a868e98a0bcb72ce5b8949816c6f79ad3ceb4
MD5 ed490bfbff784c1f45d83433fcde0430
BLAKE2b-256 ab54ae2059dbc0183bc8439e5a065de909abc26606994cf535e00dd98e2628b7

See more details on using hashes here.

File details

Details for the file swiss_road_mobility_mcp-0.5.3-py3-none-any.whl.

File metadata

File hashes

Hashes for swiss_road_mobility_mcp-0.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 35a460fce7f664987f34848ffe97d1363569b8407710f564d4c1b6c1593432e7
MD5 fb0e15be198b4992d801c0b526037f45
BLAKE2b-256 880c37691ef36e0614db922a9ed080123166bb9c297f292f8974f7f419d56abf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page