InfraNode
Summary: InfraNode is a keyless, read-only MCP server for normalized German city open data across weather, environment, mobility, demographics, infrastructure, energy, and more.
Discover coverage: list all supported cities, their metadata, and available upstream data sources/licenses.
Get a city snapshot: use
get_city_overviewfor a catalog of available data types plus live highlights like current weather, air quality, and train departures.Fetch any city data type: use
get_city_resource(slug, resource=...)for 67 resource keys, including demographics, parking, charging, solar, traffic, water levels, taxes, tourism, accidents, and more.Query named essentials directly: get base city data, current DWD weather, official UBA air quality, and OpenStreetMap POIs by type.
Check live transit: fetch station departures/arrivals by EVA number, or live public-transport departures for a specific stop ID.
Compare cities: compare one supported resource across up to 28 cities in a single response.
Work safely with agents: all tools are read-only, idempotent, non-destructive, and return a consistent
{ data, meta }envelope with source status and attribution.
Provides read-only access to city data from OpenStreetMap, including points of interest, traffic, and construction sites for German cities.
Provides read-only access to city master data from Wikidata for German cities, such as population, area, and administrative details.
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Deutsch | English
InfraNode
Die Open-Data-REST-API für Deutschland: eine HTTP-API ohne API-Key für Open Data zur öffentlichen Infrastruktur, auch als MCP-Server verfügbar.
Deutsche Städte veröffentlichen viel Open Data, aber jede Quelle hat ihr eigenes
Format, eigene Felder und eigene Eigenheiten, und für mehrere braucht es eine
Registrierung im jeweiligen Portal. InfraNode normalisiert rund 20 Kategorien,
Wetter (DWD), Luftqualität (UBA), ÖPNV (inklusive Echtzeit-Abfahrten), Verkehr,
Strompreis (SMARD), Bodenrichtwerte (BORIS), Parken, Ladeinfrastruktur,
Pegelstände, Demografie, Energie und mehr, für 84+ deutsche Städte hinter
einer Schnittstelle. Kein API-Key, kein Konto. Jede Antwort nutzt
denselben kanonischen { data, meta }-Umschlag mit Lizenz und Attribution je
Datensatz. Dieselben Daten stehen KI-Agenten auch als MCP-Server zur Verfügung
(12 schlanke Read-only-Tools über 78 Datenarten).
Der Einstieg ist get_city_overview, ein einziger Aufruf: Er liefert einen
Katalog aller Datenarten, die es für eine Stadt gibt, dazu einen Live-Auszug der
wichtigsten Werte. So sehen Agenten die volle Breite und nicht nur das Wetter.
InfraNode wächst laufend, neue Datenarten und Städte kommen regelmäßig dazu.
Zu den Quellen gehören der Deutsche Wetterdienst (DWD), das Umweltbundesamt (UBA), Mobilithek/DELFI, der VBB (Verkehrsverbund Berlin-Brandenburg, CC-BY 4.0), GovData, OpenStreetMap, die Bundesnetzagentur, das KBA und weitere.
Im Einsatz

Ein einziger get_city_overview("koeln")-Aufruf: aktuelles Wetter, amtliche
Luftqualität, DWD-Warnungen, Live-Zugabfahrten mit Verspätungen, Baustellen und
der vollständige Datenkatalog der Stadt, aus einem Endpoint ohne API-Key. Jede
Stadt lässt sich live ausprobieren auf
infranode.dev.
Related MCP server: germany-mcp-server
So funktioniert es
Ein gemeinsamer HTTP-Client fragt die Upstream-Quellen ab, jede Antwort wird auf
das kanonische Schema abgebildet, mit ihrer Attribution durch das Lizenz-Gate
geführt und in Redis zwischengespeichert (mit Stale-on-Error-Fallback), danach
über eine REST-API und einen MCP-Server ausgeliefert. Fällt eine Quelle aus,
schlägt sich das in source_status nieder. Der Aufruf selbst scheitert nie
daran.
flowchart LR
subgraph SRC["25+ deutsche Open-Data-Quellen"]
direction TB
S1["DWD, UBA<br/>Wetter, Luft"]
S2["Mobilithek, DELFI, DB<br/>ÖPNV, Echtzeit"]
S3["SMARD, BNetzA, MaStR<br/>Energie"]
S4["BORIS, GovData, OSM,<br/>KBA, ..."]
end
subgraph CORE["InfraNode-Kern"]
direction TB
N["Normalisieren<br/>ein kanonisches Schema"] --> L["Lizenz-Gate<br/>Attribution je Datensatz"] --> C["Redis-Cache<br/>Stale-on-Error-Fallback"]
end
SRC --> CORE
CORE --> API["REST-API<br/>infranode.dev/api/v1<br/>84 Städte, ohne API-Key"]
CORE --> MCP["MCP-Server<br/>mcp.infranode.dev<br/>12 Read-only-Tools"]
API --> APPS["Apps & Dashboards"]
MCP --> AGENTS["KI-Agenten<br/>Claude, ChatGPT"]Wenn InfraNode dir eine Datenintegration erspart: Ein Stern hilft anderen Entwicklern, das Projekt zu finden.
Schnellstart
Basis-URL https://infranode.dev/api/v1. Kein Key, kein Konto, einfach
aufrufen:
curl https://infranode.dev/api/v1/cities/koeln/weather{
"data": {
"city_slug": "koeln",
"observed_at": "2026-06-18T13:00:00Z",
"source": "dwd",
"attribution": { "text": "Datenbasis: Deutscher Wetterdienst", "modified": true },
"payload": { "kind": "weather", "temperature_c": 30.4, "humidity": 43.0, "station_id": "02667" }
},
"meta": { "source_status": "ok", "cache_status": "hit", "correlation_id": "..." }
}Jede Antwort folgt demselben { data, meta }-Umschlag: Jeder Datensatz trägt
seine attribution (Lizenz und Quelle), und meta.source_status sagt, ob die
Upstream-Quelle Daten geliefert hat. Eine tote Quelle degradiert damit sauber,
statt den Aufruf scheitern zu lassen.
Über alle Datenarten hinweg sind Feldnamen snake_case und englisch, und dasselbe
Konzept heißt immer gleich: post_code, street, house_number, place,
name, start, end, distance_km, power_kw, lat, lon. post_code ist
immer ein fünfstelliger String (führende Nullen bleiben erhalten), Zeitstempel
sind ISO 8601 mit Zeitzone, und ein Wert, den die Quelle nicht liefert, ist
null, nie ein leerer String. Manche Antworten führen daneben noch ältere
Doppelnamen mit identischen Werten (plz, zip, strasse, hausnummer, ort,
city, bezeichnung, beginn, ende, art, dist_km, leistung_kw,
einheit_typ, dazu die camelCase-Rohfelder der Autobahn-Verkehrsmeldungen).
Diese Namen sind veraltet, nimm die kanonischen.
Tipp: Ruf zuerst
/api/v1/citiesauf, um die kanonischen Stadt-Slugs zu finden (etwakoeln,berlin,hamburg), und danach einen stadtbezogenen Endpoint.Der
{slug}wird tolerant aufgelöst, die exakte ASCII-Form brauchst du also selten: der deutsche Name mit oder ohne Umlaute, jede Groß- und Kleinschreibung, gängige englische Exonyme und Kurzformen führen alle auf den kanonischen Slug (München/münchen/munich/munchen→muenchen,cologne→koeln,frankfurt→frankfurt-am-main). Ein unbekannter Name liefert404mit dem HinweisMeintest du ...?, der den nächstliegenden Slug nennt.
Die vollständige interaktive Referenz und die Abdeckung je Stadt stehen auf infranode.dev. Die InfraNode API im Postman API Network spiegelt jeden Endpoint mit echten Beispielantworten, sodass sich die InfraNode API Postman Collection ohne API-Key direkt im Browser ausprobieren lässt.
SDKs
Keylose Client-Bibliotheken, Quellcode und Issues in eigenen Repos:
Sprache | Installation | Repo |
Python |
| infranode-python, mit LangChain- und LlamaIndex-Tools |
JavaScript/TypeScript |
| infranode-js, mit Vercel-AI-SDK-Tool |
Java | ohne Paket | Tutorial: |
Daten (84 Städte, 122 Endpunkte)
Jede Kategorie unten ist ein REST-Endpoint unter
/api/v1/cities/{slug}/<key>. Über MCP kommen dieselben Daten durch 12 schlanke
Tools: ein paar benannte (get_city_overview, weather, air_quality, pois,
compare, die Live-Tafeln) und ein generisches
get_city_resource(slug, resource=<key>) für jede weitere Datenart (sein
resource-Enum listet alle 81 Keys).
Gruppe | Datenarten (Endpoint-Keys) |
Entdecken |
|
Wetter & Umwelt |
|
Mobilität |
|
Stadt & Menschen |
|
Wirtschaft & Immobilien |
|
Energie & Fahrzeuge |
|
Verhalten im Betrieb
Ohne Key, nur lesend. Keine Zugangsdaten, keine Schreibzugriffe, keine Nutzerkonten.
Kanonischer Umschlag.
{ data, meta }mit Status und Attribution je Quelle.Sanfte Degradation. Eine ausgefallene Quelle liefert
source_status, keinen Fehler.Sicher entworfen. SSRF- und Injection-Gates prüfen jede Anfrage, Eingaben laufen gegen feste Allowlists.
Das Sicherheitsmodell steht in SECURITY.md.
Paginierung & Kanal-Voreinstellungen
Listen von Datenarten (charging, energy, events, transit, die
OSM-Feature-Endpoints) haben bei gleicher URL eine kanalabhängige
Voreinstellung:
Direktes REST liefert die vollständige Liste in einem Aufruf (
limit=null,returned == total,truncated=false).GPT Actions (OpenAI-Header) und MCP sind an eine voreingestellte Seitengröße gebunden, damit Antworten für Agenten klein bleiben.
limit=all(oder?all=1) erzwingt auf jedem Kanal die volle Liste,limitundoffsetblättern explizit.meta.pagination(total/returned/limit/offset/truncated) steht auf jedem Kanal, der ausgelieferte Ausschnitt ist also immer nachvollziehbar.
Bei traffic ist die rohe Polyline optional: include=geometry (oder ?full=1)
ergänzen, die Standardantwort bleibt schlank.
Stabilität, Changelog & Roadmap
Du baust produktiv auf InfraNode auf? Dann bleib bei Änderungen vorne:
Changelog listet jede sichtbare Änderung (neue Datenarten, neue Städte, geändertes Verhalten, Fehlerbehebungen, Deprecations), die neueste zuerst. Per RSS abonnierbar.
Roadmap zeigt das Geplante und die Stabilitätszusage: Die API wächst additiv, der Umschlag bleibt stabil, und Änderungen an bestehenden Antworten werden vorher angekündigt (in der Regel 30+ Tage).
Statusseite und die GitHub-Releases decken Verfügbarkeit und versionierte Änderungen ab.
Als MCP-Server nutzen
Dieselbe API steht als Remote-MCP-Server bereit, KI-Agenten können also alle 78 Datenarten als Tools aufrufen. Mit Claude Code genügt eine Zeile:
claude mcp add --transport http infranode https://mcp.infranode.dev/mcpJeden anderen MCP-Client richtest du auf denselben Remote-Endpoint (Streamable HTTP):
{
"mcpServers": {
"infranode": { "url": "https://mcp.infranode.dev/mcp" }
}
}Cursor / Windsurf: den Block oben in
~/.cursor/mcp.jsoneintragen (oder in die MCP-Einstellungen der App).VS Code:
code --add-mcp '{"name":"infranode","url":"https://mcp.infranode.dev/mcp"}'Claude Desktop: denselben
mcpServers-Block in dieclaude_desktop_config.jsoneintragen.ChatGPT: einen Connector mit der URL
https://mcp.infranode.dev/mcpanlegen.
Alle Tools tragen die Annotationen readOnlyHint: true /
destructiveHint: false / idempotentHint: true, MCP-Clients können sie also
gefahrlos automatisch freigeben. Die MCP-Schicht bringt außerdem fertige
Prompts (city_briefing, compare_air_quality, commute_check) und
Ressourcen (infranode://cities, infranode://sources) mit. Die
vollständige Installationsanleitung, das komplette Tool-Manifest mit
Beispielausgaben, das Berechtigungsmodell und ein Beispiel-Transkript stehen in
docs/mcp-install.md. Das Registry-Manifest ist
server.json.
In ChatGPT nutzen (Custom-GPT-Action)
Fertiges GPT: InfraNode: German City Data - Weather & Transit steht im GPT Store (Research & Analysis) und funktioniert sofort.
Für eine eigene Variante liefert InfraNode eine kuratierte OpenAPI-Spec für GPT-Actions: 23 der nützlichsten Operationen (ChatGPT erlaubt höchstens 30 pro Action), ohne Key, alle GET.
Im GPT-Editor Configure → Actions → Create new action → Import from URL öffnen und
https://infranode.dev/actions/openapi.jsoneinfügen.Die Authentifizierung auf None stehen lassen, als Datenschutzerklärung
https://infranode.dev/datenschutz/eintragen.In den Instructions des GPT festhalten: mit
getCityOverview(slug)starten, Stadtnamen übergetCitiesauflösen unddata.attributionzitieren (die Datenlizenzen verlangen die Namensnennung).
Details und empfohlene Instructions:
infranode.dev/chatgpt/. Die Spec wird von
scripts/build_actions_spec.py aus docs/openapi.yaml erzeugt.
Alternativen und wie InfraNode dazu steht
Andere MCP-Server decken Teile des deutschen oder europäischen Datenraums ab. Für Open Data auf Stadtebene ist InfraNode am breitesten, und die Projekte unten ergänzen einander oft:
germany-mcp-server Bundes- und Regierungsdaten (Autobahn, DWD, NINA, SMARD, Bundestag). Bundesweit, ohne Tiefe je Stadt.
db-mcp-server / db-timetable-mcp nur Fahrpläne der Deutschen Bahn.
mcp-server-public-transport ÖPNV in Europa, in Deutschland deckt es Berlin/Brandenburg (VBB) ab.
Server für einzelne Städte (etwa München, Berlin) decken je eine Stadt ab.
InfraNode deckt 84 deutsche Städte und 82 Datenarten hinter einem gehosteten Endpoint ohne API-Key ab: Umwelt, Mobilität, Energie, Wirtschaft und Stadtleben. Der vollständige Vergleich Seite an Seite steht auf infranode.dev/mcp-vergleich.
Selbst hosten (optional)
Nötig ist das nicht, der gehostete Endpoint oben ist der schnellste Weg. Der Code liegt aber offen. Den API-Stack lokal mit Docker (Compose v2) starten:
cp .env.example .env # example config, contains NO real secrets
docker compose -f deploy/docker-compose.yml up
curl http://localhost/api/v1/health # -> {"status":"ok","version":"1.0.0","redis":true}Den MCP-Server selbst lokal über stdio betreiben (gegen die öffentliche API):
uv sync --group mcp
INFRANODE_MCP_API_BASE=https://infranode.dev/api/v1 uv run python -m infranode.mcp.serverFür alle Einstellungen gilt das Env-Präfix INFRANODE_ (siehe .env.example),
jede Datenquelle hat ihren eigenen INFRANODE_ENABLE_*-Schalter. Echte Secrets
landen nie im Repo, versioniert ist nur .env.example, und die CI fährt einen
gitleaks-Scan.
Lizenz: Code und Daten sind getrennt
Code: Apache-2.0 (siehe LICENSE).
Daten: Die offenen Daten, die InfraNode ausliefert, behalten die Lizenzen ihrer Upstream-Quellen (etwa ODbL für OpenStreetMap, DL-DE-BY für GovData, Namensnennung für DWD). Diese Datenlizenzen und die Attribution werden separat in
DATA-LICENSES.mdgeführt. Die Apache-2.0-Lizenz gilt nur für den Quellcode der API, nicht für die durchgereichten Daten.
Mitmachen
Beiträge sind willkommen. Setup, Gate-Befehle und die Secret-Regel stehen in
CONTRIBUTING.md. Für eine neue Datenquelle ist die
deklarative Quellen-Registry in src/infranode/registry/source_specs.py der
Startpunkt (ein SourceSpec-Eintrag je Upstream), die vollständige Checkliste
steht in CONTRIBUTING.md.
Available Tools
12 toolsair_qualityAir QualityARead-onlyIdempotentInspect
Get official air quality for a German city (PM10, NO2 and more).
Sourced from the Umweltbundesamt (UBA). Read-only. For live nearest-station
hourly readings use get_city_resource(slug, resource='air') instead.
Inputs: slug (required). Returns: data, meta
compareCompare CitiesARead-onlyIdempotentInspect
Compare ONE resource across MULTIPLE cities in a single response.
Fans the resource out over the listed cities and returns a per-city
source_status (ok/disabled/no_data/error/not_found), so a missing or
failing city source does not spoil the whole answer. Read-only.
Inputs: cities (required), resource (required). Returns: data, meta
get_cityCity Base DataARead-onlyIdempotentInspect
Get base data for a German city (population, area, coordinates).
Sourced from Wikidata. Read-only. Useful as a first lookup to confirm a city
exists and get its core attributes. For a broader question about the city
(what data is available at all) use get_city_overview instead.
Inputs: slug (required). Returns: data, meta
get_city_overviewCity OverviewARead-onlyIdempotentInspect
Get a ONE-CALL overview of everything InfraNode knows about a German city.
Start here for any city question. Returns: the city's base data, a CATALOG of
all 67 available data types (weather, air quality, public transit, trains,
traffic, charging, parking, solar, energy, demographics, taxes, accidents,
tourism, heritage, trees, population density, playgrounds, post boxes and many
more), each with its coverage status and the exact tool to call next (for most
data types that is get_city_resource(slug, resource=<type>)), plus a small
live highlights snapshot (current weather, air quality and train departures).
Data types not yet covered for this city show where they ARE available so you
can pivot. InfraNode keeps adding data and cities, so the catalog grows over
time. Read-only.
Inputs: slug (required). Returns: data, meta
get_city_resourceCity Data by TypeARead-onlyIdempotentInspect
Fetch ANY per-city data type by its key (generic accessor, 67 data types).
One tool for the whole breadth of InfraNode: live data (air, traffic, transit
stops, parking, charging, water-level, flood, sharing, fuel-prices, icu-live,
webcams, station-departures/-arrivals/stations, ...), statistics
(demographics, unemployment, tourism, accidents, crime-stats, indicators,
land-values, tax-rates, insolvencies, ...), infrastructure and environment
(solar, solar-roofs, district-heating, energy, heritage, tree-cadastre,
playgrounds, public-toilets, markets, education, ...) and more. Discover the
valid keys and per-city coverage with get_city_overview(slug) or the
infranode://catalog resource; the resource enum lists every key.
Uncovered types return source_status="not_covered" (plus where they ARE
available), never an error. Read-only.
Inputs: slug (required), resource (required). Returns: data, meta
list_citiesList CitiesARead-onlyIdempotentInspect
List all covered cities (slug, federal state, population, coverage).
Takes no arguments. Call this first to discover valid city slugs before invoking any city-scoped tool. Read-only.
Inputs: no named parameters. Returns: data, meta
poisPoints of InterestARead-onlyIdempotentInspect
Get points of interest in a German city, filtered by type.
Sourced from OpenStreetMap. Read-only.
Inputs: slug (required), type (required). Returns: data, meta
sourcesData SourcesARead-onlyIdempotentInspect
List all data sources with license, attribution and availability.
Takes no arguments. Shows which upstream sources InfraNode bundles and whether each is currently active. Read-only.
Inputs: no named parameters. Returns: data, meta
station_board_arrivalsStation Board: ArrivalsARead-onlyIdempotentInspect
Get live arrivals for ANY railway station by its EVA number.
Mirror of station_board_departures for arriving trains (all categories,
real-time delays, disruption messages). Get the EVA from
get_city_resource(slug, resource='stations'). Read-only.
Inputs: eva (required). Returns: data, meta
station_board_departuresStation Board: DeparturesARead-onlyIdempotentInspect
Get live departures for ANY railway station by its EVA number.
Covers all train categories including local/regional (S/RB/RE) and long
distance, with real-time delays, cancellations and disruption messages. Get
the EVA from get_city_resource(slug, resource='stations'). Read-only.
Inputs: eva (required). Returns: data, meta
transit_departuresTransit DeparturesARead-onlyIdempotentInspect
Get live public-transport departures with real-time delays for a stop.
Sourced from GTFS-RT/HVV/VGN. Unlike the static stop list
(get_city_resource(slug, resource='transit')), this returns minute-fresh
departures including delay for ONE stop. A stop_id is required: fetch the
city's transit stops first to discover valid stop IDs, then pass one here.
Read-only.
Inputs: slug (required), stop_id. Returns: data, meta
weatherWeatherARead-onlyIdempotentInspect
Get current weather observations for a German city.
Sourced from the Deutscher Wetterdienst (DWD): temperature, wind,
precipitation and related fields. Read-only, current conditions only (not a
forecast). For warnings use get_city_resource(slug, resource='weather-warnings'). For a broader question about the city (not
just weather) use get_city_overview instead, which already includes a
live weather highlight.
Inputs: slug (required). Returns: data, meta
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Most tools have distinct targets, and the generic get_city_resource is clearly positioned as the fallback for many resource types. Intentional overlap exists between get_city/get_city_overview and air_quality vs resource='air', but the descriptions explicitly route agents to the correct tool. Station board and transit departures are also disambiguated by mode and ID type.
Names are readable and consistently snake_case, but the style is mixed: get_city/get_city_resource use verb_noun, while air_quality/weather/pois/sources are bare nouns and station_board_departures/transit_departures use noun_noun patterns. No single clear convention exists, though the get_city_* family provides some structure.
12 tools is well within the ideal range and each one supports a distinct workflow: discovery, single-city lookup, resource-specific retrieval, station boards, and multi-city comparison. No redundant tools stand out, and the generic resource accessor keeps the count from ballooning despite a large underlying data catalog.
The server covers the full read-only data lifecycle: list_cities for discovery, get_city_overview for a one-call catalog, get_city_resource for any of the 67 data types, convenience tools for common slices, and compare for multi-city analysis. For its stated purpose, there are no critical dead ends.
Maintenance
Related MCP Connectors
GovData.de MCP — Germany's national open-data portal (CKAN API).
Keyless MCP access to official Luxembourg public data: laws, statistics, mobility, and more.
Germany public procurement MCP — official German government tenders (keyless).
Remote MCP for Dutch KLIC-melding utility data, maps, and dig-safe workflows.
Related MCP Servers
- AlicenseBqualityBmaintenanceSwiss open data MCP server — transport, weather, geodata, companies, etc,. Zero API keys.942,953 npm26MIT
- AlicenseBqualityDmaintenanceMCP server providing AI agents with access to German government open data. 12 tools across 6 categories: Autobahn traffic, DWD weather, NINA disaster warnings, SMARD energy market, Bundestag parliamentary data, and pollen forecasts. All APIs are free, no keys required.1621 PyPI3MIT
- AlicenseNot gradedqualityDmaintenanceEnables access to German weather data from the Deutscher Wetterdienst, including station observations, forecasts, and warnings, through standardized MCP tools.1MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for GovData.de, Germany's national open-data portal via CKAN API, enabling AI agents to list publishing organizations and thematic groups.1 npmMIT