Zurich Open Data MCP Server
About
Enables Claude, ChatGPT, and other MCP-compatible AI assistants to directly query 900+ datasets, geodata, parliamentary proceedings, tourism data, linked data, and real-time environmental and mobility information from the City of Zurich. 20 Tools, 6 Resources, 6 APIs.
Details
- Author
- malkreide
- Categories
- Database, Other, AI
Jump to
Setup
Install Zurich Open Data MCP Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/malkreide/zurich-opendata-mcp
Follow the installation instructions in the repository README, then restart your MCP client.
Enables Claude, ChatGPT, and other MCP-compatible AI assistants to directly query 900+ datasets, geodata, parliamentary proceedings, tourism data, linked data, and real-time environmental and mobility information from the City of Zurich. 20 Tools, 6 Resources, 6 APIs.
🇨🇭Part of theSwiss Public Data MCP Portfolio
An MCP (Model Context Protocol) server providing AI-powered access toOpen Data from the City of Zurich, Switzerland.
Enables Claude, ChatGPT, and other MCP-compatible AI assistants to directly query 900+ datasets, geodata, parliamentary proceedings, council resolutions, tourism data, linked data, and real-time environmental and mobility information from the City of Zurich.23 Tools (+3 deprecated aliases), 5 Resources, 6 APIs.
- zurich_search_datasets– Full-text search with Solr syntax across 900+ datasets
- zurich_get_dataset– Complete metadata and download URLs for a dataset
- zurich_datastore_query– Query tabular data directly (filters, sorting)
- zurich_datastore_sql– SQL queries on the DataStore
- zurich_list_categories– Browse 19 thematic categories
- zurich_list_tags– Tag-based thematic search
- zurich_weather_live– 🌤️ Current weather (temperature, humidity, pressure, rain) from 4 UGZ stations
- zurich_air_quality– 🌬️ Live air quality (NO₂, O₃, PM10, PM2.5) with WHO thresholds
- zurich_water_weather– 🌊 Lake Zurich data (water temperature, level, wind) every 10 min
- zurich_pedestrian_traffic– 🚶 Pedestrian counts on Bahnhofstrasse (3 locations, hourly)
- zurich_vbz_passengers– 🚊 VBZ public transit ridership (800,000+ records, all lines/stops)
- zurich_parking_live– 🅿️ Real-time occupancy of 36 parking garages (ParkenDD)
- zurich_geo_layers– 📍 List 14 available geodata layers
- zurich_geo_features– 📍 Fetch GeoJSON features (schools, districts, playgrounds, climate data, etc.)
- zurich_parliament_search– 🏛️ Search parliamentary proceedings (interpellations, motions, postulates)
- zurich_parliament_members– 🏛️ Search council members (party, commissions, mandates)
- zurich_tourism– 🏨 Attractions, restaurants, hotels, events (Schema.org data, 4 languages)
- zurich_sparql– 📊 SPARQL queries on the statistical linked data endpoint(endpoint not productive yet — the tool isnot registered by default; opt in with the environment variableZURICH_OPENDATA_ENABLE_SPARQL=1)
Stadtratsbeschlüsse (Council Resolutions)
- zurich_strb_search– 📜 Full-text search of public council resolutions (title, department, date range)
- zurich_strb_by_department– 📜 List all resolutions of a department (e.g.SSD,FD,PRD)
- zurich_strb_detail– 📜 Single resolution byNNNN/YYYYnumber
(The former namessearch_stadtratsbeschluesse,get_beschluesse_by_departementandget_stadtratsbeschluss_detailremain available as deprecated aliases until the next major release.)
- zurich_analyze_datasets– Comprehensive analysis: relevance, recency, data structure
- zurich_catalog_stats– Catalog overview with statistics
- zurich_find_school_data– Curated search for education-related datasets
- zurich://dataset/{name}– Dataset metadata
- zurich://category/{group_id}– Category details
- zurich://parking– Current parking data
- zurich://geo/{layer_id}– GeoJSON geodata (14 layers)
- zurich://tourism/categories– Tourism categories
- Python 3.11+
- pip or uv
- mcp[cli]2.x — installed automatically; the server uses the 2.x API (mcp.server.mcpserver) and cannot run onmcp1.x
Use 0.6.0 or newer.Release0.5.1declaredmcp[cli]>=1.28.1with no upper bound. Oncemcp2.0.0 removedmcp.server.fastmcp, every fresh install of0.5.1resolved to 2.0.0 and failed at import withModuleNotFoundError.0.6.0runs on the 2.x API and pins>=2.0.0,<3. If you are pinned to0.5.1, upgrade — there is no working configuration of that release left.
# Clone git clone https://github.com/malkreide/zurich-opendata-mcp.git cd zurich-opendata-mcp # Install pip install -e . # Or with uv uv pip install -e .
Edit~/Library/Application Support/Claude/claude_desktop_config.json(macOS):
{ "mcpServers": { "zurich-opendata": { "command": "python", "args": ["-m", "zurich_opendata_mcp.server"], "env": {} } } }
Alternatively, using the installed command:
{ "mcpServers": { "zurich-opendata": { "command": "zurich-opendata-mcp" } } }
claude mcp add zurich-opendata -- python -m zurich_opendata_mcp.server
{ "mcpServers": { "zurich-opendata": { "command": "python", "args": ["-m", "zurich_opendata_mcp.server"] } } }
- "What datasets are available about schools in Zurich?"
- "Show me school holidays for public schools"
- "Analyze the available geodata"
- "What's the current temperature in Zurich?"→zurich_weather_live
- "How is the air quality today?"→zurich_air_quality
- "What's the water temperature in Lake Zurich?"→zurich_water_weather
- "How many parking spaces are free right now?"→zurich_parking_live
- "How many people are on Bahnhofstrasse right now?"→zurich_pedestrian_traffic
- "Show me all school facilities in Zurich as GeoJSON"→zurich_geo_features
- "What geodata layers are available?"→zurich_geo_layers
- "Where are the playgrounds in Zurich?"
- "What parliamentary motions about schools were filed?"→zurich_parliament_search
- "Which council members belong to the SP party?"→zurich_parliament_members
Council Resolutions (Stadtratsbeschlüsse)
- "Find council resolutions about Volksschule from 2025"→zurich_strb_search
- "List all SSD resolutions in 2025"→zurich_strb_by_department
- "Show council resolution 1203/2025"→zurich_strb_detail
- "What restaurants does Zurich Tourism recommend?"→zurich_tourism
Source of truth:GEOPORTAL_LAYERSinsrc/zurich_opendata_mcp/config.py.
zurich-opendata-mcp/ ├── src/zurich_opendata_mcp/ │ ├── __init__.py │ ├── app.py # Shared FastMCP instance │ ├── server.py # Console entry + back-compat re-exports │ ├── config.py # Endpoints, layer maps, resource IDs │ ├── http_client.py # Shared httpx client + CKAN wrapper │ ├── formatters.py # CKAN→model mapping + Markdown rendering │ ├── models.py # Pydantic structured-output models │ ├── clients/ # API clients: paris, sparql, tourism, wfs │ └── tools/ # @mcp.tool implementations: │ # catalog, datastore, geo, parliament, │ # realtime, sparql, strb, tourism, │ # resources (zurich:// URIs) ├── tests/ # respx round-trip, unit and live-marked tests ├── audits/ # Code-audit reports ├── .github/workflows/ # ci.yml + publish.yml (Trusted Publisher) ├── pyproject.toml ├── README.md / README.de.md ├── CONTRIBUTING.md / .de.md ├── SECURITY.md / .de.md ├── CHANGELOG.md ├── CLAUDE.md # Project conventions for Claude ├── LICENSE └── claude_desktop_config.json
# Install dev dependencies pip install -e ".[dev]" # Unit + validation tests (no network) pytest tests/ -m "not live" # Live integration tests (against live APIs — opt-in) pytest tests/ -m live # Linting ruff check src/ tests/
By default the server speaks MCP over stdio.--httpserves Streamable HTTP instead:
zurich-opendata-mcp --http --port 8000 # binds 127.0.0.1 (default) zurich-opendata-mcp --http --host 0.0.0.0 --port 8000
The loopback default is deliberate.Binding0.0.0.0exposes the server on every interface, to everyone who can reach the machine — there is no authentication in front of it.
SetMCP_ALLOWED_HOSTSwhenever you bind beyond loopback.It guards againstDNS rebinding: a page on your network resolves its own hostname to this server's address and then talks to it from the browser. From the browser's point of view that request is same-origin, so no origin rule stops it — only theHostcheck does.
Left unset on a non-loopback bind, the check staysoffand a warning is logged. That is the right default only when something in front of the server validatesHost. It is deliberately not guessed: on0.0.0.0the reachable name is unknowable inside the process, and a wrong guess would answer the very deployment it is meant to protect with 421 on every request.
- Read-only:All tools perform HTTP GET requests only — no data is written, modified, or deleted.
- No personal data:The APIs return open civic datasets (parking occupancy, weather readings, parliamentary proceedings). No personally identifiable information (PII) is processed or stored by this server.
- Rate limits:CKAN Solr search and ParkenDD are public APIs without documented rate limits; userowsandlimitparameters conservatively. The server enforces a 30s timeout per request; transient upstream errors (connect failures, HTTP 502/503/504) are retried once with a short backoff.
- Data freshness:Real-time tools (parking, weather, air quality) reflect the upstream source at query time. Measurement data is never cached; only the lookup of the current per-year UGZ resource ID (weather/air quality) is cached in-process for 24h.
- Terms of service:Data is subject to the ToS of each source —data.stadt-zuerich.ch,ParkenDD,gemeinderat-zuerich.ch. All City of Zurich data is published under CC0 (Open by Default since 2021).
- No guarantees:This server is a community project, not affiliated with the City of Zurich or any of the API providers. Availability depends on upstream APIs.
Contributions are welcome — seeCONTRIBUTING.md(Deutsch).
Read-only, no PII, no authentication, a fixed set of public-data endpoints. SeeSECURITY.md(Deutsch) for the full security posture and accepted-risk decisions.
MIT License — seeLICENSE. All data used is published under open licenses (CC0 / Open by Default since 2021).
Powered byModel Context Protocol• 6 APIs • 23 Tools • 5 Resources
{ "mcpServers": { "zurich-opendata-mcp": { "command": "uvx", "args": [ "zurich-opendata-mcp" ] } } }
614 million contacts, live SMTP-verified. Invalid emails cost you $0. Connect Argorant with any Agent through CLI, MCP or API and build verified lists in Claude, GPT or Hermes.
Cactal is the website platform for AI agents. Connect Claude Code, Cursor, or anything that speaks MCP, and your agent gets the tools to design, build, host, and operate production websites: source code, CMS, assets, domains, analytics, and publishing.
Chinese writing toolbox for Claude Code: text analysis, outline generation, GB/T 7714 references,character frequency
A local MCP server that gives Claude Code, Cursor and Codex read access to your DynamoDB schema and items, with every write staged for human review.
Enables persistent knowledge storage for Claude using a knowledge graph with multiple database backends like PostgreSQL and SQLite.
Enables persistent memory for Claude using a knowledge graph stored in local JSON files.
Biologically-inspired memory for Claude. Hebbian plasticity, dream cycles, and temporal decay for persistent knowledge synthesis.
A Model Context Protocol (MCP) server that provides AI assistants (like Claude) with tools to directly interact with PostgreSQL databases securely.
Persistent memory for any AI assistant. Zero token cost until recall. Stores memories in local SQLite, ranks by 6-factor scoring, returns results 79% smaller than JSON. Works with Claude, ChatGPT, Grok, Cursor, Windsurf, and any MCP client.
An MCP server for AI video generation. MCP server for AI video generation. Lets Claude, ChatGPT, OpenClaw , Hermes & other agents create AI videos and publish them to YouTube, TikTok, Instagram etc..
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





