OpenApps

mapmap MCP server — tools & history

mapmap MCP server: observed open status, tool schemas, linked apps and version history.

mapmap

Endpoint: https://mcp.mapmap.ai/mcp

Observed status: open. Checked: 2026-10-13T05:11:47+00:00.

Linked apps

  • mapmap

    MapMap navigation platform for AI agents — 10 integration skills (routing, truck/ADR, web maps, map design, fleet optimisation, offline, self-host, x402 payments, migrations) plus the hosted MapMap MCP server. Includes an opt-in, consent-first integration-retro reminder hook (disabled by default).

Observed tools

  • camera_incidents — Road incidents a TRAFFIC CAMERA SAW and a vision model CONFIRMED, in force now: near a point (`near` [lat, lon] with `radius_m`, default 1000, at most 10000), in a `bbox` [min_lon, min_lat, max_lon, max_lat], or along a route `shape` (polyline6 from `route`, corridor `buffer_m` default 60). Give exactly one. Each record says what it asserts (`closed` or a `speed_override` in km/h) on which OSM ways and carriageway, what was seen (collision, stalled vehicle, wrong-way vehicle), the camera, the clip URL the verdict was made on (`evidence_url`), the verifier and its `confidence`, and when it lifts (`end`, always within minutes: these records expire on their own). Camera records RANK BELOW official closures and never retract one. READ `coverage_note` ALOUD: an empty list means no camera-verified incident here, NEVER a clear road. Show `attribution` verbatim (Powered by TfL Open Data). Off unless the deployment arms camera incidents (SN_CAMERA_INCIDENTS_ENABLED): an unarmed gateway answers 501 and says so. Requires the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY).
  • cheapest_charging_along_route — Find the best EV charge points along a route, with the REAL extra travel time of stopping at each one — never a straight-line guess. Provide `origin` + `destination` (a route is computed) or an existing route's `geometry_polyline6`, plus optional `connectors` ("ccs", "type2", "chademo", "type1", "tesla", "domestic", "other"), `min_kw` (e.g. 50 for rapid only), `available_only` and `max_detour_minutes` (default 10). Charge points come from operator-published feeds, are costed through the routing engine with your costing (a `truck` profile makes detours respect dimensional/ADR restrictions) and ranked most powerful first, since minutes off the clock are bought with kilowatts. Each result carries max_power_kw, connector_standards, best_connector, evse_count, detour_minutes/detour_km and, where a live feed backs it, available_now. IMPORTANT: there is no national charge-point registry — every deployment covers only the operators it has onboarded, so ALWAYS show the returned `coverage_note` alongside the results. An empty `results` means "none from these operators within the detour budget", NEVER "there are no chargers here". Statuses are live only when availability_live is true; otherwise they are the values captured at the last ingest and must not be described as current. `say` is ALWAYS present and is the whole answer as one short spoken line, composed by the gateway with the coverage already inside the claim rather than appended to it: it scopes its superlative to the operators this deployment holds, and an empty result's line says the emptiness is about those operators. Prefer reading it verbatim to writing your own summary. Requires the MapMap gateway; answers a clear error when the deployment has no charge-point dataset. Display the returned charging_attribution with the results.
  • cheapest_fuel_along_route — Find the cheapest fuel along a route, with the REAL extra travel time of stopping at each station — never a straight-line guess. Provide `origin` + `destination` (a route is computed) or an existing route's `geometry_polyline6`, plus a `fuel` code ("diesel" default, "petrol_95", "petrol_98", "premium_diesel", "e85", "lpg") and `max_detour_minutes` (default 10). Stations come from the live open-data price feeds (UK CMA retailer scheme and/or the statutory Fuel Finder, FR prix-carburants, DE Tankerkoenig; the response's `fuel_attribution` names the ones actually matched), are priced through the routing engine with your costing (a `truck` profile makes detours respect dimensional/ADR restrictions) and ranked freshest-priced first and cheapest within that. Each result carries price {value, currency, updated_at, stale}, detour_minutes/detour_km, and saving_per_litre vs the cheapest on-route baseline (pass `fill_litres` to also get saving_total). `stale` = not verifiably fresher than 24 h: true unless BOTH the price's own updated_at and the snapshot's fetch time are inside that window, and true whenever either is missing. A stale price is ranked below every fresh one, is never the baseline, and carries NO saving_per_litre — quote it as "last seen at X on <date>", never as a saving. `say` is ALWAYS present and is the whole answer as one short spoken line, composed by the gateway with the number, the detour and the honest qualifier already in it. Prefer reading it verbatim to writing your own summary: a stale price's line states the figure and the day it was last seen and claims no saving, and an empty result's line names the cause rather than implying there is no fuel on that road. Requires the MapMap gateway; answers a clear error when the deployment has no fuel-price dataset. Display the returned fuel_attribution with the prices.
  • check_adr_tunnel — Check whether a vehicle may pass through a tunnel of a given ADR category ("A"–"E"). Provide `hazmat` and, when known, the load's ADR 8.6.4 tunnel restriction code (e.g. "B", "C5000D", "B/D", "none"). Applies the conservative worst-case reading: conditional clauses are assumed to apply, so a blocked answer may over-restrict but never under-restricts. No network access; answers instantly.
  • check_clearance_on_route — Measure a vehicle's overhead clearance along a route against surveyed point cloud geometry, wherever survey coverage exists. Routes with truck costing (so the search already avoids the height restrictions the map has tagged), then measures that corridor. Give `origin`, `destination` and `height_m`; optional `width_m` asks the corridor-width axis too, and optional `margin_m` adds your operating margin to the vehicle before the verdict. Returns `pass`, `fail`, `indeterminate` or `no_verdict` with the limiting point, the measured headroom, its uncertainty bound (`safe_headroom_m`, `sigma_m`, `sampling_gap_m`) and a link to that exact view in the survey viewer. An `indeterminate` carries `indeterminate_reasons` as codes to branch on and the same reasons as English inside `explanation`; read out the English. A `pass` may carry no limiting point at all, which means the survey found nothing above that corridor, and the width axis may answer `not_assessed` where the corridor edges are too sparsely surveyed while the height axis still answers. Honesty, and it matters here: this measures physical geometry from a dated survey. It is not a signed or posted height, `clearance_enforcement.route_certified` is always false, and the caveat is on every answer including the clear one. Ground the survey did not cover comes back as `not_surveyed_m` and is never judged, so a `pass` is possible over complete coverage and nowhere else; sparse or stale coverage comes back separately as `insufficient_data_m`. Reach for this when a truck route came back unchanged and you need to know whether that means anything: an unchanged route avoids what the map records, which is a different claim from measured headroom, because a structure nobody tagged is routed through like open road. Needs the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY), which holds the surveys; there is no fallback, and it will not answer from the routing step alone. The mapmap://guide/clearance resource sets out what each answer proves.
  • check_style_contrast — Audit a map style's colour contrast against WCAG 2.1 (4.5:1 for label text, 3:1 for graphics like the route line), across both the light and dark palette variants. Pass a hosted `style_id` OR an inline `theme` document (as accepted by create_style). Advisory: failing pairs list the palette slots to adjust with set_palette; publishing is never blocked on contrast.
  • cluster — Group stops into balanced geographic clusters, so a day too large for one optimisation can be optimised one cluster at a time. This is the front half of the recipe for a thousand-stop day: cluster here, then call `optimise_routes` per cluster, where the routing engine's own matrix decides the visiting order. IMPORTANT — this is STRAIGHT-LINE clustering. Distances are measured between coordinates, not along the road network: no road, river, motorway junction or one-way system is consulted, and two stops either side of an estuary look adjacent. That makes it the right tool for deciding which stops belong TOGETHER and the wrong one for deciding what ORDER to visit them in. The answer carries a `basis` sentence saying exactly this; show it, so a centroid is never read as a plan. Provide `locations` ([{id, lat, lon, load?}], ids unique, at most 5,000) and EXACTLY ONE of `clusters` (how many groups, balanced by stop count), `max_cluster_locations` or `max_cluster_load` (a per-cluster ceiling the count is derived from). Optional `territories` keep a cluster from straddling a round: each is clustered on its own, and so are the stops inside none of them. Optional `seed` (default 42) drives the seeding — the same request with the same seed always returns the same clusters, on every deployment, so a re-run is a re-run. Returns each cluster's member ids, count, summed load, centroid and territory, plus a `balance` block naming the constraint applied and whether it had to be relaxed to place every stop: a load ceiling with lumpy loads is a bin-packing problem and may have no solution at the derived count. Requires the MapMap gateway.
  • create_style — Create a hosted map style. Provide a name, optionally a named `base` to start from (light, dark, streets, midnight, navigator-day, navigator-night, fleet, outdoor, dataviz, backdrop, print - call list_style_layers for what each one is for), and optionally a theme document ({base: "light"|"dark", palette: {slot: colour}, layers: {layer_id: overrides}}). The named base is laid down first and the theme document is merged over it, so "streets with darker water" is one call; with neither, the style starts from the default theme. A theme may also set worldview (ISO 3166-1 alpha-2, accepted: AE, KR, SA, US) to display that jurisdiction's official names for a small curated registry of renamed features; omitted, labels keep the OSM on-the-ground names. Returns the generated style_id (pass it to set_palette / set_layer_paint) and the compiled style URL for MapLibre.
  • elevation — Sample terrain elevation. Provide `points` (a bare list of coordinates) for point elevation, or `encoded_polyline` (optionally with `resample_distance_m`) for an along-route profile — not both. Returns one sample per point/resampled point in order; `elevation_m` is null wherever the engine's DEM tile set has no coverage at that point (never a guess). The `encoded_polyline` form also returns each sample's resampled lat/lon and cumulative `range_km` from the start.
  • geo_area — Area in square metres enclosed by a ring of 3+ coordinates, computed geodesically. Always positive: the answer does not depend on whether the ring is wound clockwise or anticlockwise. Intended for zones and boundaries, not for polygons covering more than half the globe. Local computation: no network call, no quota.
  • geo_bbox — The axis-aligned bounding box enclosing 1+ coordinates, as {min_lat, min_lon, max_lat, max_lon}. Useful for fitting a map view to a set of stops. Local computation: no network call, no quota.
  • geo_bearing — Initial bearing from one coordinate to another, in degrees clockwise from true north (0-360). This is the bearing at the START of the geodesic; over long distances the bearing changes en route. Local computation: no network call, no quota.
  • geo_centroid — The centroid (geometric mean position) of 1+ coordinates, e.g. to pick a depot location or centre a map. Local computation: no network call, no quota.
  • geo_destination — The coordinate reached by travelling `distance_m` metres from `from` on `bearing_deg` (degrees clockwise from true north). The inverse of `geo_distance` + `geo_bearing`. Local computation: no network call.
  • geo_distance — Distance in metres between two coordinates. Computed geodesically on the WGS84 ellipsoid, so it is the straight-line (as-the-crow-flies) distance, NOT a driving distance — use `route` or `matrix` for travel distance and time. Local computation: no network call, no quota.
  • geo_length — Total length in metres of a polyline through 2+ coordinates, summed geodesically. This measures the line you supply, NOT a driven route — use `route` for that. Local computation: no network call, no quota.
  • geo_nearest_point_on_line — The closest position on a polyline to a given coordinate, plus the geodesic distance to it in metres. The answer may lie between vertices, not only on them. Useful for 'how far is this address from the route?'. Local computation: no network call, no quota.
  • geo_point_in_polygon — Whether a coordinate lies inside a polygon: delivery zones, catchments, congestion or clean-air zones, site boundaries. Provide `point` {lat, lon} and `polygon` as 3+ {lat, lon} coordinates of the outer ring (closed automatically if the last does not repeat the first). Points exactly on the boundary count as OUTSIDE. Local computation: no network call, no quota.
  • geo_simplify — Reduce the number of coordinates in a polyline while keeping its shape (Douglas-Peucker). `tolerance_deg` is in DEGREES, not metres: about 0.0001 drops detail finer than roughly 10 m at the equator. Endpoints are always kept. Returns the retained points and how many were removed. Local computation: no network call, no quota.
  • geocode — Turn a place (address, POI, town) into coordinates. Ask two ways, and they combine: `query` is free text — one run-together string, the way a person types into a search box — and `street`, `housenumber`, `city`, `postcode` and `country` name the parts of an address separately. At least one of the two is required. Pass the parts whenever you already hold the address in parts (a form, a CRM row, a manifest): components are REQUIREMENTS, not hints, so `city: "London"` means a result outside London cannot come back at all, where "London" inside `query` only reorders. `country` takes an ISO 3166-1 alpha-2 code or a country name ("GB", "United Kingdom"); a value naming no country is refused rather than silently matching nothing. Returns up to `limit` (default 10) candidates with name, one-line label, lat/lon, type and address parts. Pass `focus` {lat, lon} to rank results near a location higher. A bare city or town name (no comma) lists that city's airports and main railway stations directly behind it, ahead of namesakes elsewhere. Each hit also carries `match`: a per-component matched/inferred/unmatched verdict, the `score_gap` to the runner-up, and which backend answered. READ IT before acting on an address — an unmatched or inferred postcode on the top hit means the answer does not carry the address you asked for, and a small `score_gap` means the ranking barely chose, so show the alternatives instead of picking one. Use `verify_places` when the address came from a model or a user and needs checking rather than using. Results are matched in `lang` (default "en"), so English exonyms — "Munich", "Cologne", "Geneva" — resolve to the place meant; pass `lang` when querying in another language, or "default" for each place's local name.
  • get_job — Read an asynchronous job submitted with `submit_optimise_job`: its status, and once it has finished, its result inline — exactly the body the synchronous tool would have returned. Status is `queued`, `running`, `succeeded` or `failed`; the answer's `terminal` field says whether the job will ever leave the status it is in, so poll while that is false. POLLING IS FREE: the gateway meters the submission and not the reads, deliberately, because a poll that costs quota is a poll a caller rations, and a rationed poll is how a job that finished in ten seconds gets noticed four minutes later. Check every few seconds rather than guessing at a duration. `units_charged` is what the SUBMISSION drew, and `refunded` says whether a failure handed it back — a failed job shows both, because reporting zero would be a lie about what was charged. Webhooks are the alternative to polling and exist for humans wiring infrastructure, not for agents in a loop. A job belongs to the key that submitted it (or another key of the same identity); anyone else's id answers NOT FOUND rather than forbidden, because confirming an id exists is itself a disclosure. Requires the MapMap gateway.
  • get_style — Fetch a hosted style's latest theme document (the editable source) and the URL of its latest compiled MapLibre style. Use the theme to inspect current palette and layer overrides before editing.
  • get_usage — Check what your own API key has spent, so you can decide mid-task whether to keep going. Reading it is free: it costs no quota. Optional `from` and `to` (YYYY-MM-DD UTC, inclusive, at most 92 days apart) bound the report; omitted, it covers the current month to date. Returns `days` (per-day, per-endpoint), `totals` per endpoint over the range, `total_units`, plus `month_used_units` against `monthly_quota_units` and the prepaid `balance_millipence` (thousandths of a penny). Everything is counted in UNITS — weighted quota units, where a heavier endpoint costs more than one unit per request — so never report these figures as a number of calls. When `identity_pooled` is true the quota is shared with the other keys belonging to the same owner, so these figures are not yours alone. The key that authenticates the call is the key reported on: there is no way to read another caller's usage. Needs the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY).
  • heritage_narration — Three to five short spoken lines an hour about the ground a route is on: one sentence, at the point the driver reaches the thing it is about, and then silence. Not a tour and not a chatbot. NOTHING IS GENERATED HERE: every line is a sentence a person wrote from a public-domain plaque inscription and a person reviewed, compiled into the gateway binary, so no model runs in this path and the lines are identical for every driver. Give `geometry_polyline6` from the `route` tool and, IMPORTANT, `duration_s` from the same answer: without it the silence budget falls back to a distance, and "four lines an hour" is a claim about time that a distance answers wrongly at both ends. Optional `min_gap_s`, `min_gap_m`, `max_offset_m` (default 60, hard ceiling 80), `max_lines` and `voice_format` ("opus" or "m4a", which adds each line's audio cache key and URL and NEVER synthesises). COVERAGE IS ONE CORRIDOR, deliberately: the Chelsea riverside, 18 reviewed lines over 5 km. EVERY OTHER ROUTE ANSWERS WITH NO LINES, and that is a correct answer rather than a failure. ALWAYS READ THE CENSUS, which is the record of WHAT WAS NOT SAID: no lines with every entry in `beyond_reach` means this feature does not cover the journey; no lines with entries in `silenced_by_budget` means the corridor is covered and the budget is holding them back. They are different answers and must never be relayed the same way. On the reference route the census reports 1 spoken and 17 silenced, which is the design working, not a thin corpus. Every line publishes `offset_m`, the measured distance from the plaque to the route, because it is the entire warrant for the word "here", and `plaque_ids` so any claim can be taken back to its source. TWO OMISSIONS ARE DELIBERATE: no line says anything is visible, still standing or unchanged (a plaque records that somebody was somewhere, and nothing more), and NO LINE SAYS WHICH SIDE OF THE ROAD anything is on, because nothing in the source records it and a look that finds nothing spends the driver's trust in everything else. Do not add either. COSTS 1 UNIT a call: it reads no tiles and opens no archive. Requires the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY).
  • list_place_categories — List the canonical place categories you can pass as `category` to `nearby_places` and `search_along_route` (and browse on with `geocode`). Each entry is a `category` token (the exact value to send, e.g. "fuel", "charging_station", "hgv_parking"), the `aliases` that colloquially name it ("petrol station", "EV charger", "lorry park"), and a one-line `description` of what it covers. Read this before guessing a category: a token that is not on this list matches nothing, and quietly returns an empty result rather than an error. Cuisines, brands and names are NOT categories — search those as free text. Sorted by category and identical on every call. Local lookup, no network, no quota.
  • list_style_layers — List everything a MapMap style theme can style: the first-party named bases a style can start from (pass one as `create_style`'s `base`, or as the static-map API's `style=`), the named palette slots with their light/dark default colours, the skeleton layer ids (paint order) that `set_layer_paint` accepts, the OpenMapTiles source-layers extra layers may reference, the insertion slots (`bottom`, `middle`, `top`) an extra layer may name, and the rules for a theme's own `sources` (your data by https URL). Attribution is enforced on every compiled style and cannot be themed away. Local lookup, no network; always works.
  • match_trace — Snap a recorded GPS trace to the road network and say what it actually travelled over. Provide `shape` (2 to 2000 recorded points, oldest first) or `encoded_polyline` (the same trace as a polyline6 string) — not both — plus the `costing` it was travelled under: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". Costing decides which roads the trace may match onto, so a walk matched as "auto" snaps to the carriageway rather than the footpath. Returns the matched path as `geometry_polyline6` (the snapped roads, not your raw points) with its `distance_m` and `duration_s`, then the roll-ups: `by_road_class` and `by_admin` (distance and time, longest first), `by_surface` (distance), and `toll`, `bridge` and `tunnel` totals. This is how you turn a dashcam or telematics log into a report — which country and region the driving happened in, how much of it was motorway, how much was tolled, how much was unpaved. Honesty: the roll-ups are summed per matched road segment, so they need not add up to `distance_m` exactly, and segments the map records no surface or admin area for are left out of that breakdown rather than filed under a guess — an entry in `by_admin` with null codes is exactly that, counted and not attributed. Needs the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY); there is no direct-backend fallback.
  • matrix — Compute a travel time/distance matrix between origins (rows) and destinations (columns). Costing "auto", "truck" (with optional `truck` profile as in `route`), "bicycle", "pedestrian" or "motor_scooter". Returns durations_s[i][j] in seconds and distances_m[i][j] in metres; null cells are unreachable pairs. Up to 10,000 cells per call (origins × destinations). Optional `exclude_polygons` for before/after scenarios ("close this bridge and recompute the matrix"): an array of polygons, each an array of [lon, lat] pairs forming one ring — longitude FIRST — whose intersecting roads are excluded from every cell's path finding. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored.
  • nearby_places — Find places near a point, nearest first with distance in metres — by category (cafes, fuel, EV charging, parking), by name or brand ("the nearest Lloyds bank", "nearest Sainsbury's"), or both. Use this instead of geocode whenever the question is about what is NEAR a location: geocode ranks a brand's branches everywhere and only biases by proximity, so it will happily return a Lloyds in another city over the one 100 m away. Provide `lat`, `lon` and at least one of `category` or `name`. `category` is matched against the map's lowercased OSM tag values (amenity/shop/tourism/…), e.g. "cafe", "fuel", "charging_station", "parking", "pharmacy", "supermarket", "hotel", "restaurant", "fast_food", "atm", "bakery", "hospital", "station"; common colloquial names are normalised ("coffee" -> cafe, "ev_charging" -> charging_station, "petrol" -> fuel, "chemist" -> pharmacy). `name` matches the place's name or alternative names word by word, case- and accent-insensitively, with the last word also matching as a prefix. Combine the two to disambiguate a brand — "Lloyds" plus "bank" excludes Lloyds Pharmacy. A category or name the map does not carry returns an empty list, never an error. Optional `radius_m` (default 2500, max 100000) bounds the straight-line search distance and `limit` (default 5, max 10) the result count. Each result has name, one-line label, lat/lon, address parts, distance_m, categories and a `details` object of display tags (opening_hours, website, phone, ...) when the map carries them. Every result also carries `bearing_deg` and a spoken `direction`. Pass `heading_deg` (degrees clockwise from true north, 0 = north, 90 = east) and results are described from where the user stands — "ahead and slightly to your right, about 80 metres" — with a signed `relative_bearing_deg` (negative left, positive right); without a heading the phrasing falls back to cardinals ("to the north-east"), so this works with or without a compass. Add `fov_deg` to keep only what lies within that cone of the heading — it is the FULL width of the cone, so 90 keeps what lies within 45 degrees either side of dead ahead; anything dropped is counted in `out_of_view`, so a non-zero count means there ARE matching places nearby, just not in front of the user — say that rather than "nothing nearby". Prefer reading `direction` aloud over coordinates. Requires the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY).
  • nearby_stops — England bus and coach stops near a point, nearest first. Pass `lat` and `lon` (WGS84), optional `radius_m` (1 to 2,000, default 500) and `limit` (1 to 50, default 10). Each stop carries its NaPTAN ATCO code `id` (pass it to `next_departures`), `name`, `indicator` (e.g. "Stop S"), `locality`, position, `distance_m` and `bearing_deg` from the point, and `lines`, the line names the Bus Open Data timetables have calling there. Bus and coach only: rail, tram, metro and ferry stops are not included, and coverage is England (plus stops just across a border that an England service calls at). Display data, never a journey plan: pass on the returned `label` and `coverage`. Requires the MapMap gateway; a deployment without the stops index answers a clear error. Display the returned `attribution` (NaPTAN and BODS, Open Government Licence v3.0).
  • next_departures — Timetabled bus departures at one stop, from the Bus Open Data (BODS) timetables. Pass `stop` (the NaPTAN ATCO code `nearby_stops` returns), optional `at` (RFC 3339, default now; the index holds three service days from today), `window_minutes` (1 to 180, default 60) and `limit` (1 to 30, default 8). Each departure carries `line`, `destination`, `operator`, `scheduled_at` (local time) and `trip`, plus `live` when a vehicle on that line was seen in the live positions within 3 km and heading towards the stop (`vehicle`, `distance_m`, `age_s`). These are TIMETABLE times: `basis` is always "timetable", and a live entry is an observation, never an arrival time or a delay. MapMap does not predict arrivals: never present `scheduled_at` or `live` as one, and pass on the returned `label` and `coverage` verbatim. Requires the MapMap gateway; a deployment without the departures index answers a clear error. Display the returned `attribution` (NaPTAN and BODS, Open Government Licence v3.0).
  • optimise_routes — Optimise multi-vehicle, multi-stop delivery plans (VRP). Provide `vehicles` (id, start/end, capacity, skills, time_window), `jobs` (id, location, service_s, delivery/pickup, skills, time_windows) and/or `shipments` (pickup+delivery pairs that ride the same vehicle). Costing "auto", "truck", "bicycle", "pedestrian" or "motor_scooter" (cargo-bike and courier fleets welcome): with a `truck` profile (dimensions + ADR declaration, as in `route`), the travel-time matrix respects dimensional and dangerous-goods restrictions, so every optimised route is truck-legal. Returns a summary, unassigned tasks and per-vehicle routes with ordered steps (arrival_s/duration_s in seconds, distance_m in metres). Fair use: at most 200 unique locations per problem, and no wider than the routing engine's matrix span (1,500 km on the hosted endpoint for motor costings, 400 km stock on a self-host). Past that, cluster the stops with `cluster` and optimise each group, or submit the whole problem to the asynchronous lane with `submit_optimise_job` (2,000 locations). Optional `territories` are named polygons ([{id, polygon}], GeoJSON [lon, lat] rings, LONGITUDE FIRST) that bound who serves what: a vehicle listing `territory_ids` may serve a task only if that task sits inside at least one of the territories it names, while a vehicle listing none is unrestricted and may serve anything, inside a round or outside every one. The response's `territories` block says which vehicle was eligible for what and names any task no vehicle could take. A vehicle may also declare `reloads` {max_trips 2-5, reload_time_s, depot?} to return to a depot, reload and go out again — the tipping round. It needs a `time_window`, because the shift is what gets split: it is cut into that many consecutive non-overlapping windows separated by the reload time, each trip carrying the vehicle's FULL capacity and task caps. That split is fixed BEFORE the solve, so the plan is conservative and never optimistic — it cannot put a lorry in two places at once — but it is an approximation: a trip that finishes early cannot lend its spare time to the next, so stops can come back unassigned that a truly sequential model would have served, and `max_trips` is a budget rather than a prediction (ask for five on a shift that supports three and every window shrinks to a fifth). Read the returned `reloads` block before quoting arrival times, and re-plan after each tip with `replan_routes` for the tighter answer. `relax_if_unassigned` {time_windows_by_s?, allow_overtime_s?} re-solves ONCE with those relaxations if the first plan left work unassigned, and the `relaxation` block says honestly which plan came back: at most one second solve, never beyond the caps stated, and the relaxed plan is returned ONLY if it assigns more work than the first. Breaks are never widened — a driver's rest is not a preference to trade for a fuller van — and neither are capacities, skills, territories or task caps; only time windows move. It bills as two solves when the second one runs. Always check `relaxation.relaxed_plan_used` before telling anyone the day fits: a plan produced under relaxation has had promises moved. `emissions` {vehicle_category, fuel, euro_standard} annotates the plan with the clean-air zones its own stops sit in and what this vehicle pays in each; add `avoid_zones: true` to steer the travel-time matrix out of them, which changes the plan itself. Territories, reloads, relaxation and zones are computed by the MapMap gateway; without one configured the tool refuses rather than returning a plan that quietly ignored them.
  • order_stops — Put a single run's stops in the best visiting order ("order my errands"). Provide `start` {lat, lon} and `stops` (1-100 entries of {location, label?, service_s?}); optionally an `end` destination or `round_trip`: true to return to the start. Costing "auto" = car, "truck" = lorry (pass `truck` as in `route` for a truck-legal order). Returns the stops in visit order with arrival offsets in seconds, plus total duration and distance.
  • places_in_view — What is over THERE: given a position and the direction the user is facing, the places inside that cone, and whether the ground and the buildings in between let them actually be seen. Use this for "what is that over there", "is there a pub in that direction", "what am I looking at". Use `nearby_places` instead when the question is about what is NEAR a point rather than what is in a direction. Provide `lat`, `lon`, `bearing_deg` (degrees CLOCKWISE FROM TRUE NORTH: 0 north, 90 east, 180 south, 270 west) and at least one of `category` or `name`; `category=building` reaches named buildings. Optional `fov_deg` is the FULL width of the cone (default 60, so 30 degrees either side), `radius_m` the range (default 1000, max 5000), `eye_height_m` the observer's eye height (default 1.6). Each result carries `distance_m`, `bearing_deg`, a signed `angular_offset_deg` (negative left, positive right), a spoken `direction`, and a `visibility` block. READ THE VISIBILITY BLOCK BEFORE SAYING ANYTHING: `clear` means nothing in the data stands in the way, `occluded` names what does (a hill, or a building with its height), and `unknown` means NO check could run: with `unknown` say you cannot tell, never that it is visible. Read `basis` too: `terrain-only` in a town means hills were checked and buildings were not, which is weak. A non-zero `out_of_sector` means there ARE matching places nearby, just not in that direction, so say that rather than "nothing nearby". `coverage` names the datasets that answered and `caveat` is the standing limit: visibility is modelled from maps, not observed, and trees, walls, scaffolding and weather are not in it. Requires the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY).
  • plan_day — Turn an itinerary into one navigable multi-stop route. Provide a `start` and `stops` (each a `location` {lat, lon} or a free-text `name` to geocode, plus optional `dwell_minutes` time at the stop), optional `depart_at` (RFC 3339) for absolute ETAs, `optimise: true` to reorder stops for the shortest day (VROOM solver), and `return_to_start`. Costing "auto", "truck" (with a `truck` profile the whole day respects dimensional/ADR restrictions), "bicycle", "pedestrian" or "motor_scooter". Returns the stops in visit order with per-leg duration/distance and arrival/departure times, totals, and the full route geometry (polyline6). Geocoded names carry a `resolution` — when `ambiguous` is true, check `alternatives` and re-run with an explicit location rather than trusting the guess.
  • plan_errands — Order a handful of errands against a hard arrival time, and say honestly whether they fit. This is the "pick up a prescription, get petrol, and be at the school by quarter past three" tool. Give `origin`, `destination` (+ `destination_name`), `arrive_by` (RFC 3339 with an offset: convert "quarter past three" yourself), optional `depart_at`, and 1 to 5 `errands`. Each errand is EITHER a `category` (a kind of place: "pharmacy", "fuel", "supermarket", or a colloquial phrase the server normalises; use `list_place_categories` for the vocabulary) OR a `place` {lat, lon} the driver already knows ("the school", "the nursery"). Resolve a named place with `geocode` first and pass the coordinate: never invent one. Optional `dwell_minutes` per errand (default 5). The server chooses the order and the actual shops, exhaustively, over engine-computed travel times -- do NOT attempt the ordering or the arithmetic yourself. IMPORTANT: `feasible: false` is an ANSWER, not an error to retry. It names the errand that costs the most (`blocking_errand`), says how late the whole chain would be (`over_by_s`), and returns the stops of the chain that DOES fit with `dropped` naming what had to go. Tell the driver what to drop. Every stop is a real indexed place carrying its id: never mention a shop the answer did not return. `hours` is "open_on_the_tag" (the map's tag covers your arrival, which is evidence and not a promise) or "unknown" (most places carry no hours at all); a place the tag proves shut is never proposed. ALWAYS show `usage_note`: this is planned before setting off or by a passenger, never at the wheel. Requires the MapMap gateway.
  • plan_ev_route — Plan a whole electric-vehicle journey, charge stops included. Give `origin` and `destination` (plus optional `waypoints`) and a `vehicle` — a published profile ("small_hatch", "saloon", "suv", "van") and/or inline figures (battery_kwh, mass_kg, drag_area_m2, aux_kw, connectors) — with `start_soc` (default 0.9), `min_arrival_soc` (default 0.1), `reserve_soc` (default 0.1, the floor the charge must never drop below mid-route), optional `connectors` and `min_kw` filters and `ambient_temperature_c`. Energy comes from a published road-load physics model over the route's own legs; charge times are integrated over the vehicle's charging curve capped by the charge point, NOT energy divided by peak power, which is the single biggest error in naive EV planners. Returns the stops with arrive/depart state of charge, charge time and detour, a per-leg state-of-charge trace, and the journey's driving and charging time. IMPORTANT: when no plan exists — a charger desert, a connector mismatch, a gap wider than the car's range — the answer comes back with `feasible: false`, a `reason` and the furthest point on the route the car can actually reach. That is an ANSWER, not an error to retry: report the reason and never describe it as a plan. `gradient_data` says whether elevation was available: "absent" means consumption was modelled on the flat and under-reads a hilly route. There is no national charge-point registry, so ALWAYS show the returned `coverage_note` — an infeasible plan means "none from these operators", never "there are no chargers here" — and statuses are current only when `availability_live` is true. Requires the MapMap gateway; answers a clear error when the deployment has no charge-point dataset. Display the returned charging_attribution with the plan.
  • reachable_area — Compute the area reachable from an origin within one or more travel-time budgets — walkability/cyclability rings. Costing "pedestrian" answers "how far can I walk in 15 minutes?", "bicycle" the cycling equivalent; "auto", "truck" and "motor_scooter" work too (e.g. delivery coverage). `contours_minutes` lists the ring boundaries in minutes (1-10 values, each up to 120); set `polygons` true for filled polygons ready to render as a map fill layer instead of contour lines. Returns a GeoJSON FeatureCollection, one feature per contour. Optional `exclude_polygons` for before/after scenarios ("close this bridge and recompute reachability"): an array of polygons, each an array of [lon, lat] pairs forming one ring — longitude FIRST — whose intersecting roads are excluded from the reachability search. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored.
  • replan_routes — Re-plan a fleet part-way through its shift. Send the day back; nothing is stored. MapMap holds NO dispatch state — no plan, no vehicle position, no completion log — so a re-plan is not a delta against something we remember: you pass the ORIGINAL `optimise_routes` problem in full, plus `progress` (per vehicle: `completed_stop_ids` IN THE ORDER SERVED, an optional `current_position`, and `unavailable: true` for a breakdown or an end of hours) and/or `changes` (`cancel_job_ids`, `add_jobs`, `add_shipments`), and get a fresh plan for what is left. That costs bandwidth and buys the absence of a server-side plan that can go stale, leak, or fall out of step with the telematics platform that actually owns the truth — and it makes a re-plan reproducible: the same body always yields the same answer. Completed stops are LOCKED by construction: they are removed from the problem entirely and each vehicle starts from where it actually is, so the solver cannot move a stop that has already happened — a guarantee the solver cannot break, rather than a hint it is free to ignore. At least one progress entry or one change is required. Returns the same plan shape as `optimise_routes` for the REMAINING work, plus a `replan` block: the prefix locked per vehicle, where each re-plans from and how that was decided, stops released from a vehicle that can no longer serve them, tasks forced unassigned, and a note for every id that did not resolve. Read that block — a stop that vanished from the plan is named there rather than left for a dispatcher to notice at four in the afternoon; a cancelled id that matched nothing is reported there too rather than refused. Multi-trip vehicles cannot be re-planned: a completion does not say which trip it belongs to, so a problem whose vehicles declare `reloads` is refused with what to send instead. Billed on the remaining problem, not the original. Requires the MapMap gateway.
  • report_map_issue — Report that the live world disagrees with the map — a closed road, a wrong or missing restriction, a bad speed limit, a missing road, a wrong one-way, or changed access. Use it when you observe the mismatch mid-task. Provide `location` {lat, lon}, a `category` (road_closed, wrong_restriction, wrong_speed_limit, missing_road, wrong_oneway, access_changed, other) and optionally a `description`, the OSM `way_id` and an `evidence_url`. This is a first-party observation: it is QUEUED for human/agent review and NEVER changes routing immediately or edits any map. Returns the queued report_id.
  • reverse_geocode — Turn coordinates into the nearest places: addresses, POIs and localities with distance in metres. The inverse of geocode. Provide `lat` and `lon`; returns up to `limit` (default 5, max 10) results, nearest first, each with name, one-line label, lat/lon, type, address parts and distance_m, plus categories and a `details` object of display tags (opening_hours, website, phone, wikipedia, ...) on POI hits when the index carries them. Every result also carries `bearing_deg` and a spoken `direction`. Pass `heading_deg` (degrees clockwise from true north, 0 = north, 90 = east) and results are described from where the user stands — "ahead and slightly to your right, about 80 metres" — with a signed `relative_bearing_deg` (negative left, positive right); without a heading the phrasing falls back to cardinals ("north-east of you"), so this works with or without a compass. Add `fov_deg` to keep only what lies within that cone of the heading — it is the FULL width, so 90 keeps what lies within 45 degrees either side of dead ahead; anything dropped is counted in `out_of_view`. Prefer reading `direction` aloud over coordinates.
  • route — Compute a turn-by-turn route between origin and destination (optionally via waypoints). Costing "auto" = car, "truck" = lorry, "bicycle", "pedestrian" = walking, "motor_scooter" = moped. Pass `truck` {height_m, width_m, length_m, gross_weight_t, hazmat, tunnel_code} to apply dimensional limits and the ADR dangerous-goods tunnel matrix to the search; `pedestrian` {use_lit 0-1, type "wheelchair"|"blind", max_hiking_difficulty 1-6} for lit-street walking, accessibility and trail limits; `bicycle` {bicycle_type, use_roads 0-1, use_living_streets 0-1, avoid_bad_surfaces 0-1, use_hills 0-1} for quiet-ride and surface preferences. Returns distance (m), duration (s), maneuvers, polyline6 geometry and the ADR costing that was applied. Any of truck, auto, bicycle, pedestrian or motor_scooter routes may set `rationale: true` (opt-in, costs up to 1 + N extra routing calls) to learn which declared truck constraints or avoidance-side preferences (hills, surfaces, tolls, unlit streets, …) actually changed the route (`rationale.avoided[]`, basis route_divergence — it proves a field was binding, it does not identify the physical restriction or feature, and no live traffic or incident data is ever attributed). ADR honesty: `applied_adr.forbidden_tunnel_categories` describes the LOAD, not the returned route, and `applied_adr.tunnel_enforcement` states the boundary: roads are excluded only where the routing graph records an ADR tunnel category, so an unchanged route is not a clearance. Set `landmarks: true` for turn instructions anchored to recognisable places — each manoeuvre that passes one gains a `landmark_instruction` like "Turn right just after the Shell garage" beside the engine's own street-name `instruction`, which is never replaced. Prefer reading it aloud: it is how a passenger gives directions. Nothing is named unless it is recognisable from the road, within 40 m of the junction and not tagged as closed, so many routes return none and a `landmarks.annotated` of 0 with no `note` means this route genuinely passes nothing recognisable. Needs the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY), whose place index does the lookup. Through the gateway each manoeuvre also carries the road it starts on: `country`, `subdivision`, `ref` (route numbers only), `road_class`, `speed_limit_unit` (`mph` or `km/h`, from the road's country), `speed_limit_sign` (`vienna` or `mutcd`), `speed_limit_posted` (the limit as the sign shows it, in the road's unit) and `driving_side`; each is absent when the map does not know it, never guessed. Optional `exclude_polygons` for what-if scenarios ("close this bridge and re-route"): an array of polygons, each an array of [lon, lat] pairs forming one ring — longitude FIRST — whose intersecting roads are excluded from the search. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored. Optional `avoid` and `exclude` name road features to keep off, and the difference between them is not cosmetic. `avoid` ("tolls", "highways", "ferries") is a PREFERENCE: it sets the costing's willingness to zero, and the engine's own reference says that is not guaranteed to avoid the feature — measured, avoiding tolls across the Dartford Crossing returns the same tolled route, because the untolled alternative is fifty kilometres further. `exclude` ("tolls", "highways", "ferries", "bridges", "tunnels") is a hard exclusion: it can answer NO ROUTE rather than a detour, and it depends on the routing engine's own hard-exclusion setting, which the engine does not report and this server cannot read — so it is requested, never promised. "tolls" and "highways" under `avoid` exist only on motorised costings; asking for one on a bicycle is refused rather than silently ignored. Whatever is applied comes back in `avoidance`, with the caveats — relay them, because "avoid tolls" read as a guarantee is the failure mode here. Each location also takes a kerbside approach: `preferred_side` "same" (alias "curb") stops on the door's side of the road, resolved against the locale's driving side — the left kerb in the UK, the right in Germany — with "opposite" and "either" (alias "unrestricted") for the rest. It is a snapping preference, not a manoeuvre guarantee, and it needs a coordinate genuinely offset from the road centreline; `street_side_tolerance_m` and `street_side_max_distance_m` bound the window in which it applies, and a pair leaving no window is refused rather than answered with the preference silently inert. Pass `emissions` {vehicle_category, fuel, euro_standard} for UK clean-air-zone assessment: the response's `zones` block then names every zone the route enters and what THIS vehicle pays there, with the publishing authority cited. Without it a zone can only be named, never priced. Needs the gateway, which holds the curated zone dataset; the whole dataset — every scheme, charge, boundary and provenance record — is readable at `GET /v1/zones` on the HTTP API when an agent needs to audit a figure or list zones without routing. Set `scenic: true` (auto costing only) to ask whether there is a prettier way. It is a PEER OFFER, never a substitution: the route in `geometry_polyline6` is byte-for-byte what the same request returns without the flag, and the prettier way, when there is one, arrives beside it in `scenic`, with its own geometry in `scenic.alternative_geometry_polyline6` and what it costs in `scenic.spoken` ("About seven minutes longer than the quick way"). EVERY OFFER STATES ITS REASON OR THERE IS NO OFFER: a route that scores well but cannot support a plain sentence is dropped rather than dressed up, so a `scenic.reason` of null means nothing here measured above the floor. That is an ANSWER, not a failure, and it is the one to relay. A REJECTION IS ALSO AN ANSWER: every candidate that lost says why in `scenic.rejections[]` (`same_route`, `no_scenic_gain`, `not_scenic_enough`, `over_time_budget` with the minutes it would have cost, `nothing_to_say`), so "no prettier way" is always attributable and raising the budget is an informed choice. It is a re-ranking of routes the engine already proposed, not a scenic search: a beautiful road the engine never offered was never considered, and `scenic.caveats` says so. Like `rationale`, IT COSTS EXTRA METERED COMPUTATIONS, at most two, which is why it is opt-in and never on by default. `available: false` with a `note` means this deployment could not look, which is not the same claim as nothing being there. Needs the gateway, whose basemap archive the scoring is measured against.
  • route_observations — What a journey PASSES, in sentences ready to be read aloud, each with its position along the route. The named rivers and canals it crosses, the road it runs on and for how far, the settlements it goes through, the protected landscapes it enters and how high the road climbs: the things a passenger who knew the area would say. NONE OF THIS IS IN A ROUTE: a route is a list of movements and a river crossing is not a movement, so do not try to read it out of `route`'s answer. Give `geometry_polyline6` straight from the `route` tool, plus optional `units` ("miles" default, or "kilometers"), `min_gap_m` and `max_observations`. Each observation carries `at_m` (WHERE it belongs (delivered anywhere else it is trivia, not an observation), a `kind`, a `say` sentence to relay verbatim, and a `basis` naming the map layer and tag the claim rests on. THE SILENCE BUDGET IS THE DESIGN: `min_gap_m` is a floor, not a target, and when a route yields more than `max_observations` the gap WIDENS on its own so the survivors stay spread over the whole journey rather than clustering where the map happened to be richest. Inside a window the rarer kind wins. So a short list on a long route is the budget working, not thin data. READ `coverage` BEFORE REPORTING AN EMPTY LIST: an empty `observations` with `tiles_read` of 0 means NO DATA WAS READ, which is not the same claim as quiet countryside, and `uncovered_m` says how much of the route could not be seen at all. Two things it will never say, deliberately: it never names a hill (a peak two kilometres away behind a ridge is named confidently and seen by nobody), and it never reads a junction number (an observation mistakable for an instruction is not safe to speak beside real guidance). A settlement is a labelled POINT, not a boundary, and `offset_m` publishes the distance behind the word "through". It is a query and it triggers nothing: no position is held and nothing is pushed. COSTS 10 UNITS a call, flat, whatever is asked for. Requires the MapMap gateway (GATEWAY_URL + GATEWAY_API_KEY), whose basemap archive and elevation model answer it; a deployment with no archive answers 501 and says so.
  • search_along_route — Find places (POIs) along a route with the REAL extra travel time of stopping at each — never a straight-line guess. Provide `origin` + `destination` (a route is computed) or an existing route's `geometry_polyline6`, plus a free-text `query` ("coffee", "EV charger", "truck stop") and `max_detour_minutes` (default 10). For a category intent ("fuel", "EV charger", "coffee") pass `category` instead of relying on words alone: it takes the same vocabulary as `nearby_places` (lowercased OSM tag values such as "fuel", "cafe", "charging_station", "parking", "pharmacy"), and common colloquial phrases are normalised server-side ("petrol station" and "gas station" to fuel, "coffee" to cafe, "EV charger" to charging_station). `query` alone also promotes a pure category phrase to the same browse, so "fuel" finds fuel stations rather than places whose NAME starts "Ful"; anything else stays free-text name matching. When a browse ran, the response echoes the tokens used in `matched_categories`. Candidates near the route corridor are priced through the routing engine with your costing: detour = (origin→place) + (place→destination) − (origin→destination). Costing "auto", "truck" (with a `truck` profile the detours respect dimensional/ADR restrictions), "bicycle", "pedestrian" or "motor_scooter". Returns results sorted by detour with detour_minutes, detour_km, along_route_position (0-1) and off_route_m; at most 25 candidates are priced per call (candidate_cap).
  • set_layer_paint — Set one MapLibre paint property on one skeleton layer of a hosted style (e.g. layer_id "road-major", property "line-width", value 4 or an expression array) and publish the result as a new immutable style version. Layer ids come from list_style_layers. Returns the new version and style URL.
  • set_palette — Recolour one or more palette slots of a hosted style (e.g. {"water": "#0b2038", "roadMajor": "#8a6d3b"}) and publish the result as a new immutable style version. Slot names come from list_style_layers; colours are CSS (#rgb/#rrggbb/#rrggbbaa/rgb()/hsl()). Returns the new version and style URL.
  • set_temporary_closure — OPERATOR WRITE, ADMIN ONLY. Asserts a short-lived closure (`assert: {kind: closed}`) or speed (`{kind: speed_override, speed_kph}`, 1 to 120) on named OSM `way_ids` (1 to 20) and `direction` (forward, backward or both, default both), for `ttl_secs` (60 to 86400), with a `reason` and an optional `evidence_url`. The record expires on its own, ranks below official closures and is logged with the reason. NEVER CALL THIS WITHOUT A PERSON'S EXPLICIT APPROVAL OF THIS EXACT CLOSURE IN THIS CONVERSATION: draft it, show it, stop, and call it only after a yes. Available only where the operator runs sn-mcp locally with SN_CAMERA_INCIDENTS_ENABLED=true and SN_ADMIN_TOKEN set; everywhere else it refuses and says why. Whether a live traffic writer applies it is reported in `applied_by_live_writer`; false means the record is stored but no road changes.
  • submit_integration_retro — Send MapMap a structured integration retro (problems, gotchas, wins, docs gaps). Call at most once, after your MapMap integration works or you stop trying, and only if the developer has approved sending feedback to MapMap. Sends ONLY the structured fields in this schema to MapMap: there is no field for a transcript, a prompt, source code, file contents or coordinates. The free-text fields are short and capped, but they are still free text: do NOT paste code, credentials, customer names or personal data into them. Provide `what_built` (required), `problems` [{area: sdk|api|mcp|docs|billing|self-host|other, description, workaround_found}], `gotchas`, `wins`, `docs_gaps`, and optionally `agent_name` and `sdk_version`.
  • submit_optimise_job — Submit a problem too large to solve inside one request to the asynchronous lane, and get a job id back. Set `kind` to "optimise", "replan" or "matrix", and pass `problem` in EXACTLY the shape the matching synchronous tool takes — `optimise_routes` input, `replan_routes` input, or `matrix` input. Moving a working synchronous call onto this lane changes nothing but which tool you call it with. A field that tool's input does not have is REFUSED by name rather than dropped: the HTTP API accepts some the MCP tools have not surfaced yet, and a job queued without a constraint you asked for is worse than one that was never queued. The ceilings are far higher here because there is no request to hold open: 2,000 unique locations for an optimisation or re-plan against the synchronous 200, and 40,000 matrix elements against 10,000 (a deployment may set either lower, in which case its own refusal is the authority). A re-plan is counted on the REMAINING problem, after completed stops are removed, so a shift well through its day may fit where the morning's would not. This answers 202-and-a-job-id, NOT a plan: the job is queued and a worker picks it up. Poll `get_job` with the returned id until it says the status is terminal, then read the result. Polling is free — the gateway meters this submission, not the reads. Units are charged on submission and handed back in full if the job fails. The optional `webhook_url` (https only) posts a SIGNED notification when the job finishes and is for a human wiring infrastructure that must react without a process watching; it carries a pointer, never the result, and needs a webhook signing secret on the key. An agent that can poll should not use it. Requires the MapMap gateway.
  • validate_geodata — Check whether a dataset's DECLARED coordinate reference system actually describes its own coordinates, before you draw it on a map. Catches the failures that are otherwise silent: swapped lat/lon axes, degrees labelled as metres, and Web Mercator or another projection mislabelled with a UTM or national-grid code. Pass the declared CRS (e.g. "EPSG:4326") and a sample of the raw coordinates as {x, y} in the dataset's OWN units — deliberately not named lon/lat, because whether they are degrees is the question. Returns a verdict (consistent / suspect / impossible), what is wrong in plain language, and where the numbers actually point when read another way. This is a sanity check, not a reprojection: it never transforms coordinates. Local computation: no network call, no quota.
  • verify_places — Check whether places (and itineraries) an AI mentioned are real, findable and physically possible. Pass structured `claims` (reliable, and the only path that supports itinerary feasibility) or free `text` (best-effort quoted-phrase extraction). Each claim resolves to exactly one of three verdicts, never a boolean: "verified" (matched a real place, with its stable id and the source/date of the evidence), "contradicted" (a specific, dated, sourced fact rules it out — currently only an itinerary leg the routing engine proves cannot be driven in the stated time, with the computed travel time as evidence), or "unverified" (no evidence either way). This tool NEVER asserts that a named real business does not exist or has closed — that would be a defamation risk with no upside; a missing match is always "unverified". Claims sharing increasing `sequence` values and both carrying `claimed_time` (ISO 8601) form itinerary legs checked for feasibility via `matrix`, catching e.g. "breakfast in Bath, 10am meeting in Edinburgh". Max 20 claims per request. The response's `summary` field is a concise plain-text digest — also returned as this tool result's text content — so clients that drop structured/non-text content blocks still see the verdicts.
  • weather_along_route — Forecast weather along a route, each sample read for the hour you actually reach it rather than the weather right now. Pass the route's `shape` (an encoded polyline6, the `route` tool's geometry_polyline6), optional `depart_at` (RFC 3339, default now), the route's `duration_s` (from `route`; omitted, an 80 km/h average is assumed and `duration_source` says so) and optional `sample_interval_m` (default 25,000, 5,000 to 100,000, at most 40 samples). Each sample carries its ETA, temperature, rain, snowfall, precipitation type and probability, wind and gust speed, visibility, the WMO weather code and `severe` (thunderstorm and heavy precipitation codes only). It is a FORECAST, not an observation: read on a 0.05 degree grid (about 5.5 km) at the nearest hour, up to 16 days ahead, and samples past that horizon or without data come back `available: false` with a reason, never painted dry. `summary` is one sentence (where rain or snow starts and for how far, the strongest gust, samples without data) and always ends by saying it is advisory, never a routing guarantee: keep that qualifier when you pass it on. Requires the MapMap gateway; a deployment without a weather source answers a clear error. Display the returned `attribution` with the forecast (CC BY 4.0).

Data as of 2026-10-13T05:11:47+00:00.

OpenApps records store listings and observed changes. Store ranks are not download counts; launch dates may be derived or use the first observation. Coverage gaps are shown in the interactive catalog.

REST API specification · Guide for AI clients · Manage API keys and MCP connections