Zurich Open Data MCP Server

Permite que Claude, ChatGPT e outros assistentes de IA compatíveis com MCP consultem diretamente mais de 900 conjuntos de dados, geodados, atas parlamentares, dados turísticos, dados vinculados e informações ambientais e de mobilidade em tempo real da Cidade de Zurique. 20 Ferramentas, 6 Recursos, 6 APIs.

Documentação

🇨🇭 Parte do Swiss Public Data MCP Portfolio

🏙️ Zurich Open Data MCP Server

PyPI License: MIT Python 3.11+ MCP No Auth Required CI

🌐 Inglês | Deutsch

Um servidor MCP (Model Context Protocol) que fornece acesso com IA a Dados Abertos da Cidade de Zurique, Suíça.

Permite que Claude, ChatGPT e outros assistentes de IA compatíveis com MCP consultem diretamente mais de 900 conjuntos de dados, geodados, atas parlamentares, resoluções do conselho, dados de turismo, dados vinculados e informações ambientais e de mobilidade em tempo real da Cidade de Zurique. 23 Ferramentas (+3 aliases obsoletos), 5 Recursos, 6 APIs.

Demonstração

Demo: Claude using zurich_parking_live and zurich_air_quality

✨ Recursos

CKAN Open Data (data.stadt-zuerich.ch)

  • zurich_search_datasets – Pesquisa de texto completo com sintaxe Solr em mais de 900 conjuntos de dados
  • zurich_get_dataset – Metadados completos e URLs de download para um conjunto de dados
  • zurich_datastore_query – Consulta direta de dados tabulares (filtros, ordenação)
  • zurich_datastore_sql – Consultas SQL no DataStore
  • zurich_list_categories – Navegue por 19 categorias temáticas
  • zurich_list_tags – Pesquisa temática baseada em tags

Dados Ambientais em Tempo Real

  • zurich_weather_live – 🌤️ Clima atual (temperatura, umidade, pressão, chuva) de 4 estações UGZ
  • zurich_air_quality – 🌬️ Qualidade do ar ao vivo (NO₂, O₃, PM10, PM2.5) com limites da OMS
  • zurich_water_weather – 🌊 Dados do Lago de Zurique (temperatura da água, nível, vento) a cada 10 min

Dados de Mobilidade em Tempo Real

  • zurich_pedestrian_traffic – 🚶 Contagem de pedestres na Bahnhofstrasse (3 locais, por hora)
  • zurich_vbz_passengers – 🚊 Número de passageiros do transporte público VBZ (mais de 800.000 registros, todas as linhas/paradas)
  • zurich_parking_live – 🅿️ Ocupação em tempo real de 36 estacionamentos (ParkenDD)

Geoportal (Geodados WFS)

  • zurich_geo_layers – 📍 Lista de 14 camadas de geodados disponíveis
  • zurich_geo_features – 📍 Busca de recursos GeoJSON (escolas, distritos, parquinhos, dados climáticos, etc.)

Parlamento da Cidade (API Paris)

  • zurich_parliament_search – 🏛️ Pesquisa de atas parlamentares (interpelações, moções, postulados)
  • zurich_parliament_members – 🏛️ Pesquisa de membros do conselho (partido, comissões, mandatos)

Turismo de Zurique

  • zurich_tourism – 🏨 Atrações, restaurantes, hotéis, eventos (dados Schema.org, 4 idiomas)

Dados Vinculados (SPARQL)

  • zurich_sparql – 📊 Consultas SPARQL no endpoint de dados vinculados estatísticos (endpoint ainda não produtivo — a ferramenta não é registrada por padrão; opte por ativá-la com a variável de ambiente ZURICH_OPENDATA_ENABLE_SPARQL=1)

Stadtratsbeschlüsse (Resoluções do Conselho)

  • zurich_strb_search – 📜 Pesquisa de texto completo de resoluções públicas do conselho (título, departamento, intervalo de datas)
  • zurich_strb_by_department – 📜 Lista todas as resoluções de um departamento (ex.: SSD, FD, PRD)
  • zurich_strb_detail – 📜 Resolução única por número NNNN/YYYY

(Os nomes anteriores search_stadtratsbeschluesse, get_beschluesse_by_departement e get_stadtratsbeschluss_detail permanecem disponíveis como aliases obsoletos até a próxima versão principal.)

Ferramentas de Análise

  • zurich_analyze_datasets – Análise abrangente: relevância, atualidade, estrutura de dados
  • zurich_catalog_stats – Visão geral do catálogo com estatísticas
  • zurich_find_school_data – Pesquisa selecionada para conjuntos de dados relacionados à educação

Recursos MCP

  • zurich://dataset/{name} – Metadados do conjunto de dados
  • zurich://category/{group_id} – Detalhes da categoria
  • zurich://parking – Dados atuais de estacionamento
  • zurich://geo/{layer_id} – Geodados GeoJSON (14 camadas)
  • zurich://tourism/categories – Categorias de turismo

🚀 Instalação

Pré-requisitos

  • Python 3.11+
  • pip ou uv
  • mcp[cli] 2.x — instalado automaticamente; o servidor usa a API 2.x (mcp.server.mcpserver) e não pode ser executado no mcp 1.x

Use 0.6.0 ou mais recente. A versão 0.5.1 declarou mcp[cli]>=1.28.1 sem limite superior. Quando mcp 2.0.0 removeu mcp.server.fastmcp, toda instalação nova de 0.5.1 resolveu para 2.0.0 e falhou na importação com ModuleNotFoundError. 0.6.0 roda na API 2.x e fixa >=2.0.0,<3. Se você estiver fixado em 0.5.1, atualize — não há configuração funcional dessa versão restante.

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 .

⚙️ Configuração

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

Adicione a .vscode/settings.json:

{
  "mcpServers": {
    "zurich-opendata": {
      "command": "python",
      "args": ["-m", "zurich_opendata_mcp.server"]
    }
  }
}

💬 Exemplos de Consultas

Após a configuração, você pode perguntar ao Claude:

Dados Abertos

  • "Quais conjuntos de dados estão disponíveis sobre escolas em Zurique?"
  • "Mostre-me as férias escolares para escolas públicas"
  • "Analise os geodados disponíveis"

Dados em Tempo Real

  • "Qual é a temperatura atual em Zurique?"zurich_weather_live
  • "Como está a qualidade do ar hoje?"zurich_air_quality
  • "Qual é a temperatura da água no Lago de Zurique?"zurich_water_weather
  • "Quantas vagas de estacionamento estão livres agora?"zurich_parking_live
  • "Quantas pessoas estão na Bahnhofstrasse agora?"zurich_pedestrian_traffic

Geodados

  • "Mostre-me todas as instalações escolares em Zurique como GeoJSON"zurich_geo_features
  • "Quais camadas de geodados estão disponíveis?"zurich_geo_layers
  • "Onde estão os parquinhos em Zurique?"

Parlamento da Cidade

  • "Quais moções parlamentares sobre escolas foram apresentadas?"zurich_parliament_search
  • "Quais membros do conselho pertencem ao partido SP?"zurich_parliament_members

Resoluções do Conselho (Stadtratsbeschlüsse)

  • "Encontre resoluções do conselho sobre Volksschule de 2025"zurich_strb_search
  • "Liste todas as resoluções SSD em 2025"zurich_strb_by_department
  • "Mostre a resolução do conselho 1203/2025"zurich_strb_detail

Turismo

  • "Quais restaurantes o Turismo de Zurique recomenda?"zurich_tourism

🔗 Fontes de Dados

APIEndpointDados
CKANdata.stadt-zuerich.ch/api/3/Mais de 900 conjuntos de dados abertos
Geoportal WFSogd.stadt-zuerich.ch/wfs/geoportal14 camadas de geodados (GeoJSON)
API Parisgemeinderat-zuerich.ch/apiAtas e membros parlamentares
Turismo de Zuriquezuerich.com/en/api/v2/dataAtrações, restaurantes, hotéis
SPARQLld.stadt-zuerich.ch/queryDados vinculados abertos / estatísticas
ParkenDDapi.parkendd.de/ZuerichOcupação de estacionamento em tempo real

📊 Categorias de Dados Disponíveis

CategoriaID
Empregoarbeit-und-erwerb
Mapas Basebasiskarten
Construção e Habitaçãobauen-und-wohnen
Populaçãobevolkerung
Educaçãobildung
Energiaenergie
Finançasfinanzen
Lazerfreizeit
Saúdegesundheit
Crimekriminalitat
Culturakultur
Mobilidademobilitat
Políticapolitik
Preçospreise
Assuntos Sociaissoziales
Turismotourismus
Meio Ambienteumwelt
Administraçãoverwaltung
Economiavolkswirtschaft

📍 Camadas Geo Disponíveis

Fonte da verdade: GEOPORTAL_LAYERS em src/zurich_opendata_mcp/config.py.

ID da CamadaDescrição
schulanlagenInstalações escolares (jardins de infância, escolas, cuidados pós-escola)
schulkreiseLimites dos distritos escolares (polígonos)
schulwegeTravessias de rotas escolares e pontos de perigo
stadtkreiseLimites dos distritos da cidade (polígonos)
spielplaetzeParquinhos públicos
kreisbueroEscritórios dos distritos da cidade
sammelstellePontos de coleta de resíduos
sportInstalações esportivas
klimadatenDados climáticos (raster, temperaturas, ilhas de calor)
lehrpfadeTrilhas educacionais
stimmlokaleLocais de votação
sozialzentrumCentros sociais
velopruefstreckenRotas de exame de bicicleta para escolas
familienberatungPontos de encontro de aconselhamento familiar

🏗️ Estrutura do Projeto

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

🧪 Desenvolvimento

# 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 padrão, o servidor fala MCP via stdio. --http serve Streamable HTTP em vez disso:

zurich-opendata-mcp --http --port 8000              # binds 127.0.0.1 (default)
zurich-opendata-mcp --http --host 0.0.0.0 --port 8000
OpçãoSignificadoPadrão
--httpServe Streamable HTTP em vez de stdio(desligado → stdio)
--hostEndereço de vinculação127.0.0.1
--portPorta de vinculação (1–65535)8000
MCP_ALLOWED_HOSTSNomes separados por vírgula pelos quais este servidor é acessível, porta incluída (ex.: zurich.example.ch:8000). Solicitações sob qualquer outro Host recebem 421; loopback permanece permitido para que as verificações de saúde do contêiner continuem funcionando.(não definido)

O padrão de loopback é intencional. Vincular 0.0.0.0 expõe o servidor em cada interface, para todos que podem alcançar a máquina — não há autenticação na frente dele.

Defina MCP_ALLOWED_HOSTS sempre que vincular além do loopback. Ele protege contra DNS rebinding: uma página na sua rede resolve seu próprio hostname para o endereço deste servidor e então fala com ele a partir do navegador. Do ponto de vista do navegador, essa solicitação é de mesma origem, então nenhuma regra de origem a impede — apenas a verificação de Host faz isso.

Se não for definido em uma vinculação não-loopback, a verificação permanece desligada e um aviso é registrado. Esse é o padrão correto apenas quando algo na frente do servidor valida Host. Não é adivinhado deliberadamente: em 0.0.0.0, o nome acessível é incognoscível dentro do processo, e uma suposição errada responderia à própria implantação que se destina a proteger com 421 em cada solicitação.

Segurança e Limites

  • Somente leitura: Todas as ferramentas executam apenas solicitações HTTP GET — nenhum dado é gravado, modificado ou excluído.
  • Sem dados pessoais: As APIs retornam conjuntos de dados cívicos abertos (ocupação de estacionamento, leituras meteorológicas, atas parlamentares). Nenhuma informação pessoalmente identificável (PII) é processada ou armazenada por este servidor.
  • Limites de taxa: A pesquisa Solr do CKAN e o ParkenDD são APIs públicas sem limites de taxa documentados; use os parâmetros rows e limit de forma conservadora. O servidor aplica um tempo limite de 30s por solicitação; erros transitórios upstream (falhas de conexão, HTTP 502/503/504) são repetidos uma vez com um pequeno backoff.
  • Atualidade dos dados: Ferramentas em tempo real (estacionamento, clima, qualidade do ar) refletem a fonte upstream no momento da consulta. Os dados de medição nunca são armazenados em cache; apenas a busca do ID de recurso UGZ atual por ano (clima/qualidade do ar) é armazenada em cache no processo por 24h.
  • Termos de serviço: Os dados estão sujeitos aos ToS de cada fonte — data.stadt-zuerich.ch, ParkenDD, gemeinderat-zuerich.ch. Todos os dados da Cidade de Zurique são publicados sob CC0 (Open by Default desde 2021).
  • Sem garantias: Este servidor é um projeto comunitário, não afiliado à Cidade de Zurique ou a qualquer um dos provedores de API. A disponibilidade depende das APIs upstream.

🤝 Contribuindo

Contribuições são bem-vindas — veja CONTRIBUTING.md (Deutsch).

🔒 Segurança

Somente leitura, sem PII, sem autenticação, um conjunto fixo de endpoints de dados públicos. Veja SECURITY.md (Deutsch) para a postura completa de segurança e decisões de risco aceitas.

📜 Licença

Licença MIT — veja LICENSE. Todos os dados usados são publicados sob licenças abertas (CC0 / Open by Default desde 2021).

👤 Autor

Hayal Oezkan · malkreide


Desenvolvido por Model Context Protocol • 6 APIs • 23 Ferramentas • 5 Recursos

Instalação

Execute via uvx do uv — sem clone ou instalação manual necessária. Adicione à sua configuração do cliente MCP (mcpServers para Claude Desktop, Cursor e Windsurf; use uma chave servers de nível superior para VS Code em .vscode/mcp.json):

{
  "mcpServers": {
    "zurich-opendata-mcp": {
      "command": "uvx",
      "args": [
        "zurich-opendata-mcp"
      ]
    }
  }
}