Skip to main content
Glama

plan_ev_route

Plan a whole electric-vehicle journey, charge stops included. Give origin and destination (plus optional waypoints) and a vehicle, a published profile ("small_hatch", "saloon", "suv", "van") and/or inline figures (battery_kwh, mass_kg, drag_area_m2, aux_kw, connectors), with start_soc (default 0.9), min_arrival_soc (default 0.1), reserve_soc (default 0.1, the floor the charge must never drop below mid-route), optional connectors and min_kw filters and ambient_temperature_c. Energy comes from a published road-load physics model over the route's own legs; charge times are integrated over the vehicle's charging curve capped by the charge point, NOT energy divided by peak power, which is the single biggest error in naive EV planners. Returns the stops with arrive/depart state of charge, charge time and detour, a per-leg state-of-charge trace, and the journey's driving and charging time. IMPORTANT: when no plan exists, a charger desert, a connector mismatch, a gap wider than the car's range, the answer comes back with feasible: false, a reason and the furthest point on the route the car can actually reach. That is an ANSWER, not an error to retry: report the reason and never describe it as a plan. gradient_data says whether elevation was available: "absent" means consumption was modelled on the flat and under-reads a hilly route. There is no national charge-point registry, so ALWAYS show the returned coverage_note, an infeasible plan means "none from these operators", never "there are no chargers here", and statuses are current only when availability_live is true. Requires the MapMap gateway; answers a clear error when the deployment has no charge-point dataset. Display the returned charging_attribution with the plan.

Input Schema

NameRequiredDescriptionDefault
min_kwNoKeep only charge points with a usable connector rated at least this many kW (e.g. 50 for rapid charging only).
originYesWhere the journey starts.
vehicleNoThe vehicle. Omitted ⇒ the published "saloon" default, and the answer says which vehicle it used.
start_socNoState of charge at the start, 0–1 (default 0.9).
waypointsNoIntermediate points the route must pass through, in order (at most 8). Charge stops are inserted around them.
connectorsNoKeep 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.
destinationYesWhere it ends.
reserve_socNoThe floor the state of charge must never fall below mid-route (default 0.1). Distinct from the arrival figure.
min_arrival_socNoLowest acceptable state of charge on arrival (default 0.1).
max_detour_minutesNoHow far off the route a charge point may sit, as a detour in minutes (default 15, at most 120).
ambient_temperature_cNoAmbient temperature in °C. Derates traction energy from a published study; cabin heating belongs in the vehicle's `aux_kw`.

Output Schema

NameRequiredDescriptionDefault
legsYesThe driving legs, in order.
stopsYesThe charge stops, in visit order. Always empty when `feasible` is false: a journey that cannot be completed has no stop list.
reasonNoThe same cause in plain language, for the user.
summaryYesThe plan at a glance.
vehicleNoThe vehicle the plan was computed for.
feasibleYes**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_traceYesState of charge at every point of the journey.
reason_codeNoMachine 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_noteYes**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_dataYes"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_sourceNo"default" when a published profile supplied the figures, "inline" when the caller did.
route_distance_mNoDistance of the planned route, metres.
route_duration_sNoDriving time of the planned route, seconds.
availability_liveYesWhether 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_polyline6NoThe planned journey's geometry as an encoded polyline6, through the charge stops.
charging_attributionNoAttribution string for the charge-point operators actually used, display it with the plan (a licence obligation).
furthest_reachable_latNoLatitude of that furthest reachable point.
furthest_reachable_lonNoLongitude of that furthest reachable point.
furthest_reachable_positionNoHow far along the route the vehicle can get unaided, 0.0–1.0, when no plan exists.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed8 schema fields changed
    • changedInput schema / $defs / EvVehicleSpec / properties / aux_kw / description
      Previous value: -"Auxiliary load in kW — lights, electronics, cabin conditioning.\nWinter heating is several times the mild-weather default."New value: +"Auxiliary load in kW, lights, electronics, cabin conditioning.\nWinter heating is several times the mild-weather default."
    • changedOutput schema / $defs / EvPlanStop / properties / available_now / description
      Previous value: -"Whether a bay is free right now. Present only where a live\navailability feed backs the claim — absent means unknown, never\n\"occupied\"."New value: +"Whether a bay is free right now. Present only where a live\navailability feed backs the claim, absent means unknown, never\n\"occupied\"."
    • changedOutput schema / $defs / EvPlanStop / properties / charge_s / description
      Previous value: -"Time plugged in, seconds — integrated over the vehicle's charging\ncurve capped by the charge point, not energy ÷ peak power."New value: +"Time plugged in, seconds, integrated over the vehicle's charging\ncurve capped by the charge point, not energy ÷ peak power."
    • changedOutput schema / $defs / EvPlanStop / properties / charger_kw / description
      Previous value: -"That connector's rated power, kW — what the charge time was\ncomputed against."New value: +"That connector's rated power, kW, what the charge time was\ncomputed against."
    • changedOutput schema / $defs / EvPlanSummary / properties / stops / description
      Previous value: -"How many charge stops the plan contains. Zero on a journey the car\nmakes on its own — and zero on an infeasible one."New value: +"How many charge stops the plan contains. Zero on a journey the car\nmakes on its own, and zero on an infeasible one."
    • changedOutput schema / $defs / EvPlanSummary / properties / total_duration_s / description
      Previous value: -"Driving plus charging, seconds — the number a user cares about."New value: +"Driving plus charging, seconds, the number a user cares about."
    • changedOutput schema / properties / charging_attribution / description
      Previous value: -"Attribution string for the charge-point operators actually used —\ndisplay it with the plan (a licence obligation)."New value: +"Attribution string for the charge-point operators actually used,\ndisplay it with the plan (a licence obligation)."
    • changedOutput schema / properties / feasible / description
      Previous value: -"**Whether the journey is possible at all.** False means no plan\nexists — a charger desert, a connector mismatch, or a gap wider than\nthe car's range. Report the `reason` and the furthest reachable\npoint; never describe an infeasible answer as a plan."New value: +"**Whether the journey is possible at all.** False means no plan\nexists, a charger desert, a connector mismatch, or a gap wider than\nthe car's range. Report the `reason` and the furthest reachable\npoint; never describe an infeasible answer as a plan."
  2. 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"
  3. Added

TDQS

A4.6/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: it discloses that infeasible outcomes are answers (`feasible: false`, `reason`, furthest reachable point) not retryable errors, warns about `gradient_data` = absent, mandates surfacing `coverage_note` and `charging_attribution`, and notes `availability_live` for status currency plus the MapMap gateway dependency and no-dataset error. This is exactly the operational context an agent needs.

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

Conciseness4/5

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

Front-loaded with the purpose and required inputs, then tiers down into modelling detail and output caveats. It is long and occasionally dense, but nearly every sentence carries distinct behavioural information rather than padding.

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 an 11-parameter schema and a nested vehicle object, the description covers what the agent must know that structured fields cannot express: infeasibility semantics, coverage limitations, elevation caveat, and the required display of attribution. With an output schema present, it rightly avoids explaining return values and focuses on interpretation.

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 the baseline is 3, but the description adds genuine meaning beyond it: it clarifies that `reserve_soc` is the mid-route floor distinct from arrival SOC, that `connectors` only narrows the vehicle's own set, and that `profile` acts as a base overridden by inline figures. The numeric defaults it repeats are already in the schema, so it does not reach the top band.

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?

The first sentence states a specific verb and resource ("Plan a whole electric-vehicle journey, charge stops included") and the follow-up distinguishes it from plain routing by emphasizing charge-stop insertion and physics-based energy modelling. An agent can tell this apart from `route`, `optimise_routes` and `cheapest_charging_along_route` without opening any schema.

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?

The description gives clear context for invocation (give origin/destination plus a vehicle, defaults for the SOC knobs) and strong when-not guidance around infeasible results. It stops short of explicitly naming sibling alternatives such as `cheapest_charging_along_route` or `route`, so the routing is implied through scenario rather than stated.

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