MapMap
Server Details
Maps built for agents: routing incl. truck/ADR, geocoding, matrices, isochrones — 34 tools.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
Available Tools
43 toolscheapest_charging_along_routeAInspect
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. Requires the MapMap gateway; answers a clear error when the deployment has no charge-point dataset. Display the returned charging_attribution with the results.
| Name | Required | Description | Default |
|---|---|---|---|
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; the detours then respect dimensional/ADR restrictions. | |
| min_kw | No | Keep only charge points whose best connector is rated at least this many kW (e.g. 50 for rapid charging only). | |
| origin | No | Route origin (with `destination`, when no geometry is given). | |
| costing | No | Costing model for the route and detour matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| connectors | No | Keep only charge points offering at least one of these connector standards: "type2", "type1", "ccs", "chademo", "tesla", "domestic" or "other". Omitted ⇒ every standard. | |
| destination | No | Route destination. | |
| max_results | No | Maximum results (default 5, at most 25). | |
| available_only | No | Keep only charge points with a bay reported free right now. Needs the deployment to have a live availability feed; without one the call is refused rather than silently returning nothing. | |
| geometry_polyline6 | No | An existing route geometry as an encoded polyline6 (the `route` tool's `geometry_polyline6`). Provide either this or `origin` + `destination`, not both. | |
| max_detour_minutes | No | Largest acceptable detour in minutes (default 10, at most 120). |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Why `results` is empty, when it is — the cause, not a bare list. |
| costing | Yes | The costing the detours were computed with. |
| results | Yes | Charge points within the detour budget, most powerful first (power, then detour). |
| sources | Yes | Every operator in the dataset, with its own coverage note and licence. Present even when `results` is empty. |
| candidate_cap | Yes | The matrix fan-out cap in force. |
| coverage_note | Yes | **Always present.** What this deployment's charge-point dataset does and does not cover. An empty `results` means "none from these operators within the budget" — never "there are no chargers here". Show this to the user alongside the results. |
| route_length_m | Yes | Length of the route geometry in metres. |
| route_distance_m | No | Direct origin→destination distance in metres. |
| route_duration_s | No | Direct origin→destination travel time in seconds (same estimator as the detour legs), when routable. |
| availability_live | Yes | Whether statuses are live (a bring-your-own availability feed) or the values captured at the last ingest. |
| availability_note | Yes | Plain-language explanation of what the statuses mean here. |
| candidates_costed | Yes | Candidates actually costed through the engine (fan-out capped at `candidate_cap`, most powerful kept). |
| max_detour_minutes | Yes | The detour budget applied, minutes. |
| charging_attribution | No | Attribution string for the charge-point operators actually returned — display it with the results (a licence obligation). |
| candidates_considered | Yes | Charge points matching the filters that passed the corridor pre-filter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so thoroughly. It discloses the operator-feed limitation, the absence of a national registry, the meaning of empty results, stale vs live statuses, the need to show coverage_note and charging_attribution, and the gateway/dataset error case. This is exemplary behavioral disclosure for a tool with no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence contributes: purpose, input modes, filtering options, behavioral caveats, output fields, and mandatory display instructions. It is front-loaded with the core value proposition and structures the key usability warnings (empty results, stale statuses, attribution) clearly. Length is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no annotations, the description covers everything an agent needs: how to specify the route, filter options, detour semantics, coverage limitations, live-data conditions, error behavior, and required display of coverage_note and charging_attribution. An output schema exists and the description even summarizes the returned fields, so no critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100% and the schema already documents each parameter, so the baseline is 3. The description adds genuine integration logic beyond the schema: origin+destination vs geometry_polyline6 as alternatives, truck profile making detours respect dimensional/ADR restrictions, ranking by power, and the availability_live caveat for returned statuses. It does not add much beyond the schema for max_results and costing, but the added recipe-level guidance justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: finding EV charge points along a route, with real detour time rather than straight-line estimates. The phrase 'best EV charge points along a route' clearly differentiates it from fuel, geospatial, and nearby-place siblings, and the output focus on detour_minutes/detour_km gives it a distinctive identity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains when to call it: given origin+destination or an existing route's geometry_polyline6, with optional filters. It also gives important context such as available_only requiring a live feed and the MapMap gateway/no-dataset error behavior. It does not explicitly name alternatives like plan_ev_route or cheapest_fuel_along_route, so it lacks explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cheapest_fuel_along_routeAInspect
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 cheapest first. Each result carries price {value, currency, updated_at, stale} (stale = not verifiably fresher than 24 h), detour_minutes/detour_km, and saving_per_litre vs the cheapest on-route baseline (pass fill_litres to also get saving_total). Requires the MapMap gateway; answers a clear error when the deployment has no fuel-price dataset. Display the returned fuel_attribution with the prices.
| Name | Required | Description | Default |
|---|---|---|---|
| fuel | No | Which fuel to price: "diesel" (default), "petrol_95", "petrol_98", "premium_diesel", "e85" or "lpg" (aliases "petrol", "unleaded", "e10", "super_unleaded", "e5", "b7" and "sdv" are accepted). | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; the detours then respect dimensional/ADR restrictions. | |
| origin | No | Route origin (with `destination`, when no geometry is given). | |
| costing | No | Costing model for the route and detour matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| destination | No | Route destination. | |
| fill_litres | No | Optional fill size in litres; each result then also carries `saving_total` = `saving_per_litre` × `fill_litres`. | |
| max_results | No | Maximum results (default 5, at most 25). | |
| geometry_polyline6 | No | An existing route geometry as an encoded polyline6 (the `route` tool's `geometry_polyline6`). Provide either this or `origin` + `destination`, not both. | |
| max_detour_minutes | No | Largest acceptable detour in minutes (default 10, at most 120). |
Output Schema
| Name | Required | Description |
|---|---|---|
| fuel | Yes | The normalised fuel code that was priced (e.g. "diesel"). |
| costing | Yes | The costing the detours were priced with. |
| results | Yes | Stations within the detour budget, cheapest first (price, then detour). |
| baseline | Yes | The cheapest effectively-on-route option per currency (empty when no station sits on the route itself). |
| candidate_cap | Yes | The matrix fan-out cap in force. |
| route_length_m | Yes | Length of the route geometry in metres. |
| fuel_attribution | No | Attribution string for the fuel-price data sources actually returned — display it with the prices (a licence obligation). |
| route_distance_m | No | Direct origin→destination distance in metres. |
| route_duration_s | No | Direct origin→destination travel time in seconds (same estimator as the detour legs), when routable. |
| candidates_costed | Yes | Candidates actually priced through the engine (fan-out capped at `candidate_cap`, cheapest kept). |
| max_detour_minutes | Yes | The detour budget applied, minutes. |
| candidates_considered | Yes | Stations selling the fuel that passed the corridor pre-filter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full burden of behavioral disclosure, and it delivers: it names live open-data feeds, defines the stale flag as 'not verifiably fresher than 24 h', explains ranking by cheapest first, documents the error when no dataset exists, and states how truck costing affects detour restrictions. It also surfaces the 'never a straight-line guess' guarantee.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: value proposition first, then route input, then data sources, then output fields and error behavior. Every sentence adds useful context, though it is somewhat long and partially echoes schema descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 optional parameters and an output schema, the description covers the essential invocation modes, defaults, data provenance, result fields, error handling, and even an agent-facing display instruction. Minor omissions like max_results are already fully documented in the schema, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds extra meaning beyond the schema: it explains the mutual exclusivity of geometry_polyline6 vs origin+destination, that fill_litres produces saving_total, the effect of truck profiles on detours, and the default/alias behavior of fuel codes. Some repetition of schema text prevents a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find the cheapest fuel along a route', and immediately distinguishes itself from any generic routing or place-search tool by emphasizing real detour times rather than straight-line guesses. This clear scoping separates it from siblings like search_along_route and nearby_places without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete invocation guidance: provide origin+destination, or geometry_polyline6, plus fuel code and max_detour_minutes, and states the MapMap gateway prerequisite. It does not explicitly name alternatives or provide when-not conditions, so it stops short of a 5, but the usage context is otherwise clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_adr_tunnelAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| hazmat | Yes | Whether the vehicle carries dangerous goods at all. When false the ADR tunnel matrix does not apply and every tunnel is permitted. | |
| tunnel_code | No | ADR 8.6.4 tunnel restriction code of the load, e.g. "B", "C5000D", "B/D", or "(—)"/"none". Leave unset for a hazmat load of unknown code (conservatively treated as code B). | |
| tunnel_category | Yes | ADR category of the tunnel to check: "A", "B", "C", "D" or "E". |
Output Schema
| Name | Required | Description |
|---|---|---|
| reason | No | Why passage is forbidden (present only when blocked); cites the ADR 8.6.4 rule that applied. |
| decision | Yes | Whether passage is allowed or blocked. |
| explanation | Yes | Human-readable explanation of how the decision was reached, including the conservative worst-case reading. |
| forbidden_tunnel_categories | Yes | ADR tunnel categories this load is forbidden from under the worst-case reading (conditional clauses assumed to apply). Empty when unrestricted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden and succeeds: it states the conservative worst-case reading ('a blocked answer may over-restrict but never under-restricts') and operational traits ('No network access; answers instantly'). This is exactly the kind of behavioral context agents need beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, purpose front-loaded in the first ('Check whether a vehicle may pass through a tunnel...'), with every sentence earning its place. No fluff; the behavioral caveat and operational notes are tightly packed in the final sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, parameter usage, interpretation semantics, and operational behavior, while the output schema covers return values and the input schema covers all parameters. Slightly more could be said about edge-case handling (e.g., unrecognized tunnel codes), but nothing essential to selecting or invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters; baseline is 3. The description adds marginal value by reinforcing which parameters to supply and giving code examples ('B', 'C5000D', 'B/D', 'none'), though these overlap with the schema's own examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Check whether a vehicle may pass through a tunnel of a given ADR category ("A"–"E")'. The ADR tunnel category scope clearly differentiates it from geo siblings like check_clearance_on_route, which concerns route clearance rather than hazmat tunnel restrictions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use case (determining hazmat tunnel passage) and instructs what to provide ('Provide hazmat and, when known, the load's ADR 8.6.4 tunnel restriction code'), but it never explicitly contrasts with alternatives such as check_clearance_on_route or states when not to use it. Usage context is present but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_clearance_on_routeAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| origin | Yes | Route origin. | |
| width_m | No | Vehicle width in metres. Supplying it asks the width axis as well as the height axis; the width answer is reported separately and is never a headroom. | |
| height_m | Yes | Vehicle height in metres. Required: there is no default vehicle, because a default vehicle is how somebody gets an answer about a lorry that is not theirs. | |
| margin_m | No | Operating margin in metres, added to the height before the verdict is decided (default 0). Your compliance policy, not ours: the measured figure and the safe bound are both reported whatever you set here, and the margin is echoed back. It is applied to the measurement, not to the routing step, where the map's own posted heights already carry a margin of their own. | |
| destination | Yes | Route destination. |
Output Schema
| Name | Required | Description |
|---|---|---|
| basis | Yes | Always `"surveyed_geometry_not_signage"`. |
| width | Yes | The width axis, answered separately when `width_m` was given. |
| verdict | Yes | `pass`, `fail`, `indeterminate` or `no_verdict` for the height axis. A `pass` is possible over completely surveyed ground and nowhere else: unsurveyed ground yields `no_verdict`, never a pass. |
| datasets | Yes | The surveys drawn on, with their capture dates and staleness. |
| limiting | No | The limiting point on a `fail`, the tightest point on a `pass`, the worst contested point on an `indeterminate`. Absent on a `no_verdict`, and absent on a `pass` where the survey found nothing at all above the corridor. |
| view_url | No | Deep link to that exact view in the survey viewer, so the reading can be looked at rather than taken on trust. |
| advisories | Yes | Notes on stretches of the route: vegetation age, a reading limited by a wire, a seam between surveys. |
| assessed_m | Yes | Metres of route measured against survey data good enough to decide on. |
| explanation | Yes | What was measured, when, with what bound, and what the tool declined to conclude. It may over-restrict; it never under-restricts. |
| not_surveyed_m | Yes | Metres of route no survey covers. This is the absence of a measurement, and it is never the same statement as a measured open sky. No verdict is drawn over it. |
| resolution_hint | No | What would resolve an `indeterminate`, in one sentence, as the measuring service phrased it. |
| route_distance_m | Yes | Length of the route the vehicle was routed over, metres. |
| route_duration_s | Yes | Estimated driving time for that route, seconds. |
| geometry_polyline6 | Yes | The route as a six-digit-precision encoded polyline, so the same shape can be drawn or re-measured without routing again. |
| insufficient_data_m | Yes | Metres of route a survey covers but too sparsely, or too stale, to decide on. Also an absence, and reported apart from `not_surveyed_m` because the two have different remedies. |
| clearance_enforcement | Yes | What this answer does and does not prove. Read it. |
| indeterminate_reasons | Yes | Why an `indeterminate` could not be called, as machine-readable codes (`inside_uncertainty_band`, `vegetation_age_exceeded`, `artefact_stale`, `artefact_freshness_unchecked`). Empty on every other verdict. These are for branching on, not for reading out: the same reasons appear as English in `explanation`, and a person shown `artefact_freshness_unchecked` has been failed by whatever displayed it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it discloses dated-survey limitations, that route_certified is always false, how coverage gaps return not_surveyed_m and insufficient_data_m, and how pass/fail/indeterminate/no_verdict correspond to physical evidence. It even flags that a pass may have no limiting point and that width can return not_assessed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and nearly every sentence adds functional or caveat information. It is quite long and has rhetorical and grammatical turns ('Honesty, and it matters here'; 'Routes with truck costing... then measures that corridor') that keep it from being optimally concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the lack of annotations, the description is remarkably complete: it names all required and optional inputs, explains verdict semantics, uncertainty fields, coverage handling, authentication requirements, and where to find further guidance. An agent has enough information to call the tool correctly and interpret all answer types.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers parameters at 100%, so the baseline is 3. The description adds useful meaning by explaining that margin_m is applied to the measurement rather than the routing step, that width_m is reported separately and never as headroom, and that there is no default vehicle height, though it adds little new detail for origin and destination.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Measure a vehicle's overhead clearance along a route against surveyed point cloud geometry.' It also distinguishes itself from map-tagged height restrictions and sibling tools like check_adr_tunnel by clarifying it measures physical surveyed geometry, not posted or signed heights.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete trigger: 'Reach for this when a truck route came back unchanged' and states prerequisites (MapMap gateway, no fallback). However, it does not explicitly name an alternative sibling tool or say 'do not use this for posted height checks,' so the when-not guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_style_contrastAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| theme | No | …or an inline theme document (as accepted by `create_style`). Exactly one of `style_id`/`theme` must be given. | |
| style_id | No | Hosted style id whose latest theme should be checked… |
Output Schema
| Name | Required | Description |
|---|---|---|
| passes | Yes | True when every audited pair meets its WCAG threshold. |
| findings | Yes | Every audited pair, failing pairs first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the two palette variants checked, the exact thresholds, that failing pairs list slots to adjust, and that contrast never blocks publishing. It does not explicitly state it is read-only, but 'Audit' and 'Advisory' imply no mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three front-loaded sentences carry purpose, input, thresholds, and advisory behavior with no filler. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has only two parameters, an output schema exists, and the description supplies thresholds, input alternatives, palette variants, and follow-up guidance via set_palette. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the exactly-one-of style_id/theme rule and theme format. The description adds only a concise restatement and a pointer to create_style, which is useful but not a major increment over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Audit'), a precise resource ('a map style's colour contrast'), and an explicit standard (WCAG 2.1 thresholds for label text and graphics). This clearly distinguishes it from sibling tools like check_adr_tunnel or set_palette.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear invocation condition ('Pass a hosted style_id OR an inline theme document') and directs failed pairs to set_palette. It lacks an explicit 'when not to use' contrast, but the advisory note that publishing is never blocked on contrast conveys the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clusterAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for the k-means++ seeding (default 42). The same request with the same seed always returns the same clusters, on every deployment. | |
| clusters | No | How many clusters to produce, balanced by stop count. Give exactly one of `clusters`, `max_cluster_locations` or `max_cluster_load`. | |
| locations | Yes | The stops to group. Ids must be unique; at most 5,000. | |
| territories | No | Optional territories. Given, no cluster straddles one: each territory is clustered on its own, and so are the stops inside none of them. | |
| max_cluster_load | No | At most this much summed `load` per cluster; the cluster count is derived from it. A load ceiling with lumpy loads is a bin-packing problem and may have no solution at the derived count — the response says so rather than pretending. | |
| max_cluster_locations | No | At most this many stops per cluster; the cluster count is derived from it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| basis | Yes | The method statement: this is STRAIGHT-LINE clustering. Distances are between coordinates, not along roads — two stops either side of an estuary look adjacent. Show it. It is the sentence that stops a centroid being read as a plan. |
| balance | Yes | The constraint applied, the largest cluster produced, and whether the ceiling had to be relaxed to place every stop. |
| clusters | Yes | The clusters: each with its `id`, member `locations` (your ids), `count`, summed `load`, `centroid` and the `territory` it belongs to. |
| parameters | Yes | The seed, the cluster count, the locations seen, how many territories were used, the iterations run and whether it converged. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it delivers richly. It discloses the key behavioral trait: 'STRAIGHT-LINE clustering' with no road, river, or one-way system consulted, including the estuary example. It also discloses determinism across deployments, the bin-packing relaxation behavior, the `basis` output caveat, and the MapMap gateway requirement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is long, every sentence earns its place: purpose, recipe, critical caveat, parameter rules, determinism promise, balance-block explanation, and gateway dependency. It is front-loaded with the use case and the key straight-line warning, and uses bold markers to guide attention. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a 6-parameter tool with an output schema. It covers the recipe's place in the workflow, the clustering distance model, the exact-one parameter selection, determinism, how territories interact, the bin-packing relaxation possibility, and the required gateway. Since an output schema exists, the description's brief summary of the response shape is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already documents every parameter thoroughly. The description adds emphasis (e.g., 'EXACTLY ONE of') and restates the derived-count logic, but it does not add materially new meaning beyond the schema's own parameter descriptions. A score of 3 reflects that the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Group stops into balanced geographic clusters,' and immediately explains the purpose with the one-cluster-at-a-time use case. It distinguishes itself from siblings by explicitly saying it is the 'front half of the recipe' and the 'right tool for deciding which stops belong TOGETHER and the wrong one for deciding what ORDER to visit them in,' contrasting with optimise_routes and order_stops.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is fully explicit: use cluster when a day is 'too large for one optimisation,' then 'call `optimise_routes` per cluster.' It gives an exclusion rule — straight-line clustering makes it wrong for ordering — and names the specific alternative to use for order. It also states the exact-one-of constraint among `clusters`, `max_cluster_locations`, and `max_cluster_load`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_styleAInspect
Create a hosted map style. Provide a name and optionally a theme document ({base: "light"|"dark", palette: {slot: colour}, layers: {layer_id: overrides}}); omitted, 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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Human-readable style name; its kebab-case slug seeds the style id. | |
| theme | No | Optional theme document (palette/layer overrides). Omitted, the style starts from the default theme carrying `name`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| theme | Yes | The theme document that was stored. |
| version | Yes | The published version (always 1 on create). |
| style_id | Yes | The generated style id — pass it to `set_palette`, `set_layer_paint` and `get_style`. |
| style_url | Yes | Immutable URL of the compiled style at this version. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It explains default-theme behavior, optional worldview filtering with accepted ISO codes, fallback to OSM on-the-ground names, and the return format. It does not cover auth, persistence, or rate limits, but the core side effects are clearly described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense but efficient paragraph with the main purpose front-loaded. It is slightly long because of the worldview detail and return-value explanation, but every sentence contributes actionable information rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and a schema that under-describes the theme object, the description is self-sufficient. It covers required input, optional theme structure, accepted worldview codes, default behaviors, output values, and even names sibling tools that consume the returned style_id.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high, placing the baseline at 3, but the description adds meaningful detail: it expands the theme parameter into its structure ({base, palette, layers}), enumerates accepted worldview values, and clarifies what happens when each optional parameter is omitted. This goes beyond the schema's generic theme description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening phrase 'Create a hosted map style' is a specific verb+resource pair that clearly distinguishes this from sibling tools such as get_style, list_style_layers, set_palette, and set_layer_paint. It also states the main output (style_id and compiled style URL), removing ambiguity about the tool's role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: provide a name, optionally supply a theme document, and rely on defaults when omitted. It even tells the agent that the returned style_id should be passed to set_palette/set_layer_paint, which implies a create-then-modify workflow. It does not explicitly list when not to use the tool, but the workflow guidance is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
elevationAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | No | Points to sample. Provide this or `encoded_polyline`, not both. | |
| encoded_polyline | No | A route as a Google encoded polyline with six digits of precision. Provide this or `points`, not both. | |
| resample_distance_m | No | Resamples `encoded_polyline` at this spacing in metres before sampling height (ignored for `points`). |
Output Schema
| Name | Required | Description |
|---|---|---|
| samples | Yes | One sample per input point (or per resampled shape point, in the `encoded_polyline` form), in order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full disclosure burden. It states that one sample is returned per input point in order, that `elevation_m` is null for missing DEM coverage 'never a guess,' and that polyline inputs additionally return resampled lat/lon and cumulative `range_km`. This is unusually honest and useful behavioral detail for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences cover the operation, the two input modes, mutual exclusivity, output ordering, missing-data behavior, and polyline-specific outputs. The high-level purpose is front-loaded, and every clause adds information. There is no filler or repetition of schema text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a terrain sampling tool: it covers both input modes, the output contract, missing-data semantics, and extra polyline outputs, while the output schema handles return fields. Nothing an agent needs to invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents each parameter, including mutual exclusivity and the meaning of `resample_distance_m`. The description adds a small amount of relational context by grouping the parameters into 'point elevation' and 'along-route profile,' but it does not substantially extend what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the exact verb and resource: 'Sample terrain elevation.' It immediately distinguishes the tool's two modes (point sampling and along-route profile), which sets it apart from nearby routing and geospatial analysis tools. The phrasing is specific enough that an agent can match the tool to elevation queries without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly instructs when to provide `points` versus `encoded_polyline` and explicitly warns 'not both.' It also notes that `resample_distance_m` only applies to polyline input. It does not mention alternative sibling tools or state when not to use this tool, but the mode-selection guidance gives agents a clear operational context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_areaAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | Yes | The coordinates to consider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| area_sq_m | Yes | Enclosed area in square metres, always positive regardless of winding order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral load and does it well: geodesic computation, always-positive sign, winding-order independence, and local computation with no network or quota impact. It does not mention behavior on invalid input such as fewer than 3 points, but this is a minor gap for such a simple pure function.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four compact, front-loaded sentences each earn their place: result and units, sign behavior, intended scope, and execution characteristics. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single required parameter and an output schema, so the description doesn't need to explain return conventions. It supplies the key contextual facts—geodesic method, area unit, positive result, half-globe limitation, and local execution—leaving only minor edge-case behavior unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents `points` and the `lat`/`lon` fields completely, so the baseline 3 applies. The description adds useful context like 'ring' and the 3+ requirement, but it doesn't elaborate on ordering, precision, or repeated closing coordinates—details that would be extra value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation—computing enclosed area in square metres from a geodesic ring of 3+ coordinates—making it instantly distinguishable from line-measurement siblings like geo_distance and geo_length. The '3+ coordinates' condition further defines the expected input resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear intended use ('zones and boundaries') and an explicit exclusion ('not for polygons covering more than half the globe'). It stops short of naming alternative tools for that exclusion, but the guidance is sufficient for an agent to understand when this tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_bboxAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | Yes | The coordinates to consider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| max_lat | Yes | Maximum latitude (north edge). |
| max_lon | Yes | Maximum longitude (east edge). |
| min_lat | Yes | Minimum latitude (south edge). |
| min_lon | Yes | Minimum longitude (west edge). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It adds valuable context by stating that the computation is local, involves no network call, and consumes no quota. It does not cover edge cases like empty input, but the '1+' constraint mitigates that concern.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences deliver the output format, primary use case, and key performance trait without any filler. The essential definition is front-loaded, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a pure local computation with a single well-documented parameter and an output schema, the description is complete. It explains what the tool returns, why an agent would use it, and that it has no network or quota implications. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents the single `points` parameter at 100% coverage, including the LatLon structure. The description adds little parameter-level meaning beyond the '1+' minimum, so the schema does the heavy lifting. This matches the baseline score for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly defines the tool as computing an axis-aligned bounding box and explicitly gives the output shape {min_lat, min_lon, max_lat, max_lon}. This distinguishes it from sibling geo tools like geo_centroid, geo_area, and geo_distance with specific, non-tautological language.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete use case: fitting a map view to a set of stops. It does not explicitly name alternatives or say when not to use this tool, but the context is clear and actionable enough for an agent to select it appropriately among geometry siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_bearingAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | End coordinate. | |
| from | Yes | Start coordinate. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bearing_deg | Yes | Initial bearing from `from` to `to`, degrees clockwise from true north, normalised to 0–360. Note this is the bearing at the start of the geodesic: over long distances the bearing changes en route. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It transparently discloses that the computation is local (no network call, no quota) and explains a key behavior: the bearing changes en route over long distances. It does not mention error handling, but for a pure calculation the disclosed behavior is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero fluff. The core purpose is front-loaded, and the important caveat about initial bearing follows immediately. The local computation note is a useful extra. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple calculation tool with an output schema, the description covers the essential aspects: what it computes, the unit, the geodesic nuance, and the local nature. It doesn't mention potential edge cases (e.g., antimeridian), but that is minor and not expected for such a tool. The provided context is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — both 'from' and 'to' are described in the schema as start/end coordinates, and the LatLon object defines lat/lon. The description adds no new parameter semantics beyond restating the schema. Given the high coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (calculate initial bearing) with a clear resource (one coordinate to another) and defines the output in degrees clockwise from true north. It is unambiguous, but it does not explicitly differentiate from sibling tools like geo_destination or geo_distance, despite the clarity of the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by clarifying that the bearing is at the START of the geodesic, which hints that this is not for constant bearing over long distances. However, it does not explicitly mention when to use this tool versus alternatives, nor does it name any sibling tools. The guidance is implicit rather than direct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_centroidAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | Yes | The coordinates to consider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| point | Yes | The computed coordinate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It explicitly states local computation with no network call and no quota, which is valuable transparency for an agent deciding whether invocation is safe or costly. It does not discuss edge cases such as antimeridian handling, but the simple pure-computation nature and available output schema mitigate the gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. The core definition and example are front-loaded, and the computational transparency is stated succinctly at the end.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple pure function with one well-documented parameter and an output schema, the description is largely complete: it covers purpose, input cardinality, use cases, and local execution. It could still mention what happens with a single coordinate or edge-case behavior, but the low complexity means these are minor omissions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds semantic meaning beyond the schema by specifying '1+ coordinates' and clarifying that they are combined as a geometric mean. This helps the agent understand constraints and intended input semantics beyond the raw parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation as computing the centroid, or geometric mean position, of coordinates. The examples of picking a depot or centring a map make the purpose immediately understandable, and it is distinct from sibling geometry tools like geo_bbox, geo_area, and geo_bearing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives example use cases ('pick a depot location or centre a map') which imply when to use it. However, it does not explicitly contrast this tool with related siblings or state when not to use it, so the guidance is implied rather than direct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geocodeAInspect
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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Structured component: town or city, e.g. "London". Matches the containing city as well as the immediate locality, so a suburb name works here too. | |
| lang | No | Language of the place names to match and return, as a two-letter code. Defaults to "en", which is what makes English exonyms ("Munich", "Cologne", "Geneva") resolve to the place meant rather than a same-named town elsewhere. Set it to the language your query is written in; "default" asks for each place's own local name. Deployments support a fixed set (this one: "en", "de", "fr"), and anything outside it is refused. | |
| focus | No | Optional location bias: results near this point rank higher. | |
| limit | No | Maximum number of results (1–50, default 10). | |
| query | No | Free-text place query, e.g. "Dover ferry terminal". Required unless at least one structured component is supplied. | |
| street | No | Structured component: street name, e.g. "Downing Street". Matches the street of addresses and POIs (transliterated street names included) as well as the street itself. | |
| country | No | Structured component: ISO 3166-1 alpha-2 code or country name — "GB", "gb", "United Kingdom" and "UK" all mean the same country. A value naming no country is refused rather than quietly applied as a filter that matches nothing. | |
| postcode | No | Structured component: postcode in any spacing or case — "SW1A 2AA" and "sw1a2aa" are one query. A bare UK outward code ("SW1A") selects the whole district. | |
| housenumber | No | Structured component: house number, e.g. "10" or "221B". Only meaningful alongside `street` — a house number on its own excludes nearly everything and identifies nothing. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | Matching places, best first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It explains that structured components are REQUIREMENTS not hints, that invalid countries are refused, that English exonyms resolve under the default lang, and that each result includes match verdicts, score_gap, and backend. This goes far beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but each sentence carries substantive guidance: operation, dual query modes, strictness semantics, result fields, match interpretation, and language behavior. It is front-loaded with the core purpose and maintains a logical progression from invocation to interpretation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero annotations and nine parameters, the description is remarkably complete. It explains return contents, candidate ranking, match semantics, language handling, and when to prefer a sibling tool. With a rich input schema and output schema also present, nothing essential appears missing for an agent to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already explains most parameters, so the baseline is 3. The description adds valuable semantics on top: the requirement that at least one of query/structured components is supplied, the contrast between requirements and hints, and the practical implications of focus and language choice. Some parameter detail duplicates the schema, so it is not a perfect 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Turn a place (address, POI, town) into coordinates.' It clearly distinguishes geocode from sibling tools by naming verify_places as the alternative for checking addresses and framing this tool as the conversion of places into coordinates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: pass structured parts when you already hold an address in parts, use verify_places when the address came from a model or user and needs checking, and show alternatives instead of picking a top hit when score_gap is small. This is direct usage routing, not just implied context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_destinationAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| from | Yes | Starting coordinate. | |
| distance_m | Yes | Distance to travel in metres. | |
| bearing_deg | Yes | Bearing in degrees clockwise from true north. |
Output Schema
| Name | Required | Description |
|---|---|---|
| point | Yes | The computed coordinate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It adds 'Local computation: no network call,' informing the agent that this is a fast, offline operation. It also describes the mathematical behavior (inverse of distance+bearing). It does not discuss edge cases (e.g., invalid ranges), but for a simple geometric function the provided information is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. The functional definition is front-loaded, and the inverse relationship plus local computation note are appended efficiently. Every word contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple local calculation with complete schema descriptions and an assumed output schema, the description covers all essential aspects: what it computes, the inverse relationship, and the local/network behavior. It does not mention precision or error handling, but those are not critical for this straightforward tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and every parameter is already described in the schema (start coordinate, distance in metres, bearing clockwise from true north). The description essentially restates these values without adding new meaning, so it does not go beyond the baseline for fully covered parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (travel) and resource (coordinate), and precisely defines the output as the coordinate reached by traveling a given distance and bearing. It explicitly identifies itself as the inverse of `geo_distance` and `geo_bearing`, which distinguishes it from those sibling tools immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly indicates the relationship to `geo_distance` and `geo_bearing` by calling itself the inverse, which implies the appropriate usage context (i.e., when you need a destination point rather than distance or bearing). It does not explicitly state 'use this when...' or give exclusions, but the inverse relationship provides adequate context for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_distanceAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | End coordinate. | |
| from | Yes | Start coordinate. |
Output Schema
| Name | Required | Description |
|---|---|---|
| distance_m | Yes | Distance in metres along the WGS84 ellipsoid. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It conveys several behavioral traits: geodesic computation on the WGS84 ellipsoid, straight-line semantics, local computation (no network call), and no quota impact. While it does not discuss edge cases like identical or antipodal coordinates, the disclosed traits go well beyond a minimal description and there is no contradiction with any annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with zero filler. The core result (distance in metres) is front-loaded, followed by the critical driving-distance distinction and the network/quota qualifier. Every sentence earns its place, and the structure is easy for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with an output schema present, the description is complete. It covers what the tool computes, its geographic model, the distinction from route/matrix, and performance characteristics. The output schema handles the return value, so the description doesn't need to explain it. No important decision-relevant information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%—the schema already documents `from` and `to` as start/end coordinates and fully describes the nested lat/lon fields with ranges and a WGS84 note. The description adds little parameter-level meaning beyond naming two coordinates. This aligns with the baseline 3 for high schema coverage, where the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description immediately states a specific verb and resource: 'Distance in metres between two coordinates.' It further specifies the computational model ('geodesically on the WGS84 ellipsoid') and explicitly distinguishes itself from driving distance, which also differentiates it from sibling tools like route and matrix. Even without seeing the schema, an agent knows exactly what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use this tool versus alternatives: 'NOT a driving distance — use route or matrix for travel distance and time.' It also adds a decisive performance qualifier—'Local computation: no network call, no quota'—which helps an agent choose it when avoiding network latency or quota concerns.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_lengthAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | Yes | The coordinates to consider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| length_m | Yes | Total geodesic length in metres. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses that the computation is local ('no network call, no quota') and that the measurement is geodesic and summed over a 2+ point polyline. It does not detail error behavior for fewer than 2 points, but for a simple calculation tool this is adequate context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with no filler. The core measurement is front-loaded, the route distinction follows, and the local-computation note is compact and useful. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with an output schema, the description covers the essential context: units (metres), geodesic method, line-vs-route distinction, and the side-effect-free local computation. Nothing critical is missing for selecting and invoking it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for the `points` parameter but only says 'The coordinates to consider.' The description adds meaningful semantics: a polyline must have 2+ coordinates and the calculation is geodesic and summed. This goes beyond the schema's bare description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool computes 'Total length in metres of a polyline through 2+ coordinates, summed geodesically', specifying both the resource (a supplied polyline) and the operation (length measurement). It also explicitly distinguishes itself from a driven route by pointing to the `route` sibling tool, eliminating ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance: 'This measures the line you supply, NOT a driven route — use `route` for that.' This tells an agent exactly when to use this tool versus the alternative sibling, making the selection criterion clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_nearest_point_on_lineAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | The polyline's coordinates, 2 or more. | |
| point | Yes | The coordinate to measure from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| point | Yes | The closest position on the line, which may lie between vertices. |
| distance_m | Yes | Geodesic distance from the input point to that position, metres. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does so well. It discloses that the computation is local, requires no network or quota, returns geodesic distance in metres, and that the closest point may lie between vertices. These are non-obvious behaviors that the schema does not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first states the primary output, the second clarifies a subtle geometric behavior, and the third gives a use case and performance characteristic. Information is front-loaded and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter geometry calculation, the combination of a 100% documented schema, an output schema, and a description covering purpose, behavior, units, and execution context is complete. An agent has enough information to select and call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema documents both parameters fully with descriptions of the coordinate and polyline, so schema coverage is 100%. The description adds contextual framing ('coordinate' and 'polyline') but no additional parameter-level meaning beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states what the tool does: finds the closest position on a polyline to a given coordinate and returns the geodesic distance in metres. The added detail that the result may fall between vertices, not only on them, helps distinguish it from simpler point-in-polygon or point-to-point distance tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use case ('how far is this address from the route?') and highlights that it is a local computation with no network call and no quota, which helps an agent decide when to prefer it. It does not explicitly name alternative tools or state when not to use it, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_point_in_polygonAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| point | Yes | The coordinate to test. | |
| polygon | Yes | The polygon's outer ring, 3 or more coordinates. Closed automatically if the last point does not repeat the first. |
Output Schema
| Name | Required | Description |
|---|---|---|
| inside | Yes | True when the point is strictly inside the ring. Points exactly on the boundary are **not** counted as inside. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure burden. It reveals two non-obvious behaviors: boundary points are treated as OUTSIDE, and the polygon closes automatically if the last coordinate doesn't repeat the first. It also reassures about local computation with no network or quota. A brief statement about being read-only is absent but implied by the query phrasing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: a clear purpose statement, concrete use cases, required inputs, the boundary caveat, and the local-computation guarantee. The information is front-loaded and there is no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter boolean geospatial predicate with an output schema, the description covers all necessary behavioral context: input shape, closure behavior, boundary semantics, and cost characteristics. Nothing an agent needs to invoke and interpret the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description restates the point and polygon shape plus the 3+ coordinate requirement, but the schema already documents the LatLon fields, required minimum, and automatic closure. The description adds minimal semantic value beyond the structured schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a precise predicate — 'Whether a coordinate lies inside a polygon' — and names concrete use cases (delivery zones, catchments, clean-air zones, site boundaries). This clearly distinguishes it from sibling geometry tools like geo_distance, geo_area, or geo_bbox.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: use this when the question is point-in-polygon containment, with examples of typical polygon types. It does not explicitly list sibling alternatives or when-not-to-use it, but the predicate itself makes the applicable situation obvious. The 'local computation, no quota' note further helps selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
geo_simplifyAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| points | Yes | The polyline's coordinates, 2 or more. | |
| tolerance_deg | Yes | Douglas-Peucker tolerance in **degrees**, not metres. Around 0.0001 drops detail finer than roughly 10 m at the equator. |
Output Schema
| Name | Required | Description |
|---|---|---|
| points | Yes | The retained coordinates, endpoints always preserved. |
| removed | Yes | How many coordinates were removed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses that tolerance is in degrees, not metres, that endpoints are always kept, the nature of the return value, and that no network call or quota is involved. It does not cover edge cases or error behavior, but the provided details are useful and non-obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place: the core purpose, the unit warning, the endpoint guarantee, the return value, and the local-computation note. It is compact, front-loaded, and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with full schema coverage and an output schema, the description provides all essential information: how to interpret tolerance, the guarantee about endpoints, and what the return contains. No critical gap remains for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters fully, so the baseline is 3. The description adds value by clarifying the tolerance unit conversion (degrees vs metres, with a concrete equivalence) and by stating that endpoints are always kept, which affects how the points parameter is interpreted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Reduce the number of coordinates in a polyline while keeping its shape') and names the Douglas-Peucker algorithm. It clearly distinguishes geo_simplify from geometric calculation or measurement siblings like geo_length, geo_area, and geo_centroid.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for use: simplifying a polyline by reducing coordinates while preserving shape. It also notes 'Local computation: no network call, no quota,' which is a practical usage consideration, though it does not explicitly mention alternatives or when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_jobAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The job id returned by `submit_optimise_job`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | The job id. |
| kind | Yes | `optimise`, `replan` or `matrix`. |
| error | No | Why it failed, once `status` is `failed`. |
| result | No | The answer, inline, once `status` is `succeeded` — exactly the body the synchronous tool would have returned. |
| status | Yes | `queued`, `running`, `succeeded` or `failed`. Only `succeeded` and `failed` are terminal; keep polling on the other two. |
| refunded | Yes | Whether a failure refunded the submission's units. |
| terminal | Yes | Whether `status` is one this job will never leave. |
| created_at | Yes | RFC 3339 UTC submission time. |
| started_at | No | RFC 3339 UTC time a worker picked it up. |
| finished_at | No | RFC 3339 UTC time it finished, either way. |
| units_charged | Yes | Metered units the SUBMISSION drew. This is what was charged; `refunded` says whether it came back. |
| webhook_status | No | `delivered` or `delivery_failed`, once a webhook was attempted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden and exceeds it. It discloses status values, the terminal field's meaning, free polling, units_charged and refunded semantics, key ownership, and the deliberate NOT FOUND rather than forbidden behavior. This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: purpose, status semantics, polling cadence, billing behavior, auth behavior, and gateway requirement. It is front-loaded with the core purpose and then layers contextual details in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema can carry return-shape details, freeing the description to cover everything else an agent needs: job states, terminal polling semantics, cost behavior, auth boundaries, error semantics, and the gateway requirement. Nothing essential is left missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents 'id' fully at 100% coverage, so the baseline is 3. The description adds meaningful context beyond the schema by explaining that the id belongs to the submitting key or another key of the same identity, and that another party's id yields NOT FOUND rather than forbidden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read an asynchronous job submitted with submit_optimise_job' and clarifies that the result is 'exactly the body the synchronous tool would have returned.' This clearly distinguishes get_job from its submission sibling and from synchronous variants.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit operational guidance: poll while the 'terminal' field is false, check every few seconds rather than guessing at a duration, and treat webhooks as unsuitable for agents in a loop. This tells the agent exactly when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_styleAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| style_id | Yes | Hosted style id, e.g. "midnight-fleet-a1b2c3". |
Output Schema
| Name | Required | Description |
|---|---|---|
| theme | Yes | The latest theme document — the editable source the next version is published from. |
| style_id | Yes | Hosted style id. |
| style_url | Yes | URL of the latest compiled MapLibre style (point MapLibre GL at it). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It does convey read-only intent through 'Fetch' and 'inspect before editing,' and it usefully distinguishes the editable theme document from the compiled style. However, it does not explicitly state side-effect-free behavior, permission requirements, or error handling, leaving some transparency gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the main fetch action is front-loaded, and the second sentence adds practical guidance. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-required-parameter read operation with an output schema present, the description is largely self-sufficient. It explains the two outputs and the intended editing context, though it could name related sibling tools or explicitly confirm the operation is non-mutating.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including an explicit example for style_id. The description adds only a mild hosted-style framing and does not meaningfully enhance understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch') and names precise resources: the latest theme document and the URL of the compiled MapLibre style. It also ties the tool to an inspection-before-editing workflow, which clearly differentiates it from editing-focused siblings like set_palette and set_layer_paint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: use the theme to inspect current palette and layer overrides before editing. It does not explicitly name alternatives or state when not to use the tool, but the intended workflow is evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_usageAInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Last day to report, `YYYY-MM-DD` (UTC) inclusive. Defaults to today. | |
| from | No | First day to report, `YYYY-MM-DD` (UTC) inclusive. Defaults to the first day of the current month. At most 92 days may separate `from` and `to`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| to | Yes | Last day covered, `YYYY-MM-DD` inclusive. |
| days | Yes | Per-day breakdown over the range, oldest first. A day with no usage is absent rather than reported as zero. |
| from | Yes | First day covered, `YYYY-MM-DD` inclusive. |
| key_id | Yes | Identifier of the key this usage belongs to. |
| totals | Yes | Units per endpoint over the whole range. |
| total_units | Yes | Total units over the whole range. |
| identity_pooled | Yes | Whether quota is pooled across every key belonging to the same identity. When true, these figures are the identity's shared consumption, so another key of the same owner also spends them. |
| month_used_units | Yes | Units counted against the monthly quota right now: the very number the quota check enforces on, independent of `from`/`to`. Quota is monthly, so this — not `total_units` — is what to compare with `monthly_quota_units`. It includes units recorded but not yet written to the daily counters, so over a whole-month range it can exceed `total_units`; that is not a discrepancy. |
| balance_millipence | Yes | Prepaid balance in millipence (thousandths of a penny), for usage beyond the monthly allowance. |
| monthly_quota_units | Yes | The key's monthly allowance in units. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so thoroughly. It discloses that the call costs no quota, that figures are weighted units rather than raw request counts, that identity_pooled may make the numbers shared across keys, and that only the authenticating key's usage can be read. It also warns against misreporting units as calls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than a minimal one, but every extra sentence addresses a real interpretation risk: units vs. calls, pooled quota, and inability to query other keys. It is front-loaded with purpose and cost, then moves through parameters, return semantics, and caveats in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-optional-parameter read tool with an output schema, the description is exceptionally complete. It covers purpose, cost, default ranges, date-bound behavior, output semantics, unit weighting, pooled identity, authentication key ownership, and the required gateway setup. An agent has everything needed to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both optional parameters including defaults, format, inclusiveness, and the 92-day cap. The description repeats and lightly contextualizes this ('bound the report; omitted, it covers the current month to date') but does not add substantial new parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Check what your own API key has spent.' It also adds a clear use case ('decide mid-task whether to keep going') and is plainly distinct from all sibling tools, which concern routing, geocoding, style, or planning rather than quota usage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use the tool: mid-task to decide whether to continue. It also gives an explicit when-not: 'there is no way to read another caller's usage,' and clarifies that reading is free, so there is no quota cost concern. No alternative tool is relevant among siblings, so no alternative routing is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_place_categoriesAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| categories | Yes | Every category `nearby_places`, `search_along_route` and `geocode` recognise, sorted alphabetically by `category`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses that the list is sorted, identical on every call, local, offline, quota-free, and that invalid category tokens silently return empty results. This goes well beyond a simple 'list' statement and gives the agent important behavioral expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but every sentence earns its place: what the tool lists, what each entry contains, critical usage warnings, exclusions, and determinism. The most important purpose is front-loaded, and the warnings are positioned where they are most relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema, the description is complete. It covers purpose, return structure, relationship to sibling tools, failure mode for invalid tokens, excluded categories, determinism, and performance characteristics. Nothing an agent needs to decide whether to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter schema to augment; the baseline is 4. The description still explains that the output entries are exact category tokens, aliases, and descriptions, which helps the agent understand how the category value is meant to be used in sibling tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it lists canonical place categories for use with nearby_places and search_along_route. It clearly distinguishes this from sibling tools like list_style_layers by tying it to place-category tokens and related geocoding workflows. The exact purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to read this before guessing a category, and warns that unrecognized tokens return an empty result rather than an error. It also states that cuisines, brands, and names are not categories and should be searched as free text, giving clear guidance on when not to use this tool and what to do instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_style_layersAInspect
List everything a MapMap style theme can style: the named palette slots with their light/dark default colours, the skeleton layer ids (paint order) that set_layer_paint accepts, and the OpenMapTiles source-layers extra layers may reference. Attribution is enforced on every compiled style and cannot be themed away. Local lookup, no network; always works.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| layer_ids | Yes | The skeleton layer ids a theme's `layers` may override, in paint order (first = bottom). |
| attribution | Yes | The attribution contract: enforced on every compiled style, not themable. |
| palette_slots | Yes | The named palette slots a theme's `palette` may override, with their light/dark defaults, in presentation order. |
| source_layers | Yes | The OpenMapTiles source-layers the tiles emit; `extra_layers` must reference one of these. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden and does well: it explicitly states attribution is enforced and cannot be themed away, and that lookup is local with no network and always works. It could have explicitly said the operation is read-only, but 'List' plus the output schema largely covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the tool's core purpose, immediately enumerating the three categories of things it lists. The two follow-up sentences about attribution and local lookup earn their place by adding important behavioral context without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter listing tool with an output schema, the description is fully adequate: it specifies what categories of data are returned, mentions an important constraint (attribution), and reassures about availability. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema description coverage, so the baseline is 4 per the rubric. The description adds no parameter-specific detail, but none is needed because there is nothing to configure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and identifies the exact resource: everything a MapMap style theme can style, broken into palette slots, skeleton layer ids, and OpenMapTiles source-layers. This makes it clearly distinct from sibling tools like set_layer_paint, set_palette, and get_style.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context by stating that skeleton layer ids are what set_layer_paint accepts and source-layers are what extra layers may reference, making the tool's role as a reference/discovery tool obvious. It does not explicitly name alternatives or give when-not-to-use conditions, but the context is sufficient for a listing tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
match_traceAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| shape | No | The trace as an ordered list of recorded points, oldest first. Between 2 and 2000 points. Provide this or `encoded_polyline`. | |
| costing | No | Costing model the trace was travelled under: `auto` (default), `truck`, `bicycle`, `pedestrian` or `motor_scooter`. It decides which roads the trace may be matched onto, so a walked trace matched as `auto` snaps to the carriageway rather than the path. | |
| encoded_polyline | No | The trace as a Google encoded polyline with six digits of decimal precision (polyline6) — the geometry `route` and `match_trace` themselves return. Provide this or `shape`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| toll | Yes | Tolled portion of the matched path. |
| bridge | Yes | Bridge portion of the matched path. |
| tunnel | Yes | Tunnel portion of the matched path. |
| costing | Yes | Costing the trace was matched under. |
| summary | Yes | One-line human summary of the match, for reading aloud. |
| by_admin | Yes | Distance and time by administrative area, longest first. An entry whose codes are all null covers segments the graph could not place in any admin area — counted honestly rather than guessed at. |
| by_surface | Yes | Distance by road surface (`paved`, `paved_smooth`, `gravel`, …), longest first. Empty when the graph records no surface for any matched segment. |
| distance_m | Yes | Length of the matched path in metres. |
| duration_s | Yes | Travel time along the matched path in seconds, from the engine's own time model. |
| edge_count | Yes | How many road segments the trace matched onto. |
| by_road_class | Yes | Distance and time by road class (`motorway`, `primary`, `residential`, …), longest first. |
| geometry_polyline6 | Yes | The matched path as a Google encoded polyline with six digits of decimal precision (polyline6). This is the trace snapped to real roads, not the raw input. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and meets it: it discloses the costing mismatch effect, the roll-up summation caveat, omission of missing surface/admin data, and the hard gateway/auth requirement with no fallback. This goes beyond basic operation and helps an agent set expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it flows from purpose to input to output semantics, then caveats and infrastructure. The 'Honesty:' paragraph front-loads important accuracy caveats rather than burying them.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex map-matching tool with three parameters and an output schema, the description covers input selection, output composition, aggregation caveats, and deployment prerequisite (gateway). Nothing critical to correct invocation or interpretation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3. The description adds value beyond the schema with the 'not both' rule, the costing consequence example (walk as auto snaps to carriageway), and the polyline6 format clarification. It reinforces rather than merely restates the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Snap a recorded GPS trace to the road network' and states it reports what was travelled over. It also frames the tool's purpose for dashcam/telematics logs, which distinguishes it from route-planning siblings like `route`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly identifies the target use case ('turn a dashcam or telematics log into a report') and explains input constraints (shape OR encoded_polyline, costing must match travel mode). It does not explicitly name alternatives or state when not to use it, but the recorded-trace framing is enough to route an agent appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
matrixAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck". | |
| costing | No | Costing model: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| origins | Yes | Origin locations (matrix rows). | |
| destinations | Yes | Destination locations (matrix columns). | |
| exclude_polygons | No | Areas to avoid — scenario analysis ("close this bridge and recompute the matrix"): an array of polygons, each an array of `[lon, lat]` pairs forming one exterior ring (GeoJSON-style, longitude FIRST). Roads intersecting any ring are excluded from every cell's path finding. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored. |
Output Schema
| Name | Required | Description |
|---|---|---|
| distances_m | Yes | Travel distances in metres, same shape as `durations_s`. Null cells are unreachable pairs. |
| durations_s | Yes | Travel times in seconds; `durations_s[i][j]` is origin `i` → destination `j`. Null cells are unreachable pairs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It responsibly reveals the exact output units, null cells for unreachable pairs, the 10,000-cell cap, and the engine-specific behavior of exclude_polygons (Valhalla supported, GraphHopper ignored). This is strong transparency for a read-only compute tool, though it stops short of discussing timeout/error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences, front-loaded with the core action and followed by essential operational details. Every sentence contributes useful information (costing modes, return fields, cell limit, polygon behavior) with no filler. It could be tightened slightly for readability but is well within acceptable density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description is nearly complete: it specifies what is returned, limits, engine compatibility, and the purpose of the optional parameter. The only minor omissions are edge-case behavior (e.g., what happens when exceeding the cell limit) and explicit auth/rate-limit info, but these are not critical for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds some conceptual framing—'origins (rows)' and 'destinations (columns)'—and the engine caveat for exclude_polygons, but this largely mirrors what the schema already says. It does not materially deepen parameter understanding beyond the structured definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Compute a travel time/distance matrix between origins (rows) and destinations (columns).' It clearly distinguishes this from the sibling 'route' tool by focusing on multi-origin/multi-destination matrix output, and the mention 'as in route' only serves as a cross-reference for the truck profile. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the use case ('before/after scenarios' for exclude_polygons) and states hard limits (10,000 cells) but never explicitly says when to choose this over alternatives like 'route' for single pairs or 'reachable_area' for isochrones. An agent must infer the matrix-vs-route distinction from the tool name and purpose rather than from explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nearby_placesAInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | Latitude of the search point in decimal degrees (−90 to 90). | |
| lon | Yes | Longitude of the search point in decimal degrees (−180 to 180). | |
| name | No | The name or brand of the place to find — "Lloyds", "Lloyds Bank", "Sainsbury's" — for "where is the nearest X" questions. Every word must appear in the place's name or one of its alternative names, case- and accent-insensitively, with the last word also matching as a prefix ("Sains" finds Sainsbury's). Combine with `category` to disambiguate a brand used by more than one kind of place ("Lloyds" plus "bank" excludes Lloyds Pharmacy). Optional when `category` is given; at least one of the two is required. | |
| limit | No | Maximum number of results (1–10, default 5). | |
| fov_deg | No | Field of view: the full width in degrees of a cone centred on `heading_deg`, outside which results are dropped — it is the FULL width, so 90 keeps only what lies within 45 degrees either side of dead ahead. Needs `heading_deg` — a cone has to point somewhere. The count of results removed is reported as `out_of_view`. | |
| category | No | The kind of place to find. The gateway matches it against the index's lowercased OSM tag values (the value of the POI's `amenity`/`shop`/`tourism`/`railway`/… tag) — e.g. "cafe", "fuel", "charging_station", "parking", "pharmacy", "supermarket", "hotel", "restaurant", "fast_food", "atm", "bakery", "hospital", "station" — and normalises common colloquial names first ("coffee" → cafe; "ev_charging", "ev charging" → charging_station; "petrol" → fuel; "chemist" → pharmacy). A category the index does not carry matches nothing: the result is an empty list, not an error. Optional when `name` is given; at least one of the two is required. | |
| radius_m | No | Maximum straight-line distance of any result from the point, in metres (1–100000, default 2500). | |
| heading_deg | No | Which way the user is facing, in degrees **clockwise from true north** (0 = north, 90 = east, 180 = south, 270 = west). Supply it and every result is also described from the user's point of view ("just ahead on your right"); omit it and results fall back to cardinal directions ("to the north-east"), so the tool works with or without a compass. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | Matching places, nearest first. Empty when the index has no such place within the radius. |
| out_of_view | No | How many otherwise-matching places were dropped for falling outside `fov_deg`. Non-zero means there are matching places near the user that are simply not in front of them — say so rather than reporting nothing nearby. Always 0 when no field of view was set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: empty-list-not-error, case/accent-insensitive prefix matching, category normalization examples, fov_deg full-width semantics, heading fallback behavior, and out_of_view meaning. It even notes the gateway requirement. Exceptionally transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence earns its place given the 8-parameter tool with complex matching/bearing logic. It front-loads the core purpose and then flows into parameter details and edge cases. A bit dense, but structurally organized and appropriately sized for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers input requirements, output result fields (name, distance, bearing, details), edge cases (empty list, out_of_view), and gateway prerequisites. With an output schema present, it still effectively explains all necessary call parameters and expected behavior. Nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond schema by clarifying the 'at least one of category or name' requirement (not in required collection), explaining the disambiguation strategy ('Lloyds' plus 'bank'), and mentioning the 'Prefer reading direction aloud' tip. Slight redundancy with schema, but meaningful extra context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find places near a point, nearest first with distance in metres' and immediately scopes by category or name. It distinctly separates itself from geocode by explaining the proximity focus, so an agent can tell it apart from the sibling without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to 'Use this instead of geocode whenever the question is about what is NEAR a location' and explains why geocode is unsuitable (returns far branches over nearby ones). This direct comparison gives clear when-to-use guidance with no left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimise_routesAInspect
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 400 km matrix span — 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.
| Name | Required | Description | Default |
|---|---|---|---|
| jobs | No | Single-stop jobs (at least one job or shipment overall). | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; the travel-time matrix then respects dimensional and dangerous-goods restrictions, so the whole plan is truck-legal. | |
| costing | No | Costing model for the travel-time matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| vehicles | Yes | The fleet (at least one vehicle, each with a start and/or end). | |
| emissions | No | The fleet's emission declaration, for UK clean-air / low-emission zone assessment. On its own it annotates: the response's `zones` block names every zone containing one of the problem's own locations and what this vehicle would pay there. With `avoid_zones` it also steers the internal travel-time matrix away from those zones, so the plan itself changes. | |
| shipments | No | Pickup+delivery pairs. | |
| avoid_zones | No | Keep the optimisation's travel-time matrix out of every zone the declared vehicle would be charged or banned in. Requires `emissions`. | |
| territories | No | Fleet territories: named polygons that bound which vehicle may serve which stop, referenced by `vehicles[].territory_ids`. These are request data — caller-drawn rounds, validated per call and never stored. Nothing to do with clean-air zones or with the offline map packages of the same word. | |
| relax_if_unassigned | No | Re-solve ONCE with these relaxations if the first solve leaves work unassigned, and say honestly which plan came back. At most one second solve, never beyond the caps you state, and the relaxed plan is returned only if it assigns MORE work than the first — giving away constraints for nothing is strictly worse than not giving them away. Breaks are never widened, nor are capacities, skills, territories or task caps: only time windows move, and only by the stated amounts. Bills as two solves when the second one runs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| zones | No | Clean-air / low-emission zones touching the problem's own locations, and what the declared vehicle pays in each. Present only when `emissions` was declared. |
| routes | Yes | One optimised route per used vehicle. |
| profile | Yes | The matrix costing profile the plan was computed with ("auto", "truck", "bicycle", "pedestrian" or "motor_scooter"). |
| reloads | No | The multi-trip split: each vehicle's trips, their windows, the depot each returns to, and the stated approximation. Present only when a vehicle declared `reloads`. Read the `basis` inside it before quoting arrival times. The trip windows are fixed BEFORE the solve, so a lorry that tips early cannot lend the spare time to its next trip: stops can come back unassigned that a truly sequential model would have served. The plan is feasible, never optimistic — it cannot put a vehicle in two places at once — but it is not optimal. Re-plan after each tip through `replan_routes` for the tighter answer. |
| summary | Yes | Solution summary. |
| relaxation | No | The relaxation report: the caps requested, whether a second solve ran, whether ITS plan is the one returned, what was widened, and what is still unassigned. Present only when `relax_if_unassigned` was declared. Always read `second_solve` and `relaxed_plan_used` before telling anyone the day fits. A plan produced under relaxation has had promises moved, and the block is what says so. |
| unassigned | Yes | Tasks the solver could not assign to any vehicle. |
| territories | No | How the territories bound the plan: which vehicle was eligible for what, and any task no eligible vehicle existed for. Present only when `territories` was declared. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations were provided, so the description carries the full burden. It discloses the most important behavioral trait: `relax_if_unassigned` re-solves exactly once, returns the relaxed plan only if it assigns more work, and bills as two solves. It also warns that reloads is an approximation, that max_trips is a budget not a prediction, and that the user must check `relaxation.relaxed_plan_used` before claiming the day fits. This is rich, honest behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence earns its place — it explains the VRP inputs, costing profile rules, fair-use limits, territory semantics, reload behavior, relaxation guarantees, emissions effects, and the gateway prerequisite. It is front-loaded with the core purpose and returns. It loses one point for being quite dense and long; an agent may need to re-read parts, but the density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's high complexity (9 parameters, nested specs, output schema), the description covers all the critical decision points: when to use alternatives, what happens with reloads, what relaxation actually changes, the MapMap gateway dependency, the 200-location/400 km limit, and the honest-check caveats. The output schema exists, so the description need not enumerate return fields; it adds the operational context the schema cannot.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so the baseline is 3; however, the description adds semantic value beyond the schema by explaining how `vehicles`, `jobs`, and `shipments` interact, what `territories` polygon order requires (longitude first), how `reloads` splits the shift, what `relax_if_unassigned` actually does, and how `emissions` with `avoid_zones` changes the plan. This goes well beyond what the JSON Schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific statement — 'Optimise multi-vehicle, multi-stop delivery plans (VRP)' — and then details the core inputs (vehicles, jobs, shipments), costing modes, and return shape. It also explicitly differentiates itself from nearby siblings like `cluster`, `submit_optimise_job`, and `replan_routes`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit routing guidance: use `cluster` then optimise each group when exceeding 200 unique locations or 400 km span, use `submit_optimise_job` for 2,000 locations, and use `replan_routes` after each tip. It also states the tool refuses to run without a MapMap gateway for territories/reloads/relaxation/zones, which is important when-to-use/not-use information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
order_stopsAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Optional fixed final destination. Mutually exclusive with `round_trip`; omitted (and not a round trip), the run ends at whichever stop the solver visits last. | |
| start | Yes | Where the run starts. | |
| stops | Yes | The stops to put in the best visiting order (1–100). | |
| truck | No | Truck profile (dimensions + ADR declaration); requires costing "truck". The travel-time matrix then respects dimensional and dangerous-goods restrictions. | |
| costing | No | Costing model: "auto" (default) or "truck". | auto |
| round_trip | No | Return to `start` after the last stop (default false). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ordered | Yes | The stops in optimal visiting order. |
| profile | Yes | The matrix costing profile ("auto" or "truck"). |
| distance_m | No | Total travel distance in metres, when reported. |
| duration_s | Yes | Total travel time in seconds. |
| unassigned_stop_indexes | Yes | 0-based indexes of stops the solver could not fit (empty in the normal, unconstrained case). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It clearly discloses the output contract: stops in visit order, arrival offsets in seconds, plus total duration and distance, and it clarifies truck mode produces a truck-legal order. It does not mention statelessness or failure behavior, but as a pure computation tool the disclosure is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences front-load the purpose before parameter details, with no filler. Each sentence adds distinct information while keeping the whole description readable and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the input schema fully documents each parameter, the description is complete enough for correct invocation. It covers required inputs, the 1–100 stop limit, optional end/round_trip behavior, costing selection, truck-legal ordering, and the return value shape without needing to repeat schema details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all parameters (100% coverage), so the baseline is 3. The description adds human-readable meaning: auto=car, truck=lorry, a compact stop shape of {location, label?, service_s?}, and a pointer to route's truck syntax, all of which help an agent map intent to parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation: "Put a single run's stops in the best visiting order," reinforced by the quoted user intent "order my errands". The phrase "single run's stops" separates it from broader fleet tools like optimise_routes and from route geometry tools, so an agent can identify what it does precisely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives practical configuration guidance: optional end vs round_trip, costing auto vs truck, and passing truck as in route. However, it never explicitly says when to choose this tool over optimise_routes, route, or matrix; the use case is implied rather than stated with when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_dayAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| start | Yes | Where the day starts (name or location; `dwell_minutes` ignored). | |
| stops | Yes | The stops to visit (1–20). Visited in the given order unless `optimise` is true. | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck". | |
| costing | No | Costing model: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| optimise | No | Reorder the stops for the shortest day (VROOM solver; requires the optimisation sidecar). Default false: visit in the given order. | |
| depart_at | No | Departure time as RFC 3339 (e.g. "2026-07-18T09:00:00Z"); when given, every ETA is also returned as an absolute timestamp. | |
| return_to_start | No | End the day back at the start (default false). |
Output Schema
| Name | Required | Description |
|---|---|---|
| start | Yes | The day's starting point. |
| stops | Yes | The stops in visit order, each with leg, ETAs and any geocoding resolution to double-check. |
| costing | Yes | The costing the plan was routed with. |
| summary | Yes | One-line human-readable summary of the day. |
| depart_at | No | The departure time echoed back, when one was given. |
| finish_at | No | Absolute end of the day (RFC 3339), when `depart_at` was given. |
| optimised | Yes | Whether the stop order was optimised (VROOM) or kept as given. |
| return_leg | No | The leg back to the start, when `return_to_start` was set. |
| total_dwell_s | Yes | Total time at stops, seconds. |
| finish_offset_s | Yes | End of the day (last arrival + dwell), seconds after departure. |
| total_distance_m | Yes | Total travel distance, metres. |
| geometry_polyline6 | Yes | Full multi-stop route geometry (polyline6) — hand it to the map SDK or the `route` tool consumers directly. |
| total_travel_duration_s | Yes | Total driving/travel time, seconds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the output structure (visit order, per-leg duration/distance, arrival/departure times, totals, polyline6), the side effects of dwell_minutes and depart_at, the VROOM solver behavior, truck restrictions, and the geocoding ambiguity handling. This is unusually transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every clause carries information: core behavior, required and optional inputs, costing options, output details, and geocoding caveats. It is front-loaded with the primary purpose and contains no filler or repetition of schema text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with an output schema, the description covers everything an agent needs to invoke it correctly: required start/stops, optional parameters, costing semantics, special truck handling, optimisation behavior, return structure, and geocoding failure handling. Remaining details like stop count limits are already in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value beyond the schema: it explains what optimise does with VROOM, how truck costing interacts with dimensional/ADR restrictions, how dwell_minutes shifts ETAs, how depart_at yields absolute timestamps, and how to react to ambiguous geocoding results. This elevates it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Turn an itinerary into one navigable multi-stop route.' It clearly distinguishes itself from siblings like 'route' or 'order_stops' by combining multi-stop planning, optional optimisation, costing modes, and return-to-start behavior in one call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes a clear usage context: when you need an entire day's itinerary as one route with stops, departure time, optimisation, and multiple costing options. It does not explicitly name alternatives or state when-not-to-use it, but the multi-stop framing makes selection unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_ev_routeAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| min_kw | No | Keep only charge points with a usable connector rated at least this many kW (e.g. 50 for rapid charging only). | |
| origin | Yes | Where the journey starts. | |
| vehicle | No | The vehicle. Omitted ⇒ the published "saloon" default, and the answer says which vehicle it used. | |
| start_soc | No | State of charge at the start, 0–1 (default 0.9). | |
| waypoints | No | Intermediate points the route must pass through, in order (at most 8). Charge stops are inserted around them. | |
| connectors | No | Keep only charge points offering at least one of these connector standards: "type2", "type1", "ccs", "chademo", "tesla", "domestic", "other". This narrows the vehicle's own set, never widens it. | |
| destination | Yes | Where it ends. | |
| reserve_soc | No | The floor the state of charge must never fall below mid-route (default 0.1). Distinct from the arrival figure. | |
| min_arrival_soc | No | Lowest acceptable state of charge on arrival (default 0.1). | |
| max_detour_minutes | No | How far off the route a charge point may sit, as a detour in minutes (default 15, at most 120). | |
| ambient_temperature_c | No | Ambient temperature in °C. Derates traction energy from a published study; cabin heating belongs in the vehicle's `aux_kw`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| legs | Yes | The driving legs, in order. |
| stops | Yes | The charge stops, in visit order. Always empty when `feasible` is false: a journey that cannot be completed has no stop list. |
| reason | No | The same cause in plain language, for the user. |
| summary | Yes | The plan at a glance. |
| vehicle | No | The vehicle the plan was computed for. |
| feasible | Yes | **Whether the journey is possible at all.** False means no plan exists — a charger desert, a connector mismatch, or a gap wider than the car's range. Report the `reason` and the furthest reachable point; never describe an infeasible answer as a plan. |
| soc_trace | Yes | State of charge at every point of the journey. |
| reason_code | No | Machine token for why no plan exists, when none does: "no_chargers_in_corridor", "connector_mismatch", "out_of_range", "dead_end", "below_min_kw", "chargers_unrated", "stop_limit", "dataset_empty", "no_charge_curve" or "unroutable". |
| coverage_note | Yes | **Always present.** What this deployment's charge-point dataset does and does not cover. An infeasible plan means "none from these operators", never "there are no chargers here". Show this alongside the answer. |
| gradient_data | Yes | "complete", "partial" or "absent". **"absent" means the deployment had no elevation data and consumption was modelled on the flat**, which under-reads a hilly route. Say so rather than presenting the figure as measured. |
| profile_source | No | "default" when a published profile supplied the figures, "inline" when the caller did. |
| route_distance_m | No | Distance of the planned route, metres. |
| route_duration_s | No | Driving time of the planned route, seconds. |
| availability_live | Yes | Whether charge-point statuses came from a live availability feed. A static planner is the default: without a feed, nothing in this answer is a claim about which bays are free right now. |
| geometry_polyline6 | No | The planned journey's geometry as an encoded polyline6, through the charge stops. |
| charging_attribution | No | Attribution string for the charge-point operators actually used — display it with the plan (a licence obligation). |
| furthest_reachable_lat | No | Latitude of that furthest reachable point. |
| furthest_reachable_lon | No | Longitude of that furthest reachable point. |
| furthest_reachable_position | No | How far along the route the vehicle can get unaided, 0.0–1.0, when no plan exists. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so impressively. It explains the physics-based energy model, warns that charge time is not energy divided by peak power, and details infeasible-answer semantics ('feasible: false' is an answer, not an error). It also covers gradient-data caveats, coverage_note display requirements, availability_live status, and the MapMap gateway dependency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with the core purpose and has no filler; each sentence adds a meaningful caveat or behavioral clarification. It uses an 'IMPORTANT' marker and 'ALWAYS' to emphasize critical operational guidance. It could be tightened into shorter paragraphs or bullets for easier scanning, but it earns its length given the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with an output schema, the description covers everything an agent needs: input composition, defaults, infeasible-result handling, data caveats, coverage note requirements, and even display instructions for charging_attribution. It also warns about deployment environments without a charge-point dataset. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds meaning beyond the schema by explaining reserve_soc as the mid-route floor, clarifying connectors/min_kw as filters, and describing how vehicle profiles and inline figures interact. It also clarifies defaults for start_soc, min_arrival_soc, and reserve_soc in the flow of the description. The rich schema still does most of the parameter documentation work, but the description genuinely supplements it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Plan a whole electric-vehicle journey, charge stops included.' This clearly distinguishes it from general routing siblings like route or optimize_routes by emphasizing the EV-specific charge-stop planning scope. It also states exactly what it returns: stops, state-of-charge traces, and driving/charging times.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is clear: this tool is for planning a full EV journey with charge stops, including vehicle specification, SOC thresholds, and connector filters. The description implies it is the right choice when charge stops, charging curves, and EV-specific feasibility matter, while siblings like route or reachable_area serve other purposes. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reachable_areaAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| origin | Yes | Origin the reachable area is computed from. | |
| costing | No | Travel mode: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| polygons | No | Return filled polygons instead of contour linestrings (default false). Polygons draw directly as a MapLibre fill layer. | |
| contours_minutes | Yes | Contour boundaries in minutes of travel time, e.g. [5, 10, 15] for 5/10/15-minute rings. 1–10 values, each between 0 and 120 minutes. | |
| exclude_polygons | No | Areas to avoid — scenario analysis ("close this bridge and recompute reachability"): an array of polygons, each an array of `[lon, lat]` pairs forming one exterior ring (GeoJSON-style, longitude FIRST). Roads intersecting any ring are excluded from the reachability search. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored. |
Output Schema
| Name | Required | Description |
|---|---|---|
| geojson | Yes | GeoJSON FeatureCollection of the reachability contours, one feature per requested minute value (each feature's `contour` property is its minutes), as returned by the routing engine. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It discloses the GeoJSON FeatureCollection return shape, filled polygons versus contour lines, the 'longitude FIRST' ordering requirement for exclude_polygons, and the Valhalla-only / GraphHopper-ignored engine behavior. It does not explicitly state read-only/no side effects, but the compute-oriented phrasing makes that risk low.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is dense and every clause earns its place: purpose, costings, contours_minutes constraints, polygon rendering, output format, exclude scenarios, and engine support. The core purpose is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and all five parameters documented in the input schema, the description covers the remaining practical knowledge: output feature count, rendering-ready polygons, scenario use, and engine limitations. Nothing needed to call the tool correctly appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds value above the schema by turning costing modes into practical questions and by highlighting when polygons and exclude_polygons are useful. The engine caveat for exclude_polygons is also conveyed in prose beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Compute the area reachable from an origin within one or more travel-time budgets', then clarifies the concept as walkability/cyclability rings. This clearly distinguishes the tool from point-based route/matrix siblings by emphasizing areal coverage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description supplies concrete use cases: 'how far can I walk in 15 minutes?', cycling equivalents, delivery coverage, and before/after scenarios using exclude_polygons. It gives clear context but does not explicitly name alternatives or say when not to use this tool versus route or matrix.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replan_routesAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| jobs | No | Single-stop jobs (at least one job or shipment overall). | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; the travel-time matrix then respects dimensional and dangerous-goods restrictions, so the whole plan is truck-legal. | |
| changes | No | Changes to the work itself. Optional, on the same condition. | |
| costing | No | Costing model for the travel-time matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| progress | No | Per-vehicle progress. Optional, but at least one progress entry or one change is required — a re-plan that reports nothing new is the original problem. | |
| vehicles | Yes | The fleet (at least one vehicle, each with a start and/or end). | |
| emissions | No | The fleet's emission declaration, for UK clean-air / low-emission zone assessment. On its own it annotates: the response's `zones` block names every zone containing one of the problem's own locations and what this vehicle would pay there. With `avoid_zones` it also steers the internal travel-time matrix away from those zones, so the plan itself changes. | |
| shipments | No | Pickup+delivery pairs. | |
| avoid_zones | No | Keep the optimisation's travel-time matrix out of every zone the declared vehicle would be charged or banned in. Requires `emissions`. | |
| territories | No | Fleet territories: named polygons that bound which vehicle may serve which stop, referenced by `vehicles[].territory_ids`. These are request data — caller-drawn rounds, validated per call and never stored. Nothing to do with clean-air zones or with the offline map packages of the same word. | |
| relax_if_unassigned | No | Re-solve ONCE with these relaxations if the first solve leaves work unassigned, and say honestly which plan came back. At most one second solve, never beyond the caps you state, and the relaxed plan is returned only if it assigns MORE work than the first — giving away constraints for nothing is strictly worse than not giving them away. Breaks are never widened, nor are capacities, skills, territories or task caps: only time windows move, and only by the stated amounts. Bills as two solves when the second one runs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| zones | No | Clean-air / low-emission zones touching the problem's own locations, and what the declared vehicle pays in each. Present only when `emissions` was declared. |
| replan | Yes | What the re-plan locked and why: the prefix held per vehicle, where each vehicle re-plans from and how that was decided, stops released from a vehicle that could no longer serve them, tasks forced unassigned, and a note for every id that did not resolve. Read it. A stop that vanished from the plan is named here rather than left for the dispatcher to notice at four in the afternoon. |
| routes | Yes | One optimised route per used vehicle. |
| profile | Yes | The matrix costing profile the plan was computed with ("auto", "truck", "bicycle", "pedestrian" or "motor_scooter"). |
| reloads | No | The multi-trip split: each vehicle's trips, their windows, the depot each returns to, and the stated approximation. Present only when a vehicle declared `reloads`. Read the `basis` inside it before quoting arrival times. The trip windows are fixed BEFORE the solve, so a lorry that tips early cannot lend the spare time to its next trip: stops can come back unassigned that a truly sequential model would have served. The plan is feasible, never optimistic — it cannot put a vehicle in two places at once — but it is not optimal. Re-plan after each tip through `replan_routes` for the tighter answer. |
| summary | Yes | Solution summary. |
| relaxation | No | The relaxation report: the caps requested, whether a second solve ran, whether ITS plan is the one returned, what was widened, and what is still unassigned. Present only when `relax_if_unassigned` was declared. Always read `second_solve` and `relaxed_plan_used` before telling anyone the day fits. A plan produced under relaxation has had promises moved, and the block is what says so. |
| unassigned | Yes | Tasks the solver could not assign to any vehicle. |
| territories | No | How the territories bound the plan: which vehicle was eligible for what, and any task no eligible vehicle existed for. Present only when `territories` was declared. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers richly: statelessness ('nothing is stored', 'MapMap holds NO dispatch state'), the need to pass the full original problem, the locked-prefix guarantee by construction, refusal of `reloads` vehicles, billing on the remaining problem, and the contents of the `replan` response block. No annotation contradiction exists since no annotations were provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and every sentence carries genuine behavioral information, but the description runs roughly 280 words. Passages like 'left for a dispatcher to notice at four in the afternoon' and 'go stale, leak, or fall out of step' are colorfully worded and could be tightened without losing meaning. Dense and valuable, but not concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a complex 11-parameter tool: it covers the required input (full original problem), the qualifying condition, locked-stop behavior, the output shape (`optimise_routes` shape plus `replan` block), refusal cases, billing, and the gateway requirement. The output schema exists, and the description still adds the `replan` block semantics on top.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: it names and interrelates the replan-specific parameters (`progress`, `changes`), stresses the strict serving order of `completed_stop_ids`, states the 'at least one of progress or changes' requirement, and explains that vehicles with `reloads` cause a refusal. This goes beyond what the JSON Schema alone communicates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource pairing: 'Re-plan a fleet part-way through its shift.' It clearly distinguishes itself from the sibling `optimise_routes` by defining what a re-plan is (original problem plus progress/changes) and what it is not (a delta against stored state).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the trigger condition: part-way through a shift, and 'At least one progress entry or one change is required' — a re-plan reporting nothing new is 'the original problem' (i.e., call `optimise_routes`). It also names a hard exclusion: multi-trip vehicles declaring `reloads` are refused, with direction on what to send instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_map_issueAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| way_id | No | The OSM way id the observation concerns, when the caller knows it. Optional — the report stands on its own as a first-party observation and is never tied to OSM data beyond this hint. | |
| category | Yes | What kind of mismatch this is. | |
| location | Yes | Where the mismatch was observed (WGS84 decimal degrees). | |
| description | No | Free-text detail of what was observed on the ground, e.g. "barrier across the lane, diversion signed via the B4009". Bounded length. | |
| evidence_url | No | A URL backing the observation (photo, notice, news item), when one exists. Bounded length. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | Always "queued": the report awaits human/agent review and changes nothing about routing immediately. |
| category | Yes | The category, echoed back as its snake_case wire tag. |
| report_id | Yes | The generated id of the queued report (cite it in follow-ups). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It clearly states the report is QUEUED for human/agent review, NEVER changes routing immediately, and NEVER edits any map, plus it names the return value (report_id). This prevents the agent from assuming immediate side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with purpose, then moves to usage trigger, parameter requirements, and side-effect caveat. Every sentence contributes needed information; there is no filler or repetition of title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with no annotations, the description covers purpose, when to use it, parameter requirements, behavioral consequences, and return value. The output schema exists and the description explicitly names the queued report_id, so nothing needed to invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with per-parameter descriptions and category enum semantics, so the baseline is 3. The description usefully compresses required vs optional parameters and lists category values, but adds little meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report that the live world disagrees with the map' and enumerates seven concrete mismatch types. None of the 33 sibling tools covers map-issue reporting, so this is unambiguously distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger: 'Use it when you observe the mismatch mid-task.' It doesn't name exclusions or alternatives, but there are no obvious sibling alternatives, and the queued-observation framing helps the agent understand the tool's role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reverse_geocodeAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | Latitude in decimal degrees (−90 to 90). | |
| lon | Yes | Longitude in decimal degrees (−180 to 180). | |
| limit | No | Maximum number of results (1–10, default 5). The hosted first-party index answers at most 5 nearest hits per lookup. | |
| fov_deg | No | Field of view: the full width in degrees of a cone centred on `heading_deg`, outside which results are dropped — it is the FULL width, so 90 keeps only what lies within 45 degrees either side of dead ahead. Needs `heading_deg` — a cone has to point somewhere. The count of results removed is reported as `out_of_view`. | |
| heading_deg | No | Which way the user is facing, in degrees **clockwise from true north** (0 = north, 90 = east, 180 = south, 270 = west). Supply it and every result is also described from the user's point of view ("just ahead on your right"); omit it and results fall back to cardinal directions ("to the north-east"), so the tool works with or without a compass. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | Nearby places, nearest first. |
| out_of_view | No | How many otherwise-matching places were dropped for falling outside `fov_deg`. Non-zero means there are places near the user that are simply not in front of them — say so rather than reporting nothing nearby. Always 0 when no field of view was set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure and exceeds it. It details the output structure (name, label, lat/lon, type, address parts, distance_m, categories, details object, bearing_deg, direction), dynamic behavior (heading-based relative_bearing_deg, FOV-based out_of_view count), and even advises to 'Prefer reading direction aloud over coordinates.' This is exceptionally transparent about how the tool behaves across different inputs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with purpose, then logically flows into output details, heading behavior, FOV, and a recommendation. However, it repeats the 'FULL width' explanation of fov_deg that already exists verbatim the schema description, and it restates the default/max for limit that is also in the schema. While not wasteful, these redundancies could be trimmed without losing value. The density is justified by complexity but slightly over-lengthy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex tool with 5 parameters and rich output behavior, and the description covers everything an agent needs: input requirements, output field descriptions, edge cases (FOV without heading), fallback behavior (cardinals vs relative), and even a usability recommendation. The output schema exists but the description still explains return fields in detail, which is helpful. No gaps are evident for correct invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds substantial semantic value beyond the schema. It explains the interplay between fov_deg and heading_deg (a cone must point somewhere), the full-width vs. half-width interpretation of fov_deg, the default/max for limit, and the meaning of signed relative_bearing_deg. It also clarifies that out_of_view reports dropped results, which is not in the schema property descriptions. This enriches parameter understanding significantly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Turn coordinates into the nearest places: addresses, POIs and localities with distance in metres.' It explicitly frames itself as 'The inverse of geocode,' immediately distinguishing it from the sibling tool. This gives an agent a precise understanding of what it does and how it relates to geocode.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names geocode as the inverse, which guides when to use this tool. It also explains two usage modes (with or without heading_deg) and how that changes output phrasing. However, it does not mention any other sibling tools like nearby_places, nor does it state when NOT to use this tool. The inverse reference and mode explanations provide strong contextual guidance, but exclusions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
routeAInspect
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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| avoid | No | Road features to avoid as a PREFERENCE. Rendered as the costing's willingness factor set to zero — a thumb on the scale, not a ban. The engine's own reference is explicit that a value of zero is not guaranteed to avoid the feature entirely, and it does not: asking to avoid tolls across the Dartford Crossing returns the same tolled route, because the untolled alternative is fifty kilometres further. Use `exclude` when you mean a ban. | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; when present, ADR dangerous-goods costing options are merged into the request. | |
| origin | Yes | Route origin. | |
| bicycle | No | Bicycle options (bicycle type, road/surface/hill preferences). Requires costing "bicycle". | |
| costing | No | Costing model: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| exclude | No | Road features to exclude outright, rendered as the costing's hard exclusion flag. Two things follow from that and both matter: a hard exclusion can return NO ROUTE rather than a detour (excluding tunnels on a Rotherhithe crossing has no answer), and the flags depend on the routing engine's `allow_hard_exclusions` setting, which the engine does not expose and nothing here can read — so this is never promised, only requested. | |
| emissions | No | The vehicle's emission declaration, for UK clean-air / low-emission zone assessment. Given, the response's `zones` block 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 MapMap gateway, which holds the curated zone dataset; the full dataset is readable at `GET /v1/zones`. | |
| landmarks | No | Name landmarks in the turn instructions (default false): each manoeuvre that passes a recognisable place — a petrol station, a supermarket, a household-name chain — gains a `landmark_instruction` like "Turn right just after the Shell garage" beside the engine's own street-name instruction, which is never replaced. Nothing is named unless it is recognisable from the road, within 40 m of the junction and not tagged as closed, so many routes come back with none: a wrong landmark is worse than no landmark. Needs the MapMap gateway, whose place index does the lookup. | |
| rationale | No | Explain the route (default false): re-routes with each declared truck constraint (truck costing) or avoidance-side routing preference (auto, bicycle, pedestrian, motor_scooter) relaxed and reports the ones that actually changed the route as `rationale.avoided[]`. Opt-in — it costs up to 1 + N extra routing calls, one per declared field plus one combined probe, and it is billed for the ones it actually makes: at most 8 in total, typically fewer, and 1 when there is nothing to probe. Against the hosted gateway each probe is its own metered route call, which is exactly what `POST /route` with `rationale: true` charges for its own fan-out, so the two surfaces price the same explanation the same way. | |
| waypoints | No | Optional intermediate stops, visited in order between origin and destination. | |
| pedestrian | No | Pedestrian options (lit-street preference, wheelchair/blind type, hiking difficulty). Requires costing "pedestrian". | |
| destination | Yes | Route destination. | |
| exclude_polygons | No | Areas to avoid — scenario analysis ("close this bridge and re-route"): an array of polygons, each an array of `[lon, lat]` pairs forming one exterior ring (GeoJSON-style, longitude FIRST). Roads intersecting any ring are excluded from the search. Applies to the Valhalla engine; unsupported on the GraphHopper engine, where it is ignored. |
Output Schema
| Name | Required | Description |
|---|---|---|
| zones | No | Clean-air / low-emission zones this route enters and what the declared vehicle pays in each, with the publishing authority cited (only when `emissions` was declared). Passed through verbatim from the gateway's curated dataset — the same figures `GET /v1/zones` publishes, so a charge can always be audited back to its source. |
| summary | Yes | One-line human-readable summary of the route. |
| avoidance | No | What `avoid`/`exclude` became, and the caveats that go with it (only when either list carried something). |
| landmarks | No | The landmark-annotation summary (only when `landmarks: true` was requested): how many manoeuvres gained a `landmark_instruction`, and a `note` when the per-route cap was hit or the deployment has no place index. A zero with no note means this route genuinely passes nothing recognisable. |
| maneuvers | Yes | Ordered turn-by-turn maneuvers across all legs. |
| rationale | No | Why the route goes this way (only when `rationale: true` was requested; computed for truck, auto, bicycle, pedestrian and motor_scooter costings). |
| distance_m | Yes | Total route distance in metres. |
| duration_s | Yes | Total estimated travel time in seconds. |
| applied_adr | No | The ADR costing merged into the request, or null when no truck profile was given. |
| geometry_polyline6 | Yes | Full route geometry as a Google encoded polyline with six digits of decimal precision (polyline6). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and meets it extensively: it discloses that avoid is a preference not a guarantee (Dartford example), exclude is requested never promised, rationale costs up to 1+N calls, preferred_side is a snapping preference needing an offset coordinate, landmarks may return none, and ADR tunnel_applied describes the load not the route. It also explains engine/GraphHopper differences and gateway dependency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but the tool has 13 parameters and many caveats, and nearly every sentence earns its place by adding behavioral nuance or a failure mode. It is front-loaded with the core computation before the option deep-dives. It could be tightened in places, but the length is defensible for this complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 13-parameter tool, a complete output schema, and no annotations, this description covers everything an agent needs to call the tool correctly: required locations, optional waypoints, engine support, external gateway requirements, cost implications, honest limitations, and feature-specific behavior. There are no obvious gaps that would cause incorrect invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds meaning beyond the schema: it maps costing names to everyday vehicles, spells out truck/pedestrian/bicycle tuning intent, distinguishes avoid vs exclude with consequences, explains 'longitude FIRST' for polygons, and clarifies that preferred_side aliases resolve against the locale's driving side. This is substantive semantic enrichment, not restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Compute a turn-by-turn route between origin and destination (optionally via waypoints).' It also lists concrete outputs (distance, duration, maneuvers, polyline6 geometry) and costing options, so an agent can clearly tell this is the point-to-point routing tool rather than matrix/geocoding or other siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is rich guidance for when to use individual features (truck ADR, pedestrian accessibility, rationale, landmarks, exclude_polygons, emissions) and clear warnings about engine support. However, the description never names sibling tools or states when to use route instead of matrix, plan_ev_route, match_trace, search_along_route, or reachable_area; usage vs alternatives is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_along_routeAInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Free-text POI query, e.g. "coffee", "EV charger", "truck stop". | |
| truck | No | Truck profile (dimensions + ADR declaration). Requires costing "truck"; the detours then respect dimensional/ADR restrictions. | |
| origin | No | Route origin (with `destination`, when no geometry is given). | |
| costing | No | Costing model for the route and detour matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
| category | No | Explicit place category ("fuel", "cafe", "charging_station" — same vocabulary as nearby_places). Colloquial phrases are normalised server-side; prefer this over query for category intents. | |
| destination | No | Route destination. | |
| max_results | No | Maximum results (default 5, at most 25). | |
| geometry_polyline6 | No | An existing route geometry as an encoded polyline6 (the `route` tool's `geometry_polyline6`). Provide either this or `origin` + `destination`, not both. | |
| max_detour_minutes | No | Largest acceptable detour in minutes (default 10, at most 120). |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | The query as interpreted. |
| costing | Yes | The costing the detours were priced with. |
| results | Yes | Places within the detour budget, cheapest detour first. |
| candidate_cap | Yes | The matrix fan-out cap in force. |
| route_length_m | Yes | Length of the route geometry in metres. |
| fuel_attribution | No | Attribution string for fuel-price data sources, present only when at least one returned result carries `fuel_prices` (gateway-preferred mode with `SN_FUEL_PRICES` configured; see [`AlongRouteHit`]). |
| route_distance_m | No | Direct origin→destination distance in metres. |
| route_duration_s | No | Direct origin→destination travel time in seconds (same estimator as the detour legs), when routable. |
| candidates_costed | Yes | Candidates actually priced through the engine (fan-out is capped at `candidate_cap` nearest-to-route). |
| matched_categories | No | The normalised category tokens the candidates were browsed by, present only when a category browse actually ran (an explicit `category`, or a query the server promoted to one). Absent means free-text name matching answered the call, so a caller can tell how its words were understood rather than inferring it from the results. |
| max_detour_minutes | Yes | The detour budget applied, minutes. |
| candidates_considered | Yes | Candidates found near the corridor before pricing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure and does so thoroughly: it gives the exact detour formula, the candidate cap of 25, result fields, costing modes, truck ADR/dimensional restrictions, and server-side category normalization. It also explains how query alone can promote a category phrase to category browsing, making the tool's behavior predictable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every clause earns its place, and the key differentiator is front-loaded: real detour time, never a straight-line guess. The content is organized around input modes, query/category behavior, detour computation, costing, and output, which makes even a dense description navigable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no annotations and rich semantics, the description covers input alternatives, defaults, limits, category vocabulary, detour mathematics, costing behavior, and returned fields. Since an output schema is present, return-structure details are already covered structurally, and nothing necessary for invoking the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial semantic value beyond the schema: it clarifies the query/category distinction, the mutual exclusivity of geometry_polyline6 versus origin+destination, the default and maximum detour minutes, and how costing profiles influence detour computation. This materially improves an agent's ability to choose and format parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find places (POIs) along a route' and immediately distinguishes the tool by emphasizing real detour time rather than a straight-line guess. It also signals how it relates to nearby_places through shared category vocabulary, making the tool's scope clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly covers two input modes (origin+destination vs geometry_polyline6) and gives detailed guidance on when to pass category versus query, including server-side normalization behavior. It does not explicitly state when to prefer this tool over sibling alternatives such as cheapest_fuel_along_route or nearby_places, so exclusions to alternatives remain implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_layer_paintAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | The paint value (any MapLibre-valid JSON: number, colour string or expression array). | |
| layer_id | Yes | Skeleton layer id, e.g. "road-major". Call `list_style_layers` for the accepted ids. | |
| property | Yes | MapLibre paint property name, e.g. "line-width" or "fill-color". | |
| style_id | Yes | Hosted style id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| version | Yes | The newly published version. |
| style_id | Yes | Hosted style id. |
| style_url | Yes | Immutable URL of the compiled style at this version. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the burden of behavioral transparency. It discloses that the operation is non-destructive in effect by publishing 'a new immutable style version', and it states the returned artifacts ('new version and style URL'). It does not mention permissions or failure modes, but the core side-effect is clearly communicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the verb, target, scope, example, prerequisite id source, and return value with no filler. The most important information is front-loaded, and every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is functionally complete: it states the operation, target, examples, where layer ids come from, and what is returned; an output schema handles return shape. It could explicitly mention set_palette as the multi-property alternative for full sibling differentiation, but the gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all four parameters in detail, including value types and examples. The description adds a concrete example ('road-major', 'line-width', '4') and reminds the agent that expressions are valid, but this largely mirrors the schema's existing documentation. With 100% schema coverage, the description's added semantic value is modest.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a precise operation: 'Set one MapLibre paint property on one skeleton layer of a hosted style', immediately clarifying scope and context. It also explains the outcome ('publish the result as a new immutable style version') and explicitly contrasts this with related styling tools by using 'one property' and 'one skeleton layer'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes when to use this tool: when you need to change a single paint property on a layer, and it tells the agent where to get valid layer ids ('Layer ids come from list_style_layers'). It does not explicitly contrast with set_palette or state when not to use it, but the single-layer/single-property framing is clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_paletteAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| colours | Yes | Palette overrides: slot name → CSS colour (e.g. {"water": "#0b2038"}). Call `list_style_layers` for the slot names. | |
| style_id | Yes | Hosted style id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| version | Yes | The newly published version. |
| style_id | Yes | Hosted style id. |
| style_url | Yes | Immutable URL of the compiled style at this version. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that this operation publishes a new immutable style version, which implies the existing style version is not mutated, and it states the return value. It could additionally mention side effects like publication visibility, but the core behavior is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence that front-loads the action, includes a concrete example, covers input sources and colour syntax, and states the return value. There is no fluff or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool does, how to find slot names, allowed colour formats, and the return value. Since an output schema exists, detailed return documentation is unnecessary. A brief note drawing the boundary against set_layer_paint would make it fully complete, but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by enumerating accepted CSS colour formats (#rgb, #rrggbb, #rrggbbaa, rgb(), hsl()) and providing a concrete example of the colours object. This helps the agent construct valid parameter values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Recolour one or more palette slots'), a specific resource ('hosted style'), and a distinctive outcome ('publish the result as a new immutable style version'). It clearly separates this from siblings like set_layer_paint by focusing on palette slots rather than layer paint properties.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: it tells the agent to obtain slot names from list_style_layers and explains how colours should be formatted. It does not explicitly compare against siblings such as set_layer_paint or create_style, so exclusion guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_integration_retroAInspect
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 — never your conversation or code. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| wins | No | What went well (at most 20 entries × 500 bytes). | |
| gotchas | No | Surprises/traps worth documenting (at most 20 entries × 500 bytes). | |
| problems | No | Problems hit during the integration (at most 20). | |
| docs_gaps | No | Documentation gaps hit (at most 20 entries × 500 bytes). | |
| agent_name | No | The submitting agent's name, e.g. "Claude Code" (at most 100 bytes). | |
| what_built | Yes | What was built with MapMap, in one or two sentences (required, at most 500 bytes). | |
| sdk_version | No | MapMap SDK version integrated against, when known (at most 50 bytes). |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | `received` when the gateway stored it; `queued` when it was appended to the local review queue. |
| message | Yes | A short, honest sentence for the agent saying where the retro landed — sent to MapMap, or held in this server's local queue. |
| delivery | Yes | How it was delivered: `gateway` or `local-queue`. |
| retro_id | Yes | Id of the stored retro (gateway id, or the local queue id). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It clearly states the tool only sends structured schema fields, never conversation or code, and that it should be called at most once. This covers the key side effects and privacy boundary a caller needs to know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences: purpose, invocation constraints, and field summary. Every sentence earns its place, and the most critical information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for this tool: it specifies when to call, what conditions must be met, what is sent, what is not sent, and which fields are required or optional. The output schema exists, so not explaining return values is acceptable. Nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter in detail. The description adds a useful summary of required vs. optional fields, but does not materially expand on the schema's own description of each parameter. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Send MapMap a structured integration retro'. It clearly distinguishes this tool from the geo/mapping siblings by naming the unique feedback purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides explicit when-to-use guidance: 'Call at most once, after your MapMap integration works or you stop trying, and only if the developer has approved sending feedback to MapMap.' This is precise and leaves no ambiguity about invocation conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_optimise_jobAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Which problem this is. It selects both the body shape below and the ceiling the submission is judged against. | |
| problem | Yes | The problem itself, in exactly the shape the synchronous tool takes — `optimise_routes` input for `optimise`, `replan_routes` input for `replan`, `matrix` input for `matrix`. Moving a working synchronous call onto this lane changes nothing but the tool you call it with. | |
| webhook_url | No | Optional HTTPS URL to POST a signed `{job_id, kind, status, result_url}` notification to when the job finishes. The RESULT is never pushed — the notification says where to fetch it. Requires a webhook signing secret on the key; without one the submission is refused rather than delivered unsigned. An agent that can poll does not need this: polling with `get_job` is free. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | The job id. Pass it to `get_job` to poll. |
| kind | Yes | `optimise`, `replan` or `matrix`. |
| next | Yes | What to do next, in one sentence: poll `get_job`, and how often is reasonable. |
| status | Yes | Always `queued` — no worker has looked at it yet. |
| result_url | Yes | The HTTP URL this job (and its result) can be fetched from. The same URL a webhook carries. `get_job` is the tool that reads it. |
| units_charged | Yes | Quota units this submission drew. Charged now, handed back in full if the job fails. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the burden and does so richly. It discloses that the tool returns a 202-and-job-id, not a plan; that jobs are queued and processed asynchronously; that unknown fields are refused by name rather than dropped; that polling is free; that units are charged on submission and refunded on failure; and that webhook_url delivers a signed pointer, never the result. These are substantial behavioral traits beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every sentence conveys a distinct and necessary fact: purpose, parameter mapping, refusal behavior, ceilings, re-plan counting, response semantics, polling cost, billing, and webhook guidance. It is front-loaded with the core purpose and then structured to cover the tool's edge cases. Nothing is redundant or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex asynchronous submission tool with no annotations, the description is remarkably complete. It covers purpose, alternatives, parameter semantics, error behavior, quotas, billing, result retrieval via get_job, and optional webhook usage. The output schema may handle return value structure, but the description provides all contextual and operational knowledge an agent needs to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds significant meaning. It explains the kind values map to specific synchronous input shapes, elaborates on the problem parameter with the exact-shape requirement and refusal behavior, and details webhook_url semantics including HTTPS-only, signed notifications, pointer-not-result, and the agent-should-poll caveat. This goes well beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Submit a problem too large to solve inside one request to the asynchronous lane, and get a job id back.' It clearly differentiates this tool from synchronous siblings like optimise_routes and replan_routes, and from get_job which polls the result. The purpose is unambiguous and distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: for problems too large for a single synchronous request. It names the matching synchronous tools and says moving a working synchronous call changes nothing but the tool. It also gives a clear exclusion for webhook_url: 'An agent that can poll should not use it.' This is explicit when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_geodataAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| coordinates | Yes | A sample of the dataset's coordinates. A few dozen is plenty; the check is about ranges and spans, not volume. | |
| declared_crs | Yes | The CRS the dataset claims, e.g. `"EPSG:4326"`, `"EPSG:32610"`, `"EPSG:3857"`, `"EPSG:27700"`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| extent | Yes | Observed extent of the sample, in the dataset's own units. |
| verdict | Yes | |
| problems | Yes | Plain-language findings, most important first. Empty when consistent. |
| suggestions | Yes | What the numbers look like, when they do not match the declaration. |
| interpreted_as | Yes | The CRS family the declaration was understood as. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the behavioral burden and does so thoroughly. It discloses the return shape (verdict, plain-language problem, alternative interpretation), states that no coordinate transformation occurs, and guarantees local computation with no network call or quota. This gives an agent a complete picture of side effects and non-effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: purpose, failure modes, input prescription, output summary, and capability boundary. The description is dense but not bloated, and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter validation tool with a full output schema present, the description covers what matters: what the tool checks, why it exists, what inputs to provide, what outputs to expect, and what it will not do. An agent has everything needed to select and invoke it correctly without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers 100% of parameters, so the baseline is 3; the description adds real value beyond that by explaining why parameters are named x/y rather than lon/lat, giving concrete EPSG examples, and advising that 'a few dozen is plenty'. This helps the agent construct sensible inputs without restating schema content.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a precise verb-check, a specific resource (a dataset's declared CRS against its own coordinates), and a concrete use moment ('before you draw it on a map'). It also names example failure modes (swapped axes, degrees labelled as metres), making the tool's job unmistakable and distinct from the many geo sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly frames when to use it ('before you draw it on a map') and explicitly excludes a major misuse case ('a sanity check, not a reprojection: it never transforms coordinates'). It does not name an alternative tool for reprojection or other coordinate operations, so it stops just short of explicit alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_placesAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Free text to extract place claims from (best-effort heuristic: quoted phrases and Title Case runs after "at/in/near/to/from/ visiting" — not NLP or an LLM call, and it does not attempt itinerary feasibility since there are no explicit times to anchor legs to). Mutually exclusive with `claims`. Max 8,000 characters. | |
| claims | No | Structured claims — the reliable path, and the only path that supports itinerary feasibility. Mutually exclusive with `text`. Max 20 per request. | |
| costing | No | Costing for feasibility legs: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter". | auto |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| summary | Yes | Always present: a concise plain-text summary alongside the structured `results` — several MCP clients (notably ChatGPT connectors) drop non-text content blocks, so this must stand on its own. This same string is also returned as the tool call's text content block, not only inside the structured JSON. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and exceeds it: it explains the non-boolean verdicts, the defamation-avoidance rule, how sequence/claimed_time trigger routing-based contradiction checks, the 20-claim limit, and that `summary` is surfaced as text content. This is exemplary disclosure for a tool with this complexity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though long, every sentence earns its place: purpose, mode selection, verdict semantics, a crucial behavioral caveat, itinerary feasibility, request limits, and output-format note. The structure front-loads the primary action and then layers necessary detail without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with three parameters, no annotations, and real behavioral nuance, the description is complete: it covers input-mode tradeoffs, verdict semantics, constraints, edge-case behavior, and response-format quirks. The presence of an output schema means the description does not need to enumerate return fields, and nothing an agent needs to call the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds real semantic value beyond the schema by labeling `claims` as the reliable path, `text` as best-effort heuristic extraction, and explaining why `sequence` and `claimed_time` together enable feasibility checks. It does not merely repeat schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource: checking whether places and itineraries an AI mentioned are real, findable, and physically possible. The three-verdict model (verified/contradicted/unverified) further sharpens what the tool does and clearly distinguishes it from geocoding or place-search siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells agents when to use structured `claims` versus free `text`, and notes that only `claims` supports itinerary feasibility. It does not explicitly name sibling alternatives like `geocode` or `nearby_places` as things to use instead, but the usage context is clear enough for a unique-purpose tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
- Added
cluster - Added
get_job - Changed
optimise_routes16 fields changed- added
Input schema / $defs / EmissionsFuelAdded value: +{ + "description": "What a vehicle burns, in clean-air-zone scheme terms.", + "oneOf": [ + { + "const": "petrol", + "description": "Petrol, including petrol hybrids (schemes rate a hybrid by its\ncombustion engine's approval).", + "type": "string" + }, + { + "const": "diesel", + "description": "Diesel, including diesel hybrids.", + "type": "string" + }, + { + "const": "electric", + "description": "Battery-electric.", + "type": "string" + }, + { + "const": "hydrogen", + "description": "Hydrogen fuel cell.", + "type": "string" + }, + { + "const": "gas", + "description": "LPG or CNG; rated as petrol by every scheme in the dataset.", + "type": "string" + } + ] +} - added
Input schema / $defs / EmissionsSpecAdded value: +{ + "description": "A vehicle's emission declaration, for clean-air / low-emission zone\nassessment.", + "properties": { + "euro_standard": { + "description": "Its Euro emission standard, 1–6. Heavy-duty approvals are written\nin Roman numerals (Euro VI); declare Euro VI as `6`. Required for\nany combustion fuel — without it no zone can be resolved, and a\nhalf-declared vehicle is indistinguishable from an undeclared one.\nOptional only for `electric` or `hydrogen`.", + "format": "uint8", + "maximum": 255, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "fuel": { + "$ref": "#/$defs/EmissionsFuel", + "description": "What it burns." + }, + "vehicle_category": { + "$ref": "#/$defs/EmissionsVehicleCategory", + "description": "What kind of vehicle this is, in scheme terms." + } + }, + "required": [ + "vehicle_category", + "fuel" + ], + "type": "object" +} - added
Input schema / $defs / EmissionsVehicleCategoryAdded value: +{ + "description": "What a vehicle is, in clean-air-zone scheme terms.\n\nDeclaring this turns \"charge depends on vehicle emissions\" into an\nanswer. Without it a zone can only be named, never priced.", + "oneOf": [ + { + "const": "car", + "description": "A private car.", + "type": "string" + }, + { + "const": "van", + "description": "A van or light goods vehicle up to 3.5 tonnes.", + "type": "string" + }, + { + "const": "minibus", + "description": "A minibus (typically 8+ passenger seats, up to 5 tonnes).", + "type": "string" + }, + { + "const": "hgv", + "description": "A heavy goods vehicle over 3.5 tonnes.", + "type": "string" + }, + { + "const": "bus", + "description": "A bus over 5 tonnes.", + "type": "string" + }, + { + "const": "coach", + "description": "A coach over 5 tonnes.", + "type": "string" + }, + { + "const": "taxi", + "description": "A licensed hackney carriage.", + "type": "string" + }, + { + "const": "phv", + "description": "A private hire vehicle.", + "type": "string" + }, + { + "const": "motorcycle", + "description": "A motorcycle, moped or tricycle.", + "type": "string" + }, + { + "const": "motorhome", + "description": "A motor caravan or campervan.", + "type": "string" + } + ] +} - added
Input schema / $defs / OptimiseVehicleSpec / properties / reloadsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/ReloadsSpec" + }, + { + "type": "null" + } + ], + "description": "Let this vehicle return to a depot, reload and go out again — the\nwaste-collection tipping round, the van that comes back for a\nsecond wave of parcels." +} - added
Input schema / $defs / OptimiseVehicleSpec / properties / territory_idsAdded value: +{ + "description": "Ids of the request's `territories` this vehicle may work in.\nOmitted or empty, the vehicle is UNRESTRICTED and may serve any\ntask, inside a territory or outside every one of them. Listed, the\nvehicle may serve a task only if that task sits inside at least one\nof the named territories.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] +} - added
Input schema / $defs / RelaxSpecAdded value: +{ + "description": "What the caller is willing to give up if the first solve leaves work\nunassigned. At least one field is required.", + "properties": { + "allow_overtime_s": { + "description": "Extend every vehicle's shift END by this many seconds. Shift starts\nare never moved earlier — a driver cannot begin before they begin.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "time_windows_by_s": { + "description": "Widen every task time window by this many seconds at EACH end. A\n09:00–12:00 window with 1800 becomes 08:30–12:30.", + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" +} - added
Input schema / $defs / ReloadsSpecAdded value: +{ + "description": "A vehicle's multi-trip reload plan.", + "properties": { + "depot": { + "anyOf": [ + { + "$ref": "#/$defs/LatLon" + }, + { + "type": "null" + } + ], + "description": "Where the vehicle reloads. Omitted, its own `start` is used (or its\n`end` if it declared only that)." + }, + "max_trips": { + "description": "How many trips this vehicle may run in its shift, 2–5. A BUDGET,\nnot a prediction: the shift is cut into that many fixed windows\nbefore the solve, so asking for five trips on a shift that supports\nthree shrinks every window to a fifth and can make the whole day\nworse. Ask for the number of trips you actually expect to run.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "reload_time_s": { + "description": "Seconds at the depot between trips — tipping, reloading, the\nweighbridge. Held out of the shift before it is partitioned, so it\nis never accidentally spent driving.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "max_trips" + ], + "type": "object" +} - added
Input schema / $defs / TerritorySpecAdded value: +{ + "description": "One named territory: a polygon that bounds which vehicle may serve\nwhich stop.", + "properties": { + "id": { + "description": "Caller-chosen id, echoed back and referenced by\n`vehicles[].territory_ids`. Must be unique within the request.", + "type": "string" + }, + "polygon": { + "description": "The outer ring as GeoJSON `[lon, lat]` positions — longitude\nFIRST. Closed or open; an unclosed ring is closed for you.", + "items": { + "items": { + "format": "double", + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "type": "array" + } + }, + "required": [ + "id", + "polygon" + ], + "type": "object" +} - added
Input schema / properties / avoid_zonesAdded value: +{ + "description": "Keep the optimisation's travel-time matrix out of every zone the\ndeclared vehicle would be charged or banned in. Requires\n`emissions`.", + "type": [ + "boolean", + "null" + ] +} - added
Input schema / properties / emissionsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/EmissionsSpec" + }, + { + "type": "null" + } + ], + "description": "The fleet's emission declaration, for UK clean-air / low-emission\nzone assessment. On its own it annotates: the response's `zones`\nblock names every zone containing one of the problem's own\nlocations and what this vehicle would pay there. With\n`avoid_zones` it also steers the internal travel-time matrix away\nfrom those zones, so the plan itself changes." +} - added
Input schema / properties / relax_if_unassignedAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/RelaxSpec" + }, + { + "type": "null" + } + ], + "description": "Re-solve ONCE with these relaxations if the first solve leaves work\nunassigned, and say honestly which plan came back. At most one\nsecond solve, never beyond the caps you state, and the relaxed plan\nis returned only if it assigns MORE work than the first — giving\naway constraints for nothing is strictly worse than not giving them\naway. Breaks are never widened, nor are capacities, skills,\nterritories or task caps: only time windows move, and only by the\nstated amounts. Bills as two solves when the second one runs." +} - added
Input schema / properties / territoriesAdded value: +{ + "description": "Fleet territories: named polygons that bound which vehicle may\nserve which stop, referenced by `vehicles[].territory_ids`. These\nare request data — caller-drawn rounds, validated per call and\nnever stored. Nothing to do with clean-air zones or with the\noffline map packages of the same word.", + "items": { + "$ref": "#/$defs/TerritorySpec" + }, + "type": [ + "array", + "null" + ] +} - added
Output schema / properties / relaxationAdded value: +{ + "description": "The relaxation report: the caps requested, whether a second solve\nran, whether ITS plan is the one returned, what was widened, and\nwhat is still unassigned. Present only when `relax_if_unassigned`\nwas declared.\n\nAlways read `second_solve` and `relaxed_plan_used` before telling\nanyone the day fits. A plan produced under relaxation has had\npromises moved, and the block is what says so." +} - added
Output schema / properties / reloadsAdded value: +{ + "description": "The multi-trip split: each vehicle's trips, their windows, the\ndepot each returns to, and the stated approximation. Present only\nwhen a vehicle declared `reloads`.\n\nRead the `basis` inside it before quoting arrival times. The trip\nwindows are fixed BEFORE the solve, so a lorry that tips early\ncannot lend the spare time to its next trip: stops can come back\nunassigned that a truly sequential model would have served. The\nplan is feasible, never optimistic — it cannot put a vehicle in two\nplaces at once — but it is not optimal. Re-plan after each tip\nthrough `replan_routes` for the tighter answer." +} - added
Output schema / properties / territoriesAdded value: +{ + "description": "How the territories bound the plan: which vehicle was eligible for\nwhat, and any task no eligible vehicle existed for. Present only\nwhen `territories` was declared." +} - added
Output schema / properties / zonesAdded value: +{ + "description": "Clean-air / low-emission zones touching the problem's own\nlocations, and what the declared vehicle pays in each. Present only\nwhen `emissions` was declared." +}
- Added
replan_routes - Changed
route17 fields changed- added
Input schema / $defs / AvoidFeatureAdded value: +{ + "description": "A road feature to avoid as a PREFERENCE, not a ban. \"tolls\" and \"highways\" apply to motorised costings only (auto, truck, bus, motor_scooter, motorcycle); \"ferries\" applies to every costing. Asking for one on a costing whose engine table has no field for it is refused rather than silently ignored.", + "enum": [ + "tolls", + "highways", + "ferries" + ], + "type": "string" +} - added
Input schema / $defs / EmissionsFuelAdded value: +{ + "description": "What a vehicle burns, in clean-air-zone scheme terms.", + "oneOf": [ + { + "const": "petrol", + "description": "Petrol, including petrol hybrids (schemes rate a hybrid by its\ncombustion engine's approval).", + "type": "string" + }, + { + "const": "diesel", + "description": "Diesel, including diesel hybrids.", + "type": "string" + }, + { + "const": "electric", + "description": "Battery-electric.", + "type": "string" + }, + { + "const": "hydrogen", + "description": "Hydrogen fuel cell.", + "type": "string" + }, + { + "const": "gas", + "description": "LPG or CNG; rated as petrol by every scheme in the dataset.", + "type": "string" + } + ] +} - added
Input schema / $defs / EmissionsSpecAdded value: +{ + "description": "A vehicle's emission declaration, for clean-air / low-emission zone\nassessment.", + "properties": { + "euro_standard": { + "description": "Its Euro emission standard, 1–6. Heavy-duty approvals are written\nin Roman numerals (Euro VI); declare Euro VI as `6`. Required for\nany combustion fuel — without it no zone can be resolved, and a\nhalf-declared vehicle is indistinguishable from an undeclared one.\nOptional only for `electric` or `hydrogen`.", + "format": "uint8", + "maximum": 255, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "fuel": { + "$ref": "#/$defs/EmissionsFuel", + "description": "What it burns." + }, + "vehicle_category": { + "$ref": "#/$defs/EmissionsVehicleCategory", + "description": "What kind of vehicle this is, in scheme terms." + } + }, + "required": [ + "vehicle_category", + "fuel" + ], + "type": "object" +} - added
Input schema / $defs / EmissionsVehicleCategoryAdded value: +{ + "description": "What a vehicle is, in clean-air-zone scheme terms.\n\nDeclaring this turns \"charge depends on vehicle emissions\" into an\nanswer. Without it a zone can only be named, never priced.", + "oneOf": [ + { + "const": "car", + "description": "A private car.", + "type": "string" + }, + { + "const": "van", + "description": "A van or light goods vehicle up to 3.5 tonnes.", + "type": "string" + }, + { + "const": "minibus", + "description": "A minibus (typically 8+ passenger seats, up to 5 tonnes).", + "type": "string" + }, + { + "const": "hgv", + "description": "A heavy goods vehicle over 3.5 tonnes.", + "type": "string" + }, + { + "const": "bus", + "description": "A bus over 5 tonnes.", + "type": "string" + }, + { + "const": "coach", + "description": "A coach over 5 tonnes.", + "type": "string" + }, + { + "const": "taxi", + "description": "A licensed hackney carriage.", + "type": "string" + }, + { + "const": "phv", + "description": "A private hire vehicle.", + "type": "string" + }, + { + "const": "motorcycle", + "description": "A motorcycle, moped or tricycle.", + "type": "string" + }, + { + "const": "motorhome", + "description": "A motor caravan or campervan.", + "type": "string" + } + ] +} - added
Input schema / $defs / ExcludeFeatureAdded value: +{ + "description": "A road feature to exclude outright. A hard exclusion can leave a request with no path at all — that is the honest answer, not a failure — and it depends on the routing engine's own hard-exclusion setting, which nothing here can read.", + "enum": [ + "tolls", + "highways", + "ferries", + "bridges", + "tunnels" + ], + "type": "string" +} - removed
Input schema / $defs / LatLonRemoved value: -{ - "description": "A WGS84 coordinate pair in decimal degrees.", - "properties": { - "lat": { - "description": "Latitude in decimal degrees (−90 to 90).", - "format": "double", - "type": "number" - }, - "lon": { - "description": "Longitude in decimal degrees (−180 to 180).", - "format": "double", - "type": "number" - } - }, - "required": [ - "lat", - "lon" - ], - "type": "object" -} - added
Input schema / $defs / PreferredSideKindAdded value: +{ + "description": "Side-of-street preference for arriving at or departing from a location.\n\nCarries both vocabularies: MapMap's own `same`/`opposite`/`either` and\nthe OSRM/Mapbox `approaches` words `curb`/`unrestricted`, which are\naliases for `same` and `either`. Both spell the same request, on this\nsurface and on the HTTP API.", + "oneOf": [ + { + "const": "same", + "description": "The side the location itself projects to — the kerb, resolved\nagainst the locale's driving side (the left kerb in the UK, the\nright in Germany).", + "type": "string" + }, + { + "const": "opposite", + "description": "The far side of the road from the location.", + "type": "string" + }, + { + "const": "either", + "description": "No side preference.", + "type": "string" + }, + { + "const": "curb", + "description": "Alias for `same`, from the OSRM/Mapbox `approaches` vocabulary.", + "type": "string" + }, + { + "const": "unrestricted", + "description": "Alias for `either`, from the OSRM/Mapbox `approaches` vocabulary.", + "type": "string" + } + ] +} - added
Input schema / $defs / RouteLocationAdded value: +{ + "description": "One location of a `route` request: a coordinate, plus the optional\nkerbside approach for arriving at it.\n\nA bare `{lat, lon}` is still a complete location — every kerbside field\nis optional and omitting all of them is exactly the request that was\nmade before they existed.", + "properties": { + "lat": { + "description": "Latitude in decimal degrees (−90 to 90).", + "format": "double", + "type": "number" + }, + "lon": { + "description": "Longitude in decimal degrees (−180 to 180).", + "format": "double", + "type": "number" + }, + "preferred_side": { + "anyOf": [ + { + "$ref": "#/$defs/PreferredSideKind" + }, + { + "type": "null" + } + ], + "description": "Which side of the street to arrive on (or depart from). `same` (or\n`curb`) puts the vehicle on the door's side of the road, resolved\nagainst the locale's driving side. Two honest limits: this is a\n**snapping preference**, not a manoeuvre guarantee — the engine\nprefers an edge on that side, it does not promise the driver never\ncrosses — and it needs a coordinate genuinely offset from the road\ncentreline, because a point on the centreline has no side." + }, + "street_side_max_distance_m": { + "description": "Metres: further than this from the road centreline, the side of\nstreet is treated as `none` and `preferred_side` does nothing.\nEngine default 1000 m. Together with `street_side_tolerance_m` this\nis a WINDOW: a pair that leaves no window (tolerance at or above\nmax distance) is refused here rather than answered with a route on\nwhich the kerbside preference was silently inert.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "street_side_tolerance_m": { + "description": "Metres: nearer than this to the road centreline, the side of street\nis treated as `none` and `preferred_side` does nothing. Engine\ndefault 5 m.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "lat", + "lon" + ], + "type": "object" +} - added
Input schema / properties / avoidAdded value: +{ + "description": "Road features to avoid as a PREFERENCE. Rendered as the costing's\nwillingness factor set to zero — a thumb on the scale, not a ban.\nThe engine's own reference is explicit that a value of zero is not\nguaranteed to avoid the feature entirely, and it does not: asking\nto avoid tolls across the Dartford Crossing returns the same tolled\nroute, because the untolled alternative is fifty kilometres\nfurther. Use `exclude` when you mean a ban.", + "items": { + "$ref": "#/$defs/AvoidFeature" + }, + "type": [ + "array", + "null" + ] +} - changed
Input schema / properties / destination / $refPrevious value: -"#/$defs/LatLon"New value: +"#/$defs/RouteLocation" - added
Input schema / properties / emissionsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/EmissionsSpec" + }, + { + "type": "null" + } + ], + "description": "The vehicle's emission declaration, for UK clean-air / low-emission\nzone assessment. Given, the response's `zones` block names every\nzone the route enters and what THIS vehicle pays there, with the\npublishing authority cited. Without it a zone can only be named,\nnever priced. Needs the MapMap gateway, which holds the curated\nzone dataset; the full dataset is readable at `GET /v1/zones`." +} - added
Input schema / properties / excludeAdded value: +{ + "description": "Road features to exclude outright, rendered as the costing's hard\nexclusion flag. Two things follow from that and both matter: a hard\nexclusion can return NO ROUTE rather than a detour (excluding\ntunnels on a Rotherhithe crossing has no answer), and the flags\ndepend on the routing engine's `allow_hard_exclusions` setting,\nwhich the engine does not expose and nothing here can read — so\nthis is never promised, only requested.", + "items": { + "$ref": "#/$defs/ExcludeFeature" + }, + "type": [ + "array", + "null" + ] +} - changed
Input schema / properties / origin / $refPrevious value: -"#/$defs/LatLon"New value: +"#/$defs/RouteLocation" - changed
Input schema / properties / waypoints / items / $refPrevious value: -"#/$defs/LatLon"New value: +"#/$defs/RouteLocation" - added
Output schema / $defs / AppliedAvoidanceAdded value: +{ + "description": "What the avoidance lists actually did, reported back so a 200 is never\nreadable as a certificate.", + "properties": { + "avoid": { + "description": "The `avoid` values that were applied, echoed back.", + "items": { + "type": "string" + }, + "type": "array" + }, + "caveats": { + "description": "The caveats that apply to this request, in words fit to repeat to a\nuser. Always present when anything was applied.", + "items": { + "type": "string" + }, + "type": "array" + }, + "costing_option_fields": { + "description": "The engine costing-option fields these words became, e.g.\n`{\"use_tolls\": 0.0, \"exclude_ferries\": true}`. This is the whole of\nwhat was sent — there is no hidden second mechanism." + }, + "exclude": { + "description": "The `exclude` values that were applied, echoed back.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "costing_option_fields", + "caveats" + ], + "type": "object" +} - added
Output schema / properties / avoidanceAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/AppliedAvoidance" + }, + { + "type": "null" + } + ], + "description": "What `avoid`/`exclude` became, and the caveats that go with it\n(only when either list carried something)." +} - added
Output schema / properties / zonesAdded value: +{ + "description": "Clean-air / low-emission zones this route enters and what the\ndeclared vehicle pays in each, with the publishing authority cited\n(only when `emissions` was declared). Passed through verbatim from\nthe gateway's curated dataset — the same figures `GET /v1/zones`\npublishes, so a charge can always be audited back to its source." +}
- Added
submit_optimise_job
8 tool updates
- Added
cheapest_charging_along_route - Changed
geocode11 fields changed- added
Input schema / properties / cityAdded value: +{ + "description": "Structured component: town or city, e.g. \"London\". Matches the\ncontaining city as well as the immediate locality, so a suburb name\nworks here too.", + "type": [ + "string", + "null" + ] +} - added
Input schema / properties / countryAdded value: +{ + "description": "Structured component: ISO 3166-1 alpha-2 code or country name —\n\"GB\", \"gb\", \"United Kingdom\" and \"UK\" all mean the same country.\nA value naming no country is refused rather than quietly applied as\na filter that matches nothing.", + "type": [ + "string", + "null" + ] +} - added
Input schema / properties / housenumberAdded value: +{ + "description": "Structured component: house number, e.g. \"10\" or \"221B\". Only\nmeaningful alongside `street` — a house number on its own excludes\nnearly everything and identifies nothing.", + "type": [ + "string", + "null" + ] +} - added
Input schema / properties / postcodeAdded value: +{ + "description": "Structured component: postcode in any spacing or case — \"SW1A 2AA\"\nand \"sw1a2aa\" are one query. A bare UK outward code (\"SW1A\")\nselects the whole district.", + "type": [ + "string", + "null" + ] +} - changed
Input schema / properties / query / descriptionPrevious value: -"Free-text place query, e.g. \"Dover ferry terminal\"."New value: +"Free-text place query, e.g. \"Dover ferry terminal\". Required unless\nat least one structured component is supplied." - changed
Input schema / properties / query / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Input schema / properties / streetAdded value: +{ + "description": "Structured component: street name, e.g. \"Downing Street\". Matches\nthe street of addresses and POIs (transliterated street names\nincluded) as well as the street itself.", + "type": [ + "string", + "null" + ] +} - removed
Input schema / requiredRemoved value: -[ - "query" -] - added
Output schema / $defs / GeocodeHit / properties / matchAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/GeocodeMatch" + }, + { + "type": "null" + } + ], + "description": "How far this hit can be trusted to be the place that was asked\nfor — see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on." +} - added
Output schema / $defs / GeocodeMatchAdded value: +{ + "description": "How well one geocoding result answers what was actually asked.\n\nGeocoding's real failure mode is not \"no answer\" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for — an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.", + "properties": { + "components": { + "$ref": "#/$defs/GeocodeMatchComponents", + "description": "Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only." + }, + "score_gap": { + "description": "The top result's score minus the runner-up's, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score — so a `0` is \"no signal\", not\n\"a tie\".", + "format": "double", + "type": "number" + }, + "source": { + "description": "Which backend answered: \"mapmap-index\" (the first-party index) or\n\"photon\".", + "type": "string" + } + }, + "required": [ + "components", + "score_gap", + "source" + ], + "type": "object" +} - added
Output schema / $defs / GeocodeMatchComponentsAdded value: +{ + "description": "Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n\"matched\", \"inferred\" or \"unmatched\"; a component that was not supplied\nis absent entirely.\n\n* \"matched\" — the result's own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: \"London\"`\n matches \"City of London\").\n* \"inferred\" — the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* \"unmatched\" — the result carries no value for that component at all.", + "properties": { + "city": { + "description": "Verdict on the supplied `city`.", + "type": [ + "string", + "null" + ] + }, + "country": { + "description": "Verdict on the supplied `country`.", + "type": [ + "string", + "null" + ] + }, + "housenumber": { + "description": "Verdict on the supplied `housenumber`.", + "type": [ + "string", + "null" + ] + }, + "postcode": { + "description": "Verdict on the supplied `postcode`.", + "type": [ + "string", + "null" + ] + }, + "street": { + "description": "Verdict on the supplied `street`.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +}
- Added
get_usage - Added
list_place_categories - Added
match_trace - Changed
plan_day3 fields changed- added
Output schema / $defs / GeocodeHit / properties / matchAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/GeocodeMatch" + }, + { + "type": "null" + } + ], + "description": "How far this hit can be trusted to be the place that was asked\nfor — see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on." +} - added
Output schema / $defs / GeocodeMatchAdded value: +{ + "description": "How well one geocoding result answers what was actually asked.\n\nGeocoding's real failure mode is not \"no answer\" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for — an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.", + "properties": { + "components": { + "$ref": "#/$defs/GeocodeMatchComponents", + "description": "Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only." + }, + "score_gap": { + "description": "The top result's score minus the runner-up's, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score — so a `0` is \"no signal\", not\n\"a tie\".", + "format": "double", + "type": "number" + }, + "source": { + "description": "Which backend answered: \"mapmap-index\" (the first-party index) or\n\"photon\".", + "type": "string" + } + }, + "required": [ + "components", + "score_gap", + "source" + ], + "type": "object" +} - added
Output schema / $defs / GeocodeMatchComponentsAdded value: +{ + "description": "Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n\"matched\", \"inferred\" or \"unmatched\"; a component that was not supplied\nis absent entirely.\n\n* \"matched\" — the result's own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: \"London\"`\n matches \"City of London\").\n* \"inferred\" — the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* \"unmatched\" — the result carries no value for that component at all.", + "properties": { + "city": { + "description": "Verdict on the supplied `city`.", + "type": [ + "string", + "null" + ] + }, + "country": { + "description": "Verdict on the supplied `country`.", + "type": [ + "string", + "null" + ] + }, + "housenumber": { + "description": "Verdict on the supplied `housenumber`.", + "type": [ + "string", + "null" + ] + }, + "postcode": { + "description": "Verdict on the supplied `postcode`.", + "type": [ + "string", + "null" + ] + }, + "street": { + "description": "Verdict on the supplied `street`.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +}
- Added
plan_ev_route - Changed
search_along_route3 fields changed- added
Output schema / $defs / GeocodeHit / properties / matchAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/GeocodeMatch" + }, + { + "type": "null" + } + ], + "description": "How far this hit can be trusted to be the place that was asked\nfor — see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on." +} - added
Output schema / $defs / GeocodeMatchAdded value: +{ + "description": "How well one geocoding result answers what was actually asked.\n\nGeocoding's real failure mode is not \"no answer\" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n answer does not carry the address that was asked for — an `unmatched`\n postcode means the result has no postcode at all, `inferred` means it\n has a different one. Neither is a match. Say so rather than presenting\n the hit as the address, and reach for `verify_places` when the address\n came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n and the runner-up, which is exactly when to show the alternatives\n instead of picking one for the user.", + "properties": { + "components": { + "$ref": "#/$defs/GeocodeMatchComponents", + "description": "Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only." + }, + "score_gap": { + "description": "The top result's score minus the runner-up's, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score — so a `0` is \"no signal\", not\n\"a tie\".", + "format": "double", + "type": "number" + }, + "source": { + "description": "Which backend answered: \"mapmap-index\" (the first-party index) or\n\"photon\".", + "type": "string" + } + }, + "required": [ + "components", + "score_gap", + "source" + ], + "type": "object" +} - added
Output schema / $defs / GeocodeMatchComponentsAdded value: +{ + "description": "Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n\"matched\", \"inferred\" or \"unmatched\"; a component that was not supplied\nis absent entirely.\n\n* \"matched\" — the result's own field carries the value asked for (case-\n and accent-insensitive, and by containment, so `city: \"London\"`\n matches \"City of London\").\n* \"inferred\" — the result carries a value for that component, but not\n the one asked for. It reached the page through ranking, as when a\n street is found by its transliterated name and displayed under its\n canonical one.\n* \"unmatched\" — the result carries no value for that component at all.", + "properties": { + "city": { + "description": "Verdict on the supplied `city`.", + "type": [ + "string", + "null" + ] + }, + "country": { + "description": "Verdict on the supplied `country`.", + "type": [ + "string", + "null" + ] + }, + "housenumber": { + "description": "Verdict on the supplied `housenumber`.", + "type": [ + "string", + "null" + ] + }, + "postcode": { + "description": "Verdict on the supplied `postcode`.", + "type": [ + "string", + "null" + ] + }, + "street": { + "description": "Verdict on the supplied `street`.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +}
34 tool updates
- First observed
cheapest_fuel_along_route - First observed
check_adr_tunnel - First observed
check_clearance_on_route - First observed
check_style_contrast - First observed
create_style - First observed
elevation - First observed
geo_area - First observed
geo_bbox - First observed
geo_bearing - First observed
geo_centroid - First observed
geo_destination - First observed
geo_distance - First observed
geo_length - First observed
geo_nearest_point_on_line - First observed
geo_point_in_polygon - First observed
geo_simplify - First observed
geocode - First observed
get_style - First observed
list_style_layers - First observed
matrix - First observed
nearby_places - First observed
optimise_routes - First observed
order_stops - First observed
plan_day - First observed
reachable_area - First observed
report_map_issue - First observed
reverse_geocode - First observed
route - First observed
search_along_route - First observed
set_layer_paint - First observed
set_palette - First observed
submit_integration_retro - First observed
validate_geodata - First observed
verify_places
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
- geoOAuthco.thinair
Geocoding, truck routing, traffic, weather, and place search via MCP — 11 hosted tools.
140+ data APIs for agents: finance, banking validation, geo, weather, text. One API key.
HERE MCP — premium geocoding, places, and TRAFFIC-AWARE routing from HERE
Geospatial intelligence with Mapbox APIs like geocoding, POI search, directions, isochrones, etc.
Related MCP Servers
- AlicenseAqualityDmaintenanceGeospatial API tools for AI agents — geocoding, reverse geocoding, routing, isochrone, distance matrix, static maps, H3 hexagons, elevation, GPS map-matching, point-in-polygon, address normalisation, timezone lookup, and batch geocoding. Built on OpenStreetMap infrastructure. Cost-effective alternative to Google Maps API.1837MIT

ThinAir Geoofficial
AlicenseAqualityCmaintenanceLocation & routing intelligence for AI agents — geocoding, truck routing, traffic, weather, and place search.3019681MIT
Magic Lane MCP Serverofficial
AlicenseBqualityBmaintenanceEnables AI agents to become geospatially intelligent assistants with tools for location search, smart routing, round trip planning, reverse geocoding, isochrone analysis, route visualization, geofence management, and interactive map display.8297Apache 2.0- AlicenseBqualityDmaintenanceA comprehensive MCP server providing 30 tools for geocoding, routing, and OpenStreetMap data analysis. It enables AI assistants to search for locations, calculate travel routes, and perform quality assurance checks on map data.304625MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Most tools target a distinct action and resource pair, and descriptions are explicit about which tool fits which scenario. The closest overlaps—plan_ev_route vs cheapest_charging_along_route, and route vs plan_day vs order_stops vs optimise_routes—are mitigated by clear guidance, so an agent can usually pick correctly.
Tool names overwhelmingly follow a verb_noun snake_case pattern (plan_ev_route, set_palette, list_style_layers) with a consistent geo_ prefix for geometry helpers. Minor deviations like elevation, route, and matrix are short and readable but break the strict verb_noun convention.
At 39 tools, this surface is well past the 25+ threshold and feels heavy even for a broad mapping platform. The set spans routing, geocoding, places, styles, EV/fuel, telematics, usage, and feedback, which would be easier for an agent to navigate if split into smaller domain-focused servers.
For the stated breadth, coverage is strong: routing, multi-stop planning, VRP, EV/fuel detours, geocoding, places, geometry, style lifecycle, and telematics all have workable primary paths. Minor gaps like no style deletion, no route alternatives, and no batch geocoding are present but do not create dead ends for core workflows.