Zurich Open Data MCP Server
Permite a Claude, ChatGPT y otros asistentes de IA compatibles con MCP consultar directamente más de 900 conjuntos de datos, geodatos, actas parlamentarias, datos turísticos, datos enlazados e información ambiental y de movilidad en tiempo real de la Ciudad de Zúrich. 20 herramientas, 6 recursos, 6 API.
Documentación
🇨🇭 Parte del Portafolio Suizo de MCP de Datos Públicos
🏙️ Servidor MCP de Datos Abiertos de Zúrich
🌐 Español | Deutsch
Un servidor MCP (Protocolo de Contexto de Modelo) que proporciona acceso impulsado por IA a Datos Abiertos de la Ciudad de Zúrich, Suiza.
Permite a Claude, ChatGPT y otros asistentes de IA compatibles con MCP consultar directamente más de 900 conjuntos de datos, geodatos, actas parlamentarias, resoluciones del consejo, datos turísticos, datos enlazados e información ambiental y de movilidad en tiempo real de la Ciudad de Zúrich. 23 Herramientas (+3 alias obsoletos), 5 Recursos, 6 APIs.
Demo
✨ Características
Datos Abiertos CKAN (data.stadt-zuerich.ch)
zurich_search_datasets– Búsqueda de texto completo con sintaxis Solr en más de 900 conjuntos de datoszurich_get_dataset– Metadatos completos y URL de descarga para un conjunto de datoszurich_datastore_query– Consulta directa de datos tabulares (filtros, ordenación)zurich_datastore_sql– Consultas SQL en el DataStorezurich_list_categories– Explorar 19 categorías temáticaszurich_list_tags– Búsqueda temática basada en etiquetas
Datos Ambientales en Tiempo Real
zurich_weather_live– 🌤️ Clima actual (temperatura, humedad, presión, lluvia) de 4 estaciones UGZzurich_air_quality– 🌬️ Calidad del aire en vivo (NO₂, O₃, PM10, PM2.5) con umbrales de la OMSzurich_water_weather– 🌊 Datos del Lago de Zúrich (temperatura del agua, nivel, viento) cada 10 minutos
Datos de Movilidad en Tiempo Real
zurich_pedestrian_traffic– 🚶 Conteo de peatones en Bahnhofstrasse (3 ubicaciones, por hora)zurich_vbz_passengers– 🚊 Afluencia del transporte público VBZ (más de 800,000 registros, todas las líneas/paradas)zurich_parking_live– 🅿️ Ocupación en tiempo real de 36 estacionamientos (ParkenDD)
Geoportal (Geodatos WFS)
zurich_geo_layers– 📍 Listar 14 capas de geodatos disponibleszurich_geo_features– 📍 Obtener características GeoJSON (escuelas, distritos, parques infantiles, datos climáticos, etc.)
Parlamento de la Ciudad (API Paris)
zurich_parliament_search– 🏛️ Buscar actas parlamentarias (interpelaciones, mociones, postulados)zurich_parliament_members– 🏛️ Buscar miembros del consejo (partido, comisiones, mandatos)
Turismo de Zúrich
zurich_tourism– 🏨 Atracciones, restaurantes, hoteles, eventos (datos Schema.org, 4 idiomas)
Datos Enlazados (SPARQL)
zurich_sparql– 📊 Consultas SPARQL en el endpoint de datos enlazados estadísticos (el endpoint aún no está productivo — la herramienta no está registrada por defecto; actívela con la variable de entornoZURICH_OPENDATA_ENABLE_SPARQL=1)
Stadtratsbeschlüsse (Resoluciones del Consejo)
zurich_strb_search– 📜 Búsqueda de texto completo de resoluciones públicas del consejo (título, departamento, rango de fechas)zurich_strb_by_department– 📜 Listar todas las resoluciones de un departamento (p. ej.,SSD,FD,PRD)zurich_strb_detail– 📜 Resolución individual por númeroNNNN/YYYY
(Los nombres anteriores search_stadtratsbeschluesse, get_beschluesse_by_departement y get_stadtratsbeschluss_detail permanecen disponibles como alias obsoletos hasta la próxima versión principal.)
Herramientas de Análisis
zurich_analyze_datasets– Análisis integral: relevancia, actualidad, estructura de datoszurich_catalog_stats– Resumen del catálogo con estadísticaszurich_find_school_data– Búsqueda curada para conjuntos de datos relacionados con educación
Recursos MCP
zurich://dataset/{name}– Metadatos de conjuntos de datoszurich://category/{group_id}– Detalles de categoríaszurich://parking– Datos actuales de estacionamientozurich://geo/{layer_id}– Geodatos GeoJSON (14 capas)zurich://tourism/categories– Categorías turísticas
🚀 Instalación
Requisitos previos
- Python 3.11+
- pip o uv
mcp[cli]2.x — se instala automáticamente; el servidor utiliza la API 2.x (mcp.server.mcpserver) y no puede ejecutarse enmcp1.x
Use 0.6.0 o más reciente. La versión
0.5.1declarómcp[cli]>=1.28.1sin límite superior. Una vez quemcp2.0.0 eliminómcp.server.fastmcp, cada instalación nueva de0.5.1se resolvió a 2.0.0 y falló en la importación conModuleNotFoundError.0.6.0se ejecuta en la API 2.x y fija>=2.0.0,<3. Si está fijado a0.5.1, actualice — no queda ninguna configuración funcional de esa versión.
Instalar
# 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 .
⚙️ Configuración
Claude Desktop
Edite ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"zurich-opendata": {
"command": "python",
"args": ["-m", "zurich_opendata_mcp.server"],
"env": {}
}
}
}
Alternativamente, usando el comando instalado:
{
"mcpServers": {
"zurich-opendata": {
"command": "zurich-opendata-mcp"
}
}
}
Claude Code (CLI)
claude mcp add zurich-opendata -- python -m zurich_opendata_mcp.server
Cursor / VS Code
Agregue a .vscode/settings.json:
{
"mcpServers": {
"zurich-opendata": {
"command": "python",
"args": ["-m", "zurich_opendata_mcp.server"]
}
}
}
💬 Consultas de Ejemplo
Una vez configurado, puede preguntarle a Claude:
Datos Abiertos
- "¿Qué conjuntos de datos están disponibles sobre escuelas en Zúrich?"
- "Muéstrame las vacaciones escolares para escuelas públicas"
- "Analiza los geodatos disponibles"
Datos en Tiempo Real
- "¿Cuál es la temperatura actual en Zúrich?" →
zurich_weather_live - "¿Cómo está la calidad del aire hoy?" →
zurich_air_quality - "¿Cuál es la temperatura del agua en el Lago de Zúrich?" →
zurich_water_weather - "¿Cuántos espacios de estacionamiento están libres ahora mismo?" →
zurich_parking_live - "¿Cuántas personas hay en Bahnhofstrasse ahora mismo?" →
zurich_pedestrian_traffic
Geodatos
- "Muéstrame todas las instalaciones escolares en Zúrich como GeoJSON" →
zurich_geo_features - "¿Qué capas de geodatos están disponibles?" →
zurich_geo_layers - "¿Dónde están los parques infantiles en Zúrich?"
Parlamento de la Ciudad
- "¿Qué mociones parlamentarias sobre escuelas se presentaron?" →
zurich_parliament_search - "¿Qué miembros del consejo pertenecen al partido SP?" →
zurich_parliament_members
Resoluciones del Consejo (Stadtratsbeschlüsse)
- "Encuentra resoluciones del consejo sobre Volksschule de 2025" →
zurich_strb_search - "Lista todas las resoluciones SSD en 2025" →
zurich_strb_by_department - "Muestra la resolución del consejo 1203/2025" →
zurich_strb_detail
Turismo
- "¿Qué restaurantes recomienda Turismo de Zúrich?" →
zurich_tourism
🔗 Fuentes de Datos
| API | Endpoint | Datos |
|---|---|---|
| CKAN | data.stadt-zuerich.ch/api/3/ | Más de 900 conjuntos de datos abiertos |
| Geoportal WFS | ogd.stadt-zuerich.ch/wfs/geoportal | 14 capas de geodatos (GeoJSON) |
| API Paris | gemeinderat-zuerich.ch/api | Actas parlamentarias y miembros |
| Turismo de Zúrich | zuerich.com/en/api/v2/data | Atracciones, restaurantes, hoteles |
| SPARQL | ld.stadt-zuerich.ch/query | Datos enlazados abiertos / estadísticas |
| ParkenDD | api.parkendd.de/Zuerich | Ocupación de estacionamientos en tiempo real |
📊 Categorías de Datos Disponibles
| Categoría | ID |
|---|---|
| Empleo | arbeit-und-erwerb |
| Mapas Base | basiskarten |
| Construcción y Vivienda | bauen-und-wohnen |
| Población | bevolkerung |
| Educación | bildung |
| Energía | energie |
| Finanzas | finanzen |
| Ocio | freizeit |
| Salud | gesundheit |
| Delincuencia | kriminalitat |
| Cultura | kultur |
| Movilidad | mobilitat |
| Política | politik |
| Precios | preise |
| Asuntos Sociales | soziales |
| Turismo | tourismus |
| Medio Ambiente | umwelt |
| Administración | verwaltung |
| Economía | volkswirtschaft |
📍 Capas Geo Disponibles
Fuente de verdad: GEOPORTAL_LAYERS en src/zurich_opendata_mcp/config.py.
| ID de Capa | Descripción |
|---|---|
schulanlagen | Instalaciones escolares (jardines de infancia, escuelas, cuidado extraescolar) |
schulkreise | Límites de distritos escolares (polígonos) |
schulwege | Cruces de rutas escolares y puntos de peligro |
stadtkreise | Límites de distritos de la ciudad (polígonos) |
spielplaetze | Parques infantiles públicos |
kreisbuero | Oficinas de distrito de la ciudad |
sammelstelle | Puntos de recogida de residuos |
sport | Instalaciones deportivas |
klimadaten | Datos climáticos (raster, temperaturas, islas de calor) |
lehrpfade | Senderos educativos |
stimmlokale | Colegios electorales |
sozialzentrum | Centros sociales |
velopruefstrecken | Rutas de examen de bicicleta para escuelas |
familienberatung | Puntos de encuentro de asesoramiento familiar |
🏗️ Estructura del Proyecto
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
🧪 Desarrollo
# 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/
🌐 Transporte HTTP
Por defecto, el servidor habla MCP sobre stdio. --http sirve Streamable HTTP
en su lugar:
zurich-opendata-mcp --http --port 8000 # binds 127.0.0.1 (default)
zurich-opendata-mcp --http --host 0.0.0.0 --port 8000
| Opción | Significado | Predeterminado |
|---|---|---|
--http | Servir Streamable HTTP en lugar de stdio | (desactivado → stdio) |
--host | Dirección de enlace | 127.0.0.1 |
--port | Puerto de enlace (1–65535) | 8000 |
MCP_ALLOWED_HOSTS | Nombres separados por comas bajo los cuales este servidor es accesible, incluido el puerto (p. ej., zurich.example.ch:8000). Las solicitudes bajo cualquier otro Host reciben 421; el bucle local permanece permitido para que las comprobaciones de salud del contenedor sigan funcionando. | (sin establecer) |
El valor predeterminado de bucle local es deliberado. Enlazar 0.0.0.0 expone el servidor en
cada interfaz, a cualquiera que pueda alcanzar la máquina — no hay
autenticación delante de él.
Establezca MCP_ALLOWED_HOSTS siempre que enlace más allá del bucle local. Protege contra
el rebinding de DNS: una página en su red resuelve su propio nombre de host a la
dirección de este servidor y luego habla con él desde el navegador. Desde el punto de vista
del navegador, esa solicitud es de mismo origen, por lo que ninguna regla de origen la detiene — solo la
verificación de Host lo hace.
Si se deja sin establecer en un enlace que no sea de bucle local, la verificación permanece
desactivada y se registra una advertencia. Ese es el valor predeterminado correcto solo cuando algo
delante del servidor valida Host. Deliberadamente no se adivina: en 0.0.0.0 el nombre
alcanzable es incognoscible dentro del proceso, y una suposición incorrecta respondería a la misma
implementación que se pretende proteger con 421 en cada solicitud.
Seguridad y Límites
- Solo lectura: Todas las herramientas realizan solo solicitudes HTTP GET — no se escriben, modifican ni eliminan datos.
- Sin datos personales: Las APIs devuelven conjuntos de datos cívicos abiertos (ocupación de estacionamientos, lecturas meteorológicas, actas parlamentarias). Ninguna información de identificación personal (PII) es procesada o almacenada por este servidor.
- Límites de velocidad: La búsqueda Solr de CKAN y ParkenDD son APIs públicas sin límites de velocidad documentados; use los parámetros
rowsylimitde manera conservadora. El servidor aplica un tiempo de espera de 30s por solicitud; los errores transitorios ascendentes (fallos de conexión, HTTP 502/503/504) se reintentan una vez con una breve espera. - Actualidad de los datos: Las herramientas en tiempo real (estacionamiento, clima, calidad del aire) reflejan la fuente ascendente en el momento de la consulta. Los datos de medición nunca se almacenan en caché; solo la búsqueda del ID de recurso UGZ actual por año (clima/calidad del aire) se almacena en caché en el proceso durante 24h.
- Términos de servicio: Los datos están sujetos a los TdS de cada fuente — data.stadt-zuerich.ch, ParkenDD, gemeinderat-zuerich.ch. Todos los datos de la Ciudad de Zúrich se publican bajo CC0 (Abierto por Defecto desde 2021).
- Sin garantías: Este servidor es un proyecto comunitario, no afiliado con la Ciudad de Zúrich ni con ninguno de los proveedores de APIs. La disponibilidad depende de las APIs ascendentes.
🤝 Contribuciones
Las contribuciones son bienvenidas — consulte CONTRIBUTING.md (Deutsch).
🔒 Seguridad
Solo lectura, sin PII, sin autenticación, un conjunto fijo de endpoints de datos públicos. Consulte SECURITY.md (Deutsch) para conocer la postura de seguridad completa y las decisiones de riesgo aceptado.
📜 Licencia
Licencia MIT — consulte LICENSE. Todos los datos utilizados se publican bajo licencias abiertas (CC0 / Abierto por Defecto desde 2021).
👤 Autor
Hayal Oezkan · malkreide
Impulsado por Protocolo de Contexto de Modelo • 6 APIs • 23 Herramientas • 5 Recursos
Instalación
Ejecute a través de uvx de uv — sin clonar ni instalación manual. Agregue a la configuración de su cliente MCP (mcpServers para Claude Desktop, Cursor y Windsurf; use una clave servers de nivel superior para VS Code en .vscode/mcp.json):
{
"mcpServers": {
"zurich-opendata-mcp": {
"command": "uvx",
"args": [
"zurich-opendata-mcp"
]
}
}
}