Skip to main content
Glama

cheapest_fuel_along_route

Find the cheapest fuel along a route, with the REAL extra travel time of stopping at each station, never a straight-line guess. Provide origin + destination (a route is computed) or an existing route's geometry_polyline6, plus a fuel code ("diesel" default, "petrol_95", "petrol_98", "premium_diesel", "e85", "lpg") and max_detour_minutes (default 10). Stations come from the live open-data price feeds (UK retailer feeds of the closed CMA interim scheme and/or the statutory Fuel Finder, FR prix-carburants, DE Tankerkoenig; the response's fuel_attribution names the ones actually matched), are priced through the routing engine with your costing (a truck profile makes detours respect dimensional/ADR restrictions) and ranked freshest-priced first and cheapest within that. Each result carries price {value, currency, updated_at, stale}, detour_minutes/detour_km, and saving_per_litre vs the cheapest on-route baseline (pass fill_litres to also get saving_total). stale = not verifiably fresher than 24 h: true unless BOTH the price's own updated_at and the snapshot's fetch time are inside that window, and true whenever either is missing. A stale price is ranked below every fresh one, is never the baseline, and carries NO saving_per_litre, quote it as "last seen at X on ", never as a saving. say is ALWAYS present and is the whole answer as one short spoken line, composed by the gateway with the number, the detour and the honest qualifier already in it. Prefer reading it verbatim to writing your own summary: a stale price's line states the figure and the day it was last seen and claims no saving, and an empty result's line names the cause rather than implying there is no fuel on that road. coverage says what the price snapshot holds (stations, countries, sources) and, when it holds UK stations, carries a statement naming the UK retailers covered, with uk_retailers and uk_partial. Show the statement with any UK answer: when uk_partial is true UK prices come only from those retailers' feeds, so an empty UK result means "none from these retailers", never "no fuel here". An empty result also carries note, the cause in prose, which on such a route ends with that statement. Requires the MapMap gateway; answers a clear error when the deployment has no fuel-price dataset. Display the returned fuel_attribution with the prices.

Input Schema

NameRequiredDescriptionDefault
fuelNoWhich 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).
truckNoTruck profile (dimensions + ADR declaration). Requires costing "truck"; the detours then respect dimensional/ADR restrictions.
originNoRoute origin (with `destination`, when no geometry is given).
costingNoCosting model for the route and detour matrix: "auto" (default), "truck", "bicycle", "pedestrian" or "motor_scooter".auto
destinationNoRoute destination.
fill_litresNoOptional fill size in litres; each result then also carries `saving_total` = `saving_per_litre` × `fill_litres`.
max_resultsNoMaximum results (default 5, at most 25).
geometry_polyline6NoAn existing route geometry as an encoded polyline6 (the `route` tool's `geometry_polyline6`). Provide either this or `origin` + `destination`, not both.
max_detour_minutesNoLargest acceptable detour in minutes (default 10, at most 120).

Output Schema

NameRequiredDescriptionDefault
sayYes**Always present.** The whole answer as one short spoken line, composed by the gateway: the number, the detour, and the honest qualifier where one applies. Safe to read to a driver verbatim, and safe on an empty result, where it names the cause rather than implying there is no fuel on the road. A stale price's line states the figure and the day it was last seen and claims no saving.
fuelYesThe normalised fuel code that was priced (e.g. "diesel").
noteNoWhy `results` is empty, when it is: the cause, not a bare list. On a UK route where UK prices come only from some retailers' feeds it ends with `coverage.statement`, so an empty answer is never read as "no fuel here". Absent when there are results.
costingYesThe costing the detours were priced with.
resultsYesStations within the detour budget, cheapest first (price, then detour).
baselineYesThe cheapest effectively-on-route option per currency (empty when no station sits on the route itself).
coverageNoWhat the deployment's price snapshot covers. On a UK route, show `coverage.statement` to the user alongside the results: it names the UK retailers covered, and an empty UK result means "none from these retailers", never "no fuel here". Absent when the gateway is too old to report coverage.
candidate_capYesThe matrix fan-out cap in force.
route_length_mYesLength of the route geometry in metres.
fuel_attributionNoAttribution string for the fuel-price data sources actually returned, display it with the prices (a licence obligation).
route_distance_mNoDirect origin→destination distance in metres.
route_duration_sNoDirect origin→destination travel time in seconds (same estimator as the detour legs), when routable.
candidates_costedYesCandidates actually priced through the engine (fan-out capped at `candidate_cap`, cheapest kept).
max_detour_minutesYesThe detour budget applied, minutes.
candidates_consideredYesStations selling the fuel that passed the corridor pre-filter.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / note
      Added value: +{
      +  "description": "Why `results` is empty, when it is: the cause, not a bare list. On\na UK route where UK prices come only from some retailers' feeds it\nends with `coverage.statement`, so an empty answer is never read as\n\"no fuel here\". Absent when there are results.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  2. Changed3 schema fields changed
    • addedOutput schema / $defs / FuelCoverage
      Added value: +{
      +  "description": "What the deployment's fuel-price snapshot actually holds, as the\ngateway reports it.",
      +  "properties": {
      +    "countries": {
      +      "description": "ISO 3166-1 alpha-2 countries the snapshot holds stations for. A\ncountry absent here cannot produce results.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "sources": {
      +      "additionalProperties": {
      +        "format": "uint",
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "description": "Feed code to station count (e.g. \"uk\", \"uk-fuelfinder\", \"fr\", \"de\").",
      +      "type": "object"
      +    },
      +    "statement": {
      +      "description": "One sentence naming where UK prices come from and which retailers\nare in. Show it to the user with any UK answer: when `uk_partial`\nis true, an empty UK result means \"none from these retailers\",\nnever \"no fuel here\". Present only when the snapshot holds UK\nstations.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "stations": {
      +      "description": "Stations in the whole snapshot.",
      +      "format": "uint",
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "uk_partial": {
      +      "description": "True when UK prices come only from the retailer feeds of the\nclosed CMA interim scheme, which cover some retailers and not\nothers, rather than from the statutory Fuel Finder. Present only\nwhen the snapshot holds UK stations.",
      +      "type": [
      +        "boolean",
      +        "null"
      +      ]
      +    },
      +    "uk_retailers": {
      +      "description": "The UK retailers in the snapshot, largest first. Present only when\nthe snapshot holds UK stations.",
      +      "items": {
      +        "$ref": "#/$defs/FuelRetailer"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "stations",
      +    "countries",
      +    "sources"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / $defs / FuelRetailer
      Added value: +{
      +  "description": "One UK retailer (or, with Fuel Finder loaded, forecourt brand) in the\ndeployment's fuel-price snapshot.",
      +  "properties": {
      +    "name": {
      +      "description": "Retailer or brand display name, as the gateway names it.",
      +      "type": "string"
      +    },
      +    "stations": {
      +      "description": "How many stations it contributes to the snapshot.",
      +      "format": "uint",
      +      "minimum": 0,
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "name",
      +    "stations"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / coverage
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/FuelCoverage"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "What the deployment's price snapshot covers. On a UK route, show\n`coverage.statement` to the user alongside the results: it names\nthe UK retailers covered, and an empty UK result means \"none from\nthese retailers\", never \"no fuel here\". Absent when the gateway is\ntoo old to report coverage."
      +}
  3. Changed5 schema fields changed
    • changedInput schema / $defs / TruckSpec / properties / tunnel_code / description
      Previous value: -"ADR 8.6.4 tunnel restriction code of the load, e.g. \"B\", \"C5000D\",\n\"B/D\", or \"(—)\"/\"none\" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels)."New value: +"ADR 8.6.4 tunnel restriction code of the load, e.g. \"B\", \"C5000D\",\n\"B/D\", or \"(-)\"/\"none\" for explicitly unrestricted. Leave unset if\nunknown: a hazmat load without a code is conservatively treated as\ncode B (allowed only through category-A tunnels)."
    • changedOutput schema / $defs / FuelBaseline / description
      Previous value: -"The cheapest effectively-on-route option in one currency — what the\ndriver pays by just pulling in without a detour; the reference the\nper-result savings are computed against. Only a fresh price is\neligible, so this is `stale: false` by construction."New value: +"The cheapest effectively-on-route option in one currency, what the\ndriver pays by just pulling in without a detour; the reference the\nper-result savings are computed against. Only a fresh price is\neligible, so this is `stale: false` by construction."
    • changedOutput schema / $defs / FuelPriceQuote / properties / stale / description
      Previous value: -"True when the price could not be verified fresher than 24 hours:\nunless BOTH the source's own `updated_at` and the snapshot's fetch\ntime fall inside that window, and always when either is missing.\nTreat it as indicative, not bindable — say \"last seen at X on\n<date>\", never quote it as today's price or as a saving."New value: +"True when the price could not be verified fresher than 24 hours:\nunless BOTH the source's own `updated_at` and the snapshot's fetch\ntime fall inside that window, and always when either is missing.\nTreat it as indicative, not bindable, say \"last seen at X on\n<date>\", never quote it as today's price or as a saving."
    • changedOutput schema / $defs / FuelStationHit / properties / detour_minutes / description
      Previous value: -"Extra travel time of refuelling here, in minutes (rounded to 0.1):\n(origin→station) + (station→destination) − (origin→destination),\nall computed by the routing engine — never a straight-line guess."New value: +"Extra travel time of refuelling here, in minutes (rounded to 0.1):\n(origin→station) + (station→destination) − (origin→destination),\nall computed by the routing engine, never a straight-line guess."
    • changedOutput schema / properties / fuel_attribution / description
      Previous value: -"Attribution string for the fuel-price data sources actually\nreturned — display it with the prices (a licence obligation)."New value: +"Attribution string for the fuel-price data sources actually\nreturned, display it with the prices (a licence obligation)."
  4. Changed5 schema fields changed
    • addedInput schema / $defs / LatLon / anyOf
      Added value: +[
      +  {
      +    "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"
      +  },
      +  {
      +    "description": "GeoJSON position [lon, lat]: longitude FIRST.",
      +    "items": {
      +      "format": "double",
      +      "type": "number"
      +    },
      +    "maxItems": 2,
      +    "minItems": 2,
      +    "type": "array"
      +  }
      +]
    • changedInput schema / $defs / LatLon / description
      Previous value: -"A WGS84 coordinate pair in decimal degrees."New value: +"A WGS84 coordinate in decimal degrees: a {lat, lon} object (preferred), or a GeoJSON [lon, lat] array with LONGITUDE FIRST, the same order as every polygon field on this server."
    • removedInput schema / $defs / LatLon / properties
      Removed value: -{
      -  "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"
      -  }
      -}
    • removedInput schema / $defs / LatLon / required
      Removed value: -[
      -  "lat",
      -  "lon"
      -]
    • removedInput schema / $defs / LatLon / type
      Removed value: -"object"
  5. Changed2 schema fields changed
    • addedOutput schema / properties / say
      Added value: +{
      +  "description": "**Always present.** The whole answer as one short spoken line,\ncomposed by the gateway: the number, the detour, and the honest\nqualifier where one applies. Safe to read to a driver verbatim,\nand safe on an empty result, where it names the cause rather than\nimplying there is no fuel on the road. A stale price's line states\nthe figure and the day it was last seen and claims no saving.",
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "fuel",
      -  "costing",
      -  "route_length_m",
      -  "candidates_considered",
      -  "candidates_costed",
      -  "candidate_cap",
      -  "max_detour_minutes",
      -  "baseline",
      -  "results"
      -]New value: +[
      +  "fuel",
      +  "costing",
      +  "route_length_m",
      +  "candidates_considered",
      +  "candidates_costed",
      +  "candidate_cap",
      +  "max_detour_minutes",
      +  "baseline",
      +  "results",
      +  "say"
      +]
  6. Changed3 schema fields changed
    • changedOutput schema / $defs / FuelBaseline / description
      Previous value: -"The cheapest effectively-on-route option in one currency — what the\ndriver pays by just pulling in without a detour; the reference the\nper-result savings are computed against."New value: +"The cheapest effectively-on-route option in one currency — what the\ndriver pays by just pulling in without a detour; the reference the\nper-result savings are computed against. Only a fresh price is\neligible, so this is `stale: false` by construction."
    • changedOutput schema / $defs / FuelPriceQuote / properties / stale / description
      Previous value: -"True when the price could not be verified fresher than 24 hours —\ntreat it as indicative, not bindable."New value: +"True when the price could not be verified fresher than 24 hours:\nunless BOTH the source's own `updated_at` and the snapshot's fetch\ntime fall inside that window, and always when either is missing.\nTreat it as indicative, not bindable — say \"last seen at X on\n<date>\", never quote it as today's price or as a saving."
    • changedOutput schema / $defs / FuelStationHit / properties / saving_per_litre / description
      Previous value: -"Per-litre saving against the cheapest effectively-on-route station\nin the same currency (negative = dearer than staying on route).\nAbsent when no station sits on the route itself in this currency."New value: +"Per-litre saving against the cheapest effectively-on-route station\nin the same currency (negative = dearer than staying on route).\nAbsent when no FRESH station sits on the route itself in this\ncurrency, and always absent on a stale result: an unverifiable\nprice may state a number but never claim a saving."
  7. First observed

TDQS

A4.5/5.0
Behavior5/5

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 defines `stale` precisely (requires both price updated_at and snapshot fetch time inside 24h), states stale prices rank below fresh, are never the baseline, and carry no saving_per_litre. It also discloses the gateway requirement, the error behaviour when no dataset exists, and the `coverage`/`uk_partial` caveat for empty UK results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the either/or input rule are front-loaded, but the paragraph is very dense and runs long, with the stale/coverage/say clauses packed into one block. Much of it is genuinely load-bearing, yet the density makes it harder to scan than a structured list would be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite a 9-parameter surface, an output schema, and a complex pricing/staleness model, the description covers everything an agent needs: input mode selection, defaults, staleness semantics, empty-result causes, UK coverage caveats, and the recommendation to surface `say` and `fuel_attribution` to the user.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description still adds meaning by explaining that fill_litres produces saving_total = saving_per_litre × fill_litres, that `truck` makes detours respect dimensional/ADR restrictions, and that fuel accepts the named codes. Some of this repeats the schema, so it is not a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('find the cheapest fuel along a route') and immediately differentiates from naive alternatives by promising 'REAL extra travel time... never a straight-line guess'. The sibling cheapest_charging_along_route is implicitly distinguished by the fuel domain and price-feed coverage named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to supply either origin+destination or an existing route's geometry_polyline6 (and the schema notes not both), gives defaults for fuel and max_detour_minutes, and directs the agent to read the `say` field verbatim rather than writing its own summary. It does not explicitly steer between this and cheapest_charging_along_route, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources