Keyless, read-only MCP server providing open data for 84 German cities (~60 data types) including weather, air quality, public transport, electricity prices, land values, and more through a unified interface.
InfraNode demonstrates strong definition quality across 12 tools with comprehensive descriptions, well-structured schemas, and clear naming conventions. All tools follow verb-noun patterns (get_*, list_, compare) and have rich, context-aware descriptions (100-300+ chars) that explain WHAT the tool does, WHEN to use it, and dependencies. Parameter descriptions are detailed with format guidance. However, output schemas are not explicitly documented in the source code (only inferred from descriptions), and some tools lack formal error-handling guidance or recovery paths. Tool composition is excellent, tools are properly scoped, chainable via slug/resource patterns, and designed for agent orchestration. No security issues detected. Transport is HTTP (fastmcp), which is current.
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.
Compare one metric across many cities in one call. Returns a parallel array across multiple cities so you can rank, filter or analyze without stitching snapshots. Read-only.
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.
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 ~60 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.
Output schemas not explicitly documented in source code. While descriptions infer structure (e.g., 'Returns: the city's base data, a CATALOG of all ~60 available data types...'), the actual response field types, nested object structures, and pagination patterns are not declared in the tool definitions. Agents cannot reliably plan chaining or field extraction.
Error handling and recovery paths not documented in tool descriptions. Tools return 404 with suggestions (e.g., 'Meintest du ...?'), but this recovery path is mentioned only in parameter descriptions, not in the tool description itself. Error classification (retryable vs. user-fixable vs. fatal) is absent from all tool definitions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | A | 86 | 2025-06-18+ | v2 |
Fetch ANY per-city data type by its key (generic accessor, ~60 data types). One tool for the whole breadth of InfraNode: live data (air, traffic, transit stops, parking, charging, water-level, flood, sharing, fuel-prices, webcams, station-departures/-arrivals/stations, ...), statistics (demographics, unemployment, tourism, accidents, crime-stats, indicators, land-values, tax-rates, insolvencies, ...), multi-year TIME SERIES (``sustainability``: SDG indicators per municipality, one value per year from 2006 to 2023, so trends can be answered without stitching snapshots), 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.
Get the list of all German cities covered by InfraNode with their canonical slugs. Use these slugs as the ``slug`` parameter in other tools. Read-only.
Get points of interest in a German city, filtered by type. Sourced from OpenStreetMap. Read-only.
Get a full metadata table of every data type's source, attribution, license, update frequency and freshness. InfraNode consolidates 60+ open data sources into one envelope; this tool is the master ledger. Read-only.
Get live arrivals 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 platform info. Sourced from DB Station&Service (via Fahrplan API). Read-only.
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 platform info. Sourced from DB Station&Service (via Fahrplan API). Read-only.
Get live departures for a stop (bus/tram/train/U-Bahn/S-Bahn) in a German city, with real-time delays and cancellations. All local transit types in one tool. Sourced from the city's GTFS Realtime feed or live API. Read-only. For railway station boards (longer distances, all categories, platform info) use the EVA-based ``station_board_departures`` instead.
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.
Pagination not declared in parameter or output schemas. Tools like get_city_resource and compare may return large result sets, but there is no explicit limit, offset, cursor, or total_count documented. 'The exact tool to call next' guidance assumes pagination is available, but it is not formally specified.
Slugs accept 'leniently resolved' forms (e.g., 'München/munich/munchen -> muenchen'), but the normalization rules are not formalized. An LLM may pass 'BERLIN' vs 'berlin' vs 'BERLIN-ALT-KÖPENICK' without knowing the exact resolution algorithm. Parameter description could specify case-sensitivity, diacritic handling, and whitespace rules more precisely.