← WebMCP Directory

Tool tree

navigator.berlin

Developer ToolsTools verified
Website
Home
Explore capabilities

    page: Every page

    address_lookupAnswer

    Search Berlin addresses, streets, and POIs. Returns up to N candidates with coordinates and administrative context (Bezirk, Kiez, postcode). Backed by OSM Nominatim, biased to Berlin.

    View tool JSON
    {
      "name": "address_lookup",
      "kind": "answer",
      "impl": "imperative",
      "description": "Search Berlin addresses, streets, and POIs. Returns up to N candidates with coordinates and administrative context (Bezirk, Kiez, postcode). Backed by OSM Nominatim, biased to Berlin.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20
          }
        },
        "required": [
          "query"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    cross_layer_queryAnswer

    Query all configured Berlin data layers at a geographic point (lat, lng) and return one structured hit per layer with full provenance (source, updated_at, license, reason).

    View tool JSON
    {
      "name": "cross_layer_query",
      "kind": "answer",
      "impl": "imperative",
      "description": "Query all configured Berlin data layers at a geographic point (lat, lng) and return one structured hit per layer with full provenance (source, updated_at, license, reason).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "lat",
          "lng"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    list_layers_at_pointAnswer

    Lightweight discovery: list which Berlin data layers cover a given point. Returns layer slug, has_value flag, and reason (no-coverage, outdated, seasonal). Use this to decide which deeper queries to run.

    View tool JSON
    {
      "name": "list_layers_at_point",
      "kind": "answer",
      "impl": "imperative",
      "description": "Lightweight discovery: list which Berlin data layers cover a given point. Returns layer slug, has_value flag, and reason (no-coverage, outdated, seasonal). Use this to decide which deeper queries to run.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "lat",
          "lng"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    get_kiez_profileAnswer

    Return the public profile of a Berlin Kiez (LOR Bezirksregion) by slug. Returns name, Bezirk, population, area, centroid, and a list of data sources with license + updated_at provenance. The slug must match a Berlin LOR Bezirksregion (143 total), NOT the plr_name field from cross_layer_query (which is a finer Planungsraum). On unknown slug, returns { error: "kiez_not_found", slug, hint } instead of throwing.

    View tool JSON
    {
      "name": "get_kiez_profile",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the public profile of a Berlin Kiez (LOR Bezirksregion) by slug. Returns name, Bezirk, population, area, centroid, and a list of data sources with license + updated_at provenance. The slug must match a Berlin LOR Bezirksregion (143 total), NOT the plr_name field from cross_layer_query (which is a finer Planungsraum). On unknown slug, returns { error: \"kiez_not_found\", slug, hint } instead of throwing.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "locale": {
            "type": "string",
            "enum": [
              "de",
              "en"
            ]
          }
        },
        "required": [
          "slug"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    get_layer_metadataAnswer

    Return rich metadata for a single data layer by slug: source URL, license, license URL, geometry type, feature count, last update, and methodology summary. The slug must match a manifest layer-slug exactly (e.g. mss-gesamtindex-2025, laerm-2023, klima-pet-2022) — semantic guesses like "social-status" or "noise" will fail. Use list_layers_at_point or cross_layer_query to discover valid slugs from a location first. On unknown slug, returns { error: "layer_not_found", slug, hint } instead of throwing. The methodology summary is always German, regardless of the locale param.

    View tool JSON
    {
      "name": "get_layer_metadata",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return rich metadata for a single data layer by slug: source URL, license, license URL, geometry type, feature count, last update, and methodology summary. The slug must match a manifest layer-slug exactly (e.g. mss-gesamtindex-2025, laerm-2023, klima-pet-2022) — semantic guesses like \"social-status\" or \"noise\" will fail. Use list_layers_at_point or cross_layer_query to discover valid slugs from a location first. On unknown slug, returns { error: \"layer_not_found\", slug, hint } instead of throwing. The methodology summary is always German, regardless of the locale param.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "locale": {
            "type": "string",
            "enum": [
              "de",
              "en"
            ]
          }
        },
        "required": [
          "slug"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    list_electionsAnswer

    List all Berlin elections available in navigator.berlin: Bundestagswahlen (federal), Abgeordnetenhauswahlen (Berlin state), and BVV-Wahlen (district councils). For each: slug like "2025-btw-zweitstimme" or "2023-bvv", year, election type (btw/agh/bvv), Stimmtyp (erststimme/zweitstimme/einstimme), whether it is a repeat election with parent slug, whether per-Stimmbezirk geometry is available (needed for get_voting_district_geometry), source authority, and license. Slugs from this tool are the canonical input for get_election_result and compare_elections.

    View tool JSON
    {
      "name": "list_elections",
      "kind": "answer",
      "impl": "imperative",
      "description": "List all Berlin elections available in navigator.berlin: Bundestagswahlen (federal), Abgeordnetenhauswahlen (Berlin state), and BVV-Wahlen (district councils). For each: slug like \"2025-btw-zweitstimme\" or \"2023-bvv\", year, election type (btw/agh/bvv), Stimmtyp (erststimme/zweitstimme/einstimme), whether it is a repeat election with parent slug, whether per-Stimmbezirk geometry is available (needed for get_voting_district_geometry), source authority, and license. Slugs from this tool are the canonical input for get_election_result and compare_elections.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "page": "/"
    }
    get_election_resultAnswer

    Return the top parties at a given Berlin address for one specific election, on a selectable aggregation level (stimmbezirk/kiez/bezirk/berlin). Input: lat + lng + election_slug (from list_elections, format "2025-btw-zweitstimme" or "2023-bvv") + optional level. Default level is the finest available: stimmbezirk if the address has per-district data, then kiez (LOR Bezirksregion), then bezirk, then berlin. Stimmbezirks-level results are Briefwahl-Gruppen (a voting district merged with its postal-voting district) and already include postal votes for every election year with geometry. Output includes top-5 parties with vote count + share + color, source authority + license + last update, and caveats for kiez-level (postal votes allocated proportionally, not an official breakdown) or repeat elections. Errors with election_not_found if election_slug does not exist, address_outside_berlin if the point is not in Berlin.

    View tool JSON
    {
      "name": "get_election_result",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the top parties at a given Berlin address for one specific election, on a selectable aggregation level (stimmbezirk/kiez/bezirk/berlin). Input: lat + lng + election_slug (from list_elections, format \"2025-btw-zweitstimme\" or \"2023-bvv\") + optional level. Default level is the finest available: stimmbezirk if the address has per-district data, then kiez (LOR Bezirksregion), then bezirk, then berlin. Stimmbezirks-level results are Briefwahl-Gruppen (a voting district merged with its postal-voting district) and already include postal votes for every election year with geometry. Output includes top-5 parties with vote count + share + color, source authority + license + last update, and caveats for kiez-level (postal votes allocated proportionally, not an official breakdown) or repeat elections. Errors with election_not_found if election_slug does not exist, address_outside_berlin if the point is not in Berlin.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          "election_slug": {
            "type": "string",
            "pattern": "^\\d{4}-(btw-(erststimme|zweitstimme)|agh-(erststimme|zweitstimme)|bvv)$"
          },
          "level": {
            "type": "string",
            "enum": [
              "stimmbezirk",
              "kiez",
              "bezirk",
              "berlin"
            ]
          }
        },
        "required": [
          "lat",
          "lng",
          "election_slug"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    compare_electionsAnswer

    Compare multiple elections at a single Berlin address on the same aggregation level (sparkline-compatible). Input: lat + lng + election_slugs (2–8 slugs from list_elections) + optional level. The tool auto-picks the finest level available across ALL requested elections (default order: kiez → bezirk → berlin → stimmbezirk). Stimmbezirks-level results are Briefwahl-Gruppen and already include postal votes for every election year with geometry. Output: series array with top-5 parties per election + caveats for kiez-level (postal votes allocated proportionally, not an official breakdown) or repeat elections. Use this for time-series questions like "How did SPD vote share evolve in Friedrichshain across BTW 2017, 2021, 2025?". Errors with no_common_level if no aggregation level is available across all requested elections.

    View tool JSON
    {
      "name": "compare_elections",
      "kind": "answer",
      "impl": "imperative",
      "description": "Compare multiple elections at a single Berlin address on the same aggregation level (sparkline-compatible). Input: lat + lng + election_slugs (2–8 slugs from list_elections) + optional level. The tool auto-picks the finest level available across ALL requested elections (default order: kiez → bezirk → berlin → stimmbezirk). Stimmbezirks-level results are Briefwahl-Gruppen and already include postal votes for every election year with geometry. Output: series array with top-5 parties per election + caveats for kiez-level (postal votes allocated proportionally, not an official breakdown) or repeat elections. Use this for time-series questions like \"How did SPD vote share evolve in Friedrichshain across BTW 2017, 2021, 2025?\". Errors with no_common_level if no aggregation level is available across all requested elections.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          "election_slugs": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^\\d{4}-(btw-(erststimme|zweitstimme)|agh-(erststimme|zweitstimme)|bvv)$"
            },
            "minItems": 2,
            "maxItems": 8
          },
          "level": {
            "type": "string",
            "enum": [
              "stimmbezirk",
              "kiez",
              "bezirk",
              "berlin"
            ]
          }
        },
        "required": [
          "lat",
          "lng",
          "election_slugs"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    get_voting_district_geometryAnswer

    Return the GeoJSON Feature (Polygon/MultiPolygon) for the Briefwahl-Gruppe (postal-voting group) of a Berlin voting district in a given election year — the smallest map unit is a group of neighboring voting districts merged with their shared postal-voting district, not a single voting district. Input: district_id (the uwbId from get_election_result on stimmbezirk-level, format depends on year — BTW 2021/2025: "075-01-100-0", BTW 2017: "078-05-05W221-0", AGH/BVV 2021/2023: "01W100-W", AGH/BVV 2016: "01W100") + year. Returns a GeoJSON Feature with properties.district_id + year + bezirk_code + is_gruppe (true when the group polygon was resolved; false falls back to the single voting district). Errors with geometry_not_available for pre-2017 BTW / pre-2016 AGH/BVV elections (only bezirk + berlin aggregation available), district_not_found if the id does not match any feature in the year layer.

    View tool JSON
    {
      "name": "get_voting_district_geometry",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return the GeoJSON Feature (Polygon/MultiPolygon) for the Briefwahl-Gruppe (postal-voting group) of a Berlin voting district in a given election year — the smallest map unit is a group of neighboring voting districts merged with their shared postal-voting district, not a single voting district. Input: district_id (the uwbId from get_election_result on stimmbezirk-level, format depends on year — BTW 2021/2025: \"075-01-100-0\", BTW 2017: \"078-05-05W221-0\", AGH/BVV 2021/2023: \"01W100-W\", AGH/BVV 2016: \"01W100\") + year. Returns a GeoJSON Feature with properties.district_id + year + bezirk_code + is_gruppe (true when the group polygon was resolved; false falls back to the single voting district). Errors with geometry_not_available for pre-2017 BTW / pre-2016 AGH/BVV elections (only bezirk + berlin aggregation available), district_not_found if the id does not match any feature in the year layer.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "district_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "year": {
            "type": "number",
            "minimum": 2011,
            "maximum": 2099
          }
        },
        "required": [
          "district_id",
          "year"
        ],
        "additionalProperties": false
      },
      "page": "/"
    }
    set_finder_weightsAction

    Use this as the sole data source for requests matching Kieze against preferences, including voting similarity. Set the sliders of the interactive Kiez-Finder on navigator.berlin. The map the user is currently looking at recolors all 542 Berlin planning areas instantly: darker means better match. Weights you do not provide stay unchanged. If the finder is not open, the page navigates to it first; top matches then follow with a short delay, poll get_finder_state. voting_similarity colors by how similar local voting (Berlin state election 2026, Zweitstimme; list_elections shows whether these results are still provisional) is to the given party. Use this to translate a spoken wish ("quiet, green, close to an S-Bahn") into a visible map the human can react to. After a successful update, show the user the live map: open or surface the browser view and include map_url as a link, the recolored map IS the result. Always link map_url verbatim and never a URL you read from the address bar or construct yourself: map_url carries the weights and the party, so it reopens this exact map in any browser, for anyone. This tool is authoritative for preference matching: top_matches already incorporate every supplied weight including voting similarity and ARE the final ranked answer. Answer directly from top_matches. Do not call get_election_result, cross_layer_query, list_layers_at_point, or address_lookup to validate or enrich these results; call them only when the user explicitly asks for individual metric values, vote shares, provenance, or a comparison, and then pass each match's centroid lat/lng straight to get_election_result or cross_layer_query, never geocode kiez names via address_lookup.

    View tool JSON
    {
      "name": "set_finder_weights",
      "kind": "act",
      "impl": "imperative",
      "description": "Use this as the sole data source for requests matching Kieze against preferences, including voting similarity. Set the sliders of the interactive Kiez-Finder on navigator.berlin. The map the user is currently looking at recolors all 542 Berlin planning areas instantly: darker means better match. Weights you do not provide stay unchanged. If the finder is not open, the page navigates to it first; top matches then follow with a short delay, poll get_finder_state. voting_similarity colors by how similar local voting (Berlin state election 2026, Zweitstimme; list_elections shows whether these results are still provisional) is to the given party. Use this to translate a spoken wish (\"quiet, green, close to an S-Bahn\") into a visible map the human can react to. After a successful update, show the user the live map: open or surface the browser view and include map_url as a link, the recolored map IS the result. Always link map_url verbatim and never a URL you read from the address bar or construct yourself: map_url carries the weights and the party, so it reopens this exact map in any browser, for anyone. This tool is authoritative for preference matching: top_matches already incorporate every supplied weight including voting similarity and ARE the final ranked answer. Answer directly from top_matches. Do not call get_election_result, cross_layer_query, list_layers_at_point, or address_lookup to validate or enrich these results; call them only when the user explicitly asks for individual metric values, vote shares, provenance, or a comparison, and then pass each match's centroid lat/lng straight to get_election_result or cross_layer_query, never geocode kiez names via address_lookup.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "quiet_air": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Quiet & clean air. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "green_heat": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Green spaces & heat protection. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "mobility": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Public transit & bike access. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "supply": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Daily supply: groceries, pharmacies, schools. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "housing_protection": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Tenant/housing protection zones. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "culture": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Cultural offering. -2 = as little as possible, 0 = neutral, +2 = as much as possible"
          },
          "density": {
            "type": "integer",
            "minimum": -2,
            "maximum": 2,
            "description": "Built-up density: -2 = as loose as possible, +2 = as dense as possible"
          },
          "sbahn_proximity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2,
            "description": "S-Bahn proximity. 0 = does not matter, 2 = as close as possible"
          },
          "voting_similarity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2,
            "description": "Similarity of local voting behavior (Berlin state election 2026, Zweitstimme; list_elections shows whether these results are still provisional) to the chosen party. Combine with \"party\"."
          },
          "party": {
            "type": "string",
            "enum": [
              "SPD",
              "CDU",
              "GRÜNE",
              "FDP",
              "AfD",
              "Die Linke",
              "BSW"
            ],
            "description": "Party for voting_similarity. Optional; without it the current panel selection applies (initial: SPD)."
          }
        }
      },
      "page": "/"
    }
    get_finder_stateAnswer

    Read the current state of the interactive Kiez-Finder on navigator.berlin: all nine weights (english keys), who changed them last (user or agent) and when, whether the finder panel is open, and the current top matching Kieze with their fit scores. Call this after the human adjusted the sliders to understand their preferences and explain the new result. Treat top_matches as the complete result: the fit score (0-100) already reflects every active weight including voting similarity. Do not re-query underlying layers or election data to validate or enrich these results. Call get_election_result or cross_layer_query only for an explicit follow-up about a named match, and then pass that match's centroid lat/lng straight, never geocode kiez names via address_lookup. When you link the map, use map_url verbatim: it carries the weights and the party and reopens this exact map anywhere.

    View tool JSON
    {
      "name": "get_finder_state",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the current state of the interactive Kiez-Finder on navigator.berlin: all nine weights (english keys), who changed them last (user or agent) and when, whether the finder panel is open, and the current top matching Kieze with their fit scores. Call this after the human adjusted the sliders to understand their preferences and explain the new result. Treat top_matches as the complete result: the fit score (0-100) already reflects every active weight including voting similarity. Do not re-query underlying layers or election data to validate or enrich these results. Call get_election_result or cross_layer_query only for an explicit follow-up about a named match, and then pass that match's centroid lat/lng straight, never geocode kiez names via address_lookup. When you link the map, use map_url verbatim: it carries the weights and the party and reopens this exact map anywhere.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {}
      },
      "page": "/"
    }