Skip to main content
Glama

plot_trip

Creates a road trip on Stopful, or updates one plotted earlier, and returns an interactive map of it — adding, removing, reordering or renaming stops, changing nights, dates or party size, and redrawing the route. Renders a multi-stop driving route as an interactive map and returns a link to it, plus an inline map in clients that support one. Takes a list of stops in driving order, each with a place name, optional decimal lat/lon and number of nights; a stop without coordinates is geocoded from its name, and coordinates that fall far from where the name resolves are reported back in the result. Accepts an optional trip name, start date, party size, and a day-by-day itinerary that becomes a day view over the map. The map shows per-leg drive times and distances and an estimate of what the trip will cost before anything is booked, and is editable: the traveller can drag a pin to move a stop or drag the route to add one, and their changes are saved to the trip. Covers road trips and other multi-stop routes; a single destination or a route with no stops to draw has nothing to render. The result contains the map link, the trip as structured data, and the trip's id (see the id parameter for updating an existing trip).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoId of a trip returned by an earlier call. SEND IT whenever this call is about a trip already plotted in this conversation — showing one of its days, fixing a stop, changing the route. WITHOUT `id` a separate new trip is created and the traveller is left with a pile of near-duplicate maps instead of one they can follow. With it the map link stays the same and their own edits survive. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days`; there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive. Stops: a re-sent stop keeps the position they dragged it to, stops or waypoints they added on the map but absent from `stops` are kept, and a stop that was there before and is now omitted is removed. Activities: a re-sent one keeps its identity and the place, price and booking it carries on the map, which this tool does not report and so cannot be sent back; an activity the traveller added themselves is kept whether or not it appears here; one this tool showed earlier and now omitted is removed. Without an `id` a separate new trip is created and none of that carries over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved.
daysNoThe day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving; the activities also become the trip's itinerary in the full Stopful planner, where the traveller can edit them. Send it when planning a trip, or when rewriting the itinerary — the day titles replace the saved ones wholesale, there are no partial day updates, while the activities under them are reconciled with what is saved rather than overwritten (see `id`). On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way.
nameNoOptional trip name (e.g. 'Lisbon → Pyrenees'). Defaults to first → last stop.
stopsYesThe route in driving order, 1 to 40 entries (the first is the origin). Required for a normal call — the only call that omits it is `id` on its own, which re-reads a saved trip unchanged. Each entry needs `name`; every other field is optional. A stop is a place the traveller sleeps, or a place on the road between two such places. An outing made from a base — a waterpark, a market, a cave, a viewpoint visited from the hotel and returned from the same day — is NOT a stop: put it under `days` as that day's activity, and do not repeat the base between outings. Outings sent as stops are moved under their day.
guestsNoOptional party size.
focusDayNoOptional. Open the map on this day of the itinerary, 1 = the first day. The map shows ONE DAY at a time: the chosen day's stops, activities and driving, with the rest of the route greyed. Use it WITH `id` to answer 'show me day 3' about a trip already plotted — that gives the traveller one map they can page through instead of a new map per day. Omitted, the map opens on the day the trip is actually on (day 1 before it starts), and the traveller can switch day or ask for the whole route from the map itself.
startDateNoOptional trip start as ISO yyyy-mm-dd.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoThe trip's id. Pass it back as the `id` argument to apply a later change to this same trip.
urlYesLink that opens this trip on the map at stopful.com.
daysNoThe day-by-day itinerary. Activities may include ones the traveller added in the planner rather than through this tool.
tripYesThe trip as rendered, after geocoding and (on a continuation) merging the traveller's own map edits.
assumedNoStops placed from their name alone because no coordinates were given — approximate pins.
focusDayNoSet when the call asked for one day: the map opens on that day of the itinerary, 1 = the first day.
notFoundNoStops that were requested but could not be placed, so they are absent from the map and the route.
warningsNoStops whose supplied coordinates are far from where their name resolves, with the distance and the resolved position.
unchangedNoTrue when the call only read the saved trip and changed nothing — an `id` sent with no `stops`.
keptByTravellerNoStops left where the traveller placed them on the map, so the coordinates supplied in this call were not applied.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / focusDay / description
      Previous value: -"Optional. Open the map on this day of the itinerary, 1 = the first day. The map has a day view: this selects that day, greys the rest of the route and shows only that day's stops and activities. Use it WITH `id` to answer 'show me day 3' about a trip already plotted — that gives the traveller one map they can page through instead of a new map per day. Omit it for the whole trip."New value: +"Optional. Open the map on this day of the itinerary, 1 = the first day. The map shows ONE DAY at a time: the chosen day's stops, activities and driving, with the rest of the route greyed. Use it WITH `id` to answer 'show me day 3' about a trip already plotted — that gives the traveller one map they can page through instead of a new map per day. Omitted, the map opens on the day the trip is actually on (day 1 before it starts), and the traveller can switch day or ask for the whole route from the map itself."
  2. Changed3 schema fields changed
    • changedInput schema / properties / days / items / properties / items / items / properties / title / description
      Previous value: -"The place or activity, e.g. 'Altstadt Salzburg'."New value: +"The place or activity, e.g. 'Altstadt Salzburg'. Every outing from a base belongs here — this is the only place it should appear, never also in `stops`."
    • changedInput schema / properties / stops / description
      Previous value: -"The route in driving order, 1 to 40 entries (the first is the origin). Required for a normal call — the only call that omits it is `id` on its own, which re-reads a saved trip unchanged. Each entry needs `name`; every other field is optional."New value: +"The route in driving order, 1 to 40 entries (the first is the origin). Required for a normal call — the only call that omits it is `id` on its own, which re-reads a saved trip unchanged. Each entry needs `name`; every other field is optional. A stop is a place the traveller sleeps, or a place on the road between two such places. An outing made from a base — a waterpark, a market, a cave, a viewpoint visited from the hotel and returned from the same day — is NOT a stop: put it under `days` as that day's activity, and do not repeat the base between outings. Outings sent as stops are moved under their day."
    • changedInput schema / properties / stops / items / properties / nights / description
      Previous value: -"Optional. Nights at this stop: 0 = pass-through / day stop, 1 or more = overnight. Defaults to 1 when absent."New value: +"Optional. Nights at this stop: 0 = a pass-through on the drive (somewhere the route goes through without staying), 1 or more = overnight. Defaults to 1 when absent. A place visited from a base and returned from is an activity under `days`, not a 0-night stop."
  3. Changed3 schema fields changed
    • addedInput schema / properties / focusDay
      Added value: +{
      +  "description": "Optional. Open the map on this day of the itinerary, 1 = the first day. The map has a day view: this selects that day, greys the rest of the route and shows only that day's stops and activities. Use it WITH `id` to answer 'show me day 3' about a trip already plotted — that gives the traveller one map they can page through instead of a new map per day. Omit it for the whole trip.",
      +  "type": "integer"
      +}
    • changedInput schema / properties / id / description
      Previous value: -"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days`; there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive. Stops: a re-sent stop keeps the position they dragged it to, stops or waypoints they added on the map but absent from `stops` are kept, and a stop that was there before and is now omitted is removed. Activities: a re-sent one keeps its identity and the place, price and booking it carries on the map, which this tool does not report and so cannot be sent back; an activity the traveller added themselves is kept whether or not it appears here; one this tool showed earlier and now omitted is removed. Without an `id` a separate new trip is created and none of that carries over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved."New value: +"Id of a trip returned by an earlier call. SEND IT whenever this call is about a trip already plotted in this conversation — showing one of its days, fixing a stop, changing the route. WITHOUT `id` a separate new trip is created and the traveller is left with a pile of near-duplicate maps instead of one they can follow. With it the map link stays the same and their own edits survive. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days`; there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive. Stops: a re-sent stop keeps the position they dragged it to, stops or waypoints they added on the map but absent from `stops` are kept, and a stop that was there before and is now omitted is removed. Activities: a re-sent one keeps its identity and the place, price and booking it carries on the map, which this tool does not report and so cannot be sent back; an activity the traveller added themselves is kept whether or not it appears here; one this tool showed earlier and now omitted is removed. Without an `id` a separate new trip is created and none of that carries over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved."
    • addedOutput schema / properties / focusDay
      Added value: +{
      +  "description": "Set when the call asked for one day: the map opens on that day of the itinerary, 1 = the first day.",
      +  "type": "integer"
      +}
  4. Changed2 schema fields changed
    • changedInput schema / properties / days / description
      Previous value: -"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving; the activities also become the trip's itinerary in the full Stopful planner, where the traveller can edit them. Send it when planning a trip, or when deliberately rewriting the itinerary — it REPLACES the saved one wholesale, there are no partial day updates. On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way."New value: +"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving; the activities also become the trip's itinerary in the full Stopful planner, where the traveller can edit them. Send it when planning a trip, or when rewriting the itinerary — the day titles replace the saved ones wholesale, there are no partial day updates, while the activities under them are reconciled with what is saved rather than overwritten (see `id`). On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way."
    • changedInput schema / properties / id / description
      Previous value: -"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days` — the call replaces the itinerary rather than merging into it, and there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive: a re-sent stop keeps the position they dragged it to, and stops or waypoints they added on the map but absent from `stops` are kept, while a stop that was there before and is now omitted is removed. Without an `id` a separate new trip is created and none of those map edits carry over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved."New value: +"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days`; there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive. Stops: a re-sent stop keeps the position they dragged it to, stops or waypoints they added on the map but absent from `stops` are kept, and a stop that was there before and is now omitted is removed. Activities: a re-sent one keeps its identity and the place, price and booking it carries on the map, which this tool does not report and so cannot be sent back; an activity the traveller added themselves is kept whether or not it appears here; one this tool showed earlier and now omitted is removed. Without an `id` a separate new trip is created and none of that carries over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved."
  5. Changed2 schema fields changed
    • addedInput schema / properties / days / items / properties / items / items / properties / lat
      Added value: +{
      +  "description": "Optional decimal latitude of the activity. Supplying lat and lon puts a numbered pin on the map for it; without them the activity is still listed under its day, just not placed. Send them for a real place, and leave them out for something that isn't one ('Pack a picnic', 'Drive south').",
      +  "type": "number"
      +}
    • addedInput schema / properties / days / items / properties / items / items / properties / lon
      Added value: +{
      +  "description": "Optional decimal longitude of the activity.",
      +  "type": "number"
      +}
  6. Changed2 schema fields changed
    • changedInput schema / properties / days / description
      Previous value: -"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Send it when planning a trip, or when deliberately rewriting the itinerary — it REPLACES the saved one wholesale, there are no partial day updates. On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way."New value: +"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving; the activities also become the trip's itinerary in the full Stopful planner, where the traveller can edit them. Send it when planning a trip, or when deliberately rewriting the itinerary — it REPLACES the saved one wholesale, there are no partial day updates. On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way."
    • changedOutput schema / properties / days / description
      Previous value: -"The day-by-day itinerary, when one was supplied."New value: +"The day-by-day itinerary. Activities may include ones the traveller added in the planner rather than through this tool."
  7. Changed1 schema field changed
    • removedOutput schema / properties / editToken
      Removed value: -{
      -  "description": "Capability token the map widget uses to save the traveller's own changes. It is not an argument of this tool and never needs sending back — updating a trip needs only its `id`.",
      -  "type": "string"
      -}
  8. Changed2 schema fields changed
    • changedInput schema / properties / stops / items / properties / lat / description
      Previous value: -"Optional decimal latitude. When omitted, the stop is geocoded from its name, which is slower and less exact."New value: +"Optional decimal latitude. On a NEW stop, supplying it is faster and more exact than geocoding the name. On a stop that already exists (one you are sending an `id` for), leave lat/lon out unless you mean to move it — the stop keeps wherever it currently sits, including anywhere the traveller has dragged it. Coordinates sent for an existing stop are an instruction to move it there."
    • changedInput schema / properties / stops / items / properties / lon / description
      Previous value: -"Optional decimal longitude. When omitted, the stop is geocoded from its name, which is slower and less exact."New value: +"Optional decimal longitude. Same as lat: give it for a new stop, and leave it out for an existing one unless the point of the call is to move that stop."
  9. Changed2 schema fields changed
    • changedInput schema / properties / days / description
      Previous value: -"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Expected on any call that sends `stops`, and it replaces the itinerary wholesale — there are no partial day updates. When it is omitted on a call that updates an existing trip, the saved itinerary is kept as it was; when there is none to keep, the map falls back to bare day titles worked out from the route, with no activities."New value: +"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Send it when planning a trip, or when deliberately rewriting the itinerary — it REPLACES the saved one wholesale, there are no partial day updates. On a call that only changes the route of an existing trip, leaving `days` out keeps the saved itinerary untouched, which is usually what is wanted; the result echoes whatever is saved either way."
    • changedInput schema / required
      Previous value: -[
      -  "stops",
      -  "days"
      -]New value: +[
      +  "stops"
      +]
  10. Changed2 schema fields changed
    • addedInput schema / properties / stops / items / properties / id
      Added value: +{
      +  "description": "Optional. The id this stop was given in an earlier result. Echoing it back identifies that exact stop even if you rename it, so the traveller's placement and edits follow the right stop. Leave it out for a stop you are adding.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / trip / properties / stops / items / properties / id
      Added value: +{
      +  "description": "Stable id for this stop. Send it back as the stop's `id` when updating the trip, so this stop is recognised even under a different name.",
      +  "type": "string"
      +}
  11. Changed3 schema fields changed
    • removedInput schema / anyOf
      Removed value: -[
      -  {
      -    "required": [
      -      "stops",
      -      "days"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "id"
      -    ]
      -  }
      -]
    • changedInput schema / properties / id / description
      Previous value: -"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. With it, that same trip is updated rather than a new one created: the map link stays the same, and edits the traveller made on the map survive — a re-sent stop keeps the position they dragged it to (instead of the coordinates given here), and stops or waypoints they added on the map but absent from `stops` are kept, while a stop previously present and now omitted is removed. Without it, a separate new trip is created and any such map edits are not carried over. Supplied alone, with no `stops`, nothing is modified — the trip comes back exactly as saved; changing a trip means sending `id` together with the full updated stop list."New value: +"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. To change an existing trip, send its `id` together with the COMPLETE new `stops` and `days` — the call replaces the itinerary rather than merging into it, and there are no partial updates. The map link then stays the same, and edits the traveller made on the map survive: a re-sent stop keeps the position they dragged it to, and stops or waypoints they added on the map but absent from `stops` are kept, while a stop that was there before and is now omitted is removed. Without an `id` a separate new trip is created and none of those map edits carry over. Sending `id` with no `stops` is also accepted and changes nothing — it returns the trip exactly as saved."
    • addedInput schema / required
      Added value: +[
      +  "stops",
      +  "days"
      +]
  12. Changed4 schema fields changed
    • changedInput schema / properties / days / description
      Previous value: -"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Expected on any call that sends `stops`; when it is missing the map falls back to bare day titles worked out from the route, with no activities."New value: +"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Expected on any call that sends `stops`, and it replaces the itinerary wholesale — there are no partial day updates. When it is omitted on a call that updates an existing trip, the saved itinerary is kept as it was; when there is none to keep, the map falls back to bare day titles worked out from the route, with no activities."
    • changedOutput schema / properties / editToken / description
      Previous value: -"Capability token that permits editing this trip; used by the map widget to save the traveller's changes."New value: +"Capability token the map widget uses to save the traveller's own changes. It is not an argument of this tool and never needs sending back — updating a trip needs only its `id`."
    • addedOutput schema / properties / notFound
      Added value: +{
      +  "description": "Stops that were requested but could not be placed, so they are absent from the map and the route.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / trip / properties / id
      Added value: +{
      +  "description": "The trip's id — the same value as the top-level `id`.",
      +  "type": "string"
      +}
  13. Changed11 schema fields changed
    • addedInput schema / anyOf
      Added value: +[
      +  {
      +    "required": [
      +      "stops",
      +      "days"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "id"
      +    ]
      +  }
      +]
    • changedInput schema / properties / days / description
      Previous value: -"Optional day-by-day itinerary, one entry per day of the trip in order. When present it renders as a tappable day view over the map; when absent the map shows the route alone."New value: +"The day-by-day itinerary: one entry per calendar day of the trip, in order, each with a title and the day's activities. It renders as a tappable day view over the map, and selecting a day highlights that day's driving. Expected on any call that sends `stops`; when it is missing the map falls back to bare day titles worked out from the route, with no activities."
    • addedInput schema / properties / guests / properties / children
      Added value: +{
      +  "description": "How many children, for when their ages aren't known. Ignored when `childrenAges` is given.",
      +  "type": "integer"
      +}
    • changedInput schema / properties / guests / properties / childrenAges / description
      Previous value: -"Age of each child (drives hotel/ticket pricing)."New value: +"Age of each child, e.g. [7, 11]. Preferred over `children`, because hotel and ticket pricing depends on the ages."
    • changedInput schema / properties / id / description
      Previous value: -"Id of a trip returned by an earlier call, identifying which trip this call applies to. With it, that same trip is updated rather than a new one created: the map link stays the same, and edits the traveller made on the map survive — a re-sent stop keeps the position they dragged it to (instead of the coordinates given here), and stops or waypoints they added on the map but absent from `stops` are kept, while a stop previously present and now omitted is removed. Without it, a separate new trip is created and any such map edits are not carried over. Supplied alone, with no `stops`, it returns the trip's current state."New value: +"Optional. Id of a trip returned by an earlier call, identifying which trip this call applies to. With it, that same trip is updated rather than a new one created: the map link stays the same, and edits the traveller made on the map survive — a re-sent stop keeps the position they dragged it to (instead of the coordinates given here), and stops or waypoints they added on the map but absent from `stops` are kept, while a stop previously present and now omitted is removed. Without it, a separate new trip is created and any such map edits are not carried over. Supplied alone, with no `stops`, nothing is modified — the trip comes back exactly as saved; changing a trip means sending `id` together with the full updated stop list."
    • changedInput schema / properties / stops / description
      Previous value: -"The route in driving order (first stop = origin). 1–40 stops."New value: +"The route in driving order, 1 to 40 entries (the first is the origin). Required for a normal call — the only call that omits it is `id` on its own, which re-reads a saved trip unchanged. Each entry needs `name`; every other field is optional."
    • changedInput schema / properties / stops / items / properties / arriveBy / description
      Previous value: -"How the traveller reaches this stop from the previous one. Defaults to a road leg (drive) when absent; 'flight' marks a real flight leg between two stops."New value: +"Optional. How the traveller reaches this stop from the previous one. Defaults to a road leg (drive) when absent; 'flight' marks a real flight leg between two stops."
    • changedInput schema / properties / stops / items / properties / lat / description
      Previous value: -"Decimal latitude. When omitted, the stop is geocoded from its name, which is slower and less exact."New value: +"Optional decimal latitude. When omitted, the stop is geocoded from its name, which is slower and less exact."
    • changedInput schema / properties / stops / items / properties / lon / description
      Previous value: -"Decimal longitude. When omitted, the stop is geocoded from its name, which is slower and less exact."New value: +"Optional decimal longitude. When omitted, the stop is geocoded from its name, which is slower and less exact."
    • changedInput schema / properties / stops / items / properties / nights / description
      Previous value: -"Nights at this stop: 0 = pass-through / day stop, 1–3 = overnight."New value: +"Optional. Nights at this stop: 0 = pass-through / day stop, 1 or more = overnight. Defaults to 1 when absent."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "assumed": {
      +      "description": "Stops placed from their name alone because no coordinates were given — approximate pins.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "days": {
      +      "description": "The day-by-day itinerary, when one was supplied.",
      +      "items": {
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "editToken": {
      +      "description": "Capability token that permits editing this trip; used by the map widget to save the traveller's changes.",
      +      "type": "string"
      +    },
      +    "id": {
      +      "description": "The trip's id. Pass it back as the `id` argument to apply a later change to this same trip.",
      +      "type": "string"
      +    },
      +    "keptByTraveller": {
      +      "description": "Stops left where the traveller placed them on the map, so the coordinates supplied in this call were not applied.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "trip": {
      +      "description": "The trip as rendered, after geocoding and (on a continuation) merging the traveller's own map edits.",
      +      "properties": {
      +        "guests": {
      +          "properties": {
      +            "adults": {
      +              "type": "integer"
      +            },
      +            "childrenAges": {
      +              "items": {
      +                "type": "integer"
      +              },
      +              "type": "array"
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "maxKmPerDay": {
      +          "type": "number"
      +        },
      +        "name": {
      +          "type": "string"
      +        },
      +        "startDate": {
      +          "description": "ISO yyyy-mm-dd, when one was given.",
      +          "type": "string"
      +        },
      +        "stops": {
      +          "description": "Final stops in driving order, each with resolved coordinates.",
      +          "items": {
      +            "properties": {
      +              "arriveBy": {
      +                "type": "string"
      +              },
      +              "lat": {
      +                "type": "number"
      +              },
      +              "lon": {
      +                "type": "number"
      +              },
      +              "name": {
      +                "type": "string"
      +              },
      +              "nights": {
      +                "type": "integer"
      +              },
      +              "sub": {
      +                "type": "string"
      +              },
      +              "waypoint": {
      +                "description": "True for a shaping point the traveller dragged out of the route line, not a destination.",
      +                "type": "boolean"
      +              }
      +            },
      +            "required": [
      +              "name",
      +              "lat",
      +              "lon"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "stops"
      +      ],
      +      "type": "object"
      +    },
      +    "unchanged": {
      +      "description": "True when the call only read the saved trip and changed nothing — an `id` sent with no `stops`.",
      +      "type": "boolean"
      +    },
      +    "url": {
      +      "description": "Link that opens this trip on the map at stopful.com.",
      +      "type": "string"
      +    },
      +    "warnings": {
      +      "description": "Stops whose supplied coordinates are far from where their name resolves, with the distance and the resolved position.",
      +      "items": {
      +        "properties": {
      +          "km": {
      +            "type": "number"
      +          },
      +          "lat": {
      +            "type": "number"
      +          },
      +          "lon": {
      +            "type": "number"
      +          },
      +          "name": {
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "url",
      +    "trip"
      +  ],
      +  "type": "object"
      +}
  14. Changed6 schema fields changed
    • changedInput schema / properties / days / description
      Previous value: -"OPTIONAL day-by-day itinerary YOU have planned — renders as a tappable day view over the map. One entry per day of the trip, in order. Omit it if you only have the stops."New value: +"Optional day-by-day itinerary, one entry per day of the trip in order. When present it renders as a tappable day view over the map; when absent the map shows the route alone."
    • changedInput schema / properties / id / description
      Previous value: -"Optional — the id of a trip you plotted earlier (from that result), to CONTINUE it: pass `id` alone to reload the traveller's current version (incl. any map edits), or `id` with an updated `stops` list to change it in place. Use it when the user says 'use the current version' / 'keep editing this trip'."New value: +"Id of a trip returned by an earlier call, identifying which trip this call applies to. With it, that same trip is updated rather than a new one created: the map link stays the same, and edits the traveller made on the map survive — a re-sent stop keeps the position they dragged it to (instead of the coordinates given here), and stops or waypoints they added on the map but absent from `stops` are kept, while a stop previously present and now omitted is removed. Without it, a separate new trip is created and any such map edits are not carried over. Supplied alone, with no `stops`, it returns the trip's current state."
    • changedInput schema / properties / stops / items / properties / arriveBy / description
      Previous value: -"How the traveller reaches THIS stop from the previous one. Omit for a normal road leg (drive). Use 'flight' only for a real flight leg (fly into a nearby airport stop, then a separate onward leg)."New value: +"How the traveller reaches this stop from the previous one. Defaults to a road leg (drive) when absent; 'flight' marks a real flight leg between two stops."
    • changedInput schema / properties / stops / items / properties / lat / description
      Previous value: -"Decimal latitude. Strongly preferred — include it whenever you know it."New value: +"Decimal latitude. When omitted, the stop is geocoded from its name, which is slower and less exact."
    • changedInput schema / properties / stops / items / properties / lon / description
      Previous value: -"Decimal longitude. Strongly preferred — include it whenever you know it."New value: +"Decimal longitude. When omitted, the stop is geocoded from its name, which is slower and less exact."
    • changedInput schema / properties / stops / items / properties / name / description
      Previous value: -"Real, searchable place name — a town, city or famous landmark (e.g. 'Sirmione', 'Colosseum'). Avoid vague spots."New value: +"Real, searchable place name — a town, city or famous landmark (e.g. 'Sirmione', 'Colosseum'). A vague or descriptive phrase may fail to geocode."
  15. Changed2 schema fields changed
    • addedInput schema / properties / id
      Added value: +{
      +  "description": "Optional — the id of a trip you plotted earlier (from that result), to CONTINUE it: pass `id` alone to reload the traveller's current version (incl. any map edits), or `id` with an updated `stops` list to change it in place. Use it when the user says 'use the current version' / 'keep editing this trip'.",
      +  "type": "string"
      +}
    • removedInput schema / required
      Removed value: -[
      -  "stops"
      -]
  16. Changed1 schema field changed
    • addedInput schema / properties / days
      Added value: +{
      +  "description": "OPTIONAL day-by-day itinerary YOU have planned — renders as a tappable day view over the map. One entry per day of the trip, in order. Omit it if you only have the stops.",
      +  "items": {
      +    "properties": {
      +      "items": {
      +        "description": "The day's plan, in order.",
      +        "items": {
      +          "properties": {
      +            "note": {
      +              "description": "Optional one-line detail.",
      +              "type": "string"
      +            },
      +            "time": {
      +              "description": "Optional time or part of day, e.g. '9:00 AM' or 'Morning'.",
      +              "type": "string"
      +            },
      +            "title": {
      +              "description": "The place or activity, e.g. 'Altstadt Salzburg'.",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "title"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "summary": {
      +        "description": "Optional one-line what-to-expect for the day.",
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "Short day title, e.g. 'Over the Alps to Innsbruck'.",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  17. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses several non-obvious behaviors beyond the annotations: geocoding of stops without coordinates, reporting of coordinate/name mismatches, the editable map with drag-to-move and drag-to-add, per-leg drive times/distances and cost estimates, and the reconciliation semantics for stops and activities when an `id` is sent. It also explains that outings sent as stops are moved under their day. This is rich behavioral context that the annotations (readOnlyHint=false, openWorldHint=true) do not provide.

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?

The description is long, but it earns its length by covering complex create/update semantics, geocoding behavior, map editing, and reconciliation rules. It is front-loaded with the core purpose and output, then expands into parameter-specific guidance. A small deduction because the opening paragraph packs many clauses into a single long sentence, and some redundancy exists between the main description and the `id` parameter description.

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?

Given the tool's complexity (7 parameters, nested objects, create/update duality, reconciliation semantics, output schema present), the description is remarkably complete. It covers what the tool does, when to use it, how parameters interact, what the result contains, and edge cases (no stops, id-only call, day-only updates). The output schema exists, so return values need not be spelled out in the description. Nothing an agent needs to call this correctly is missing.

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

Parameters5/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 substantial meaning beyond the schema. It explains the driving-order semantics of `stops`, the distinction between stops and day activities, the meaning of `nights` (0 = pass-through), the behavior of `id` for updates, the reconciliation rules for days/activities, and the `focusDay` use case. This goes far beyond the schema's field-level descriptions and materially helps an agent construct correct calls.

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 description opens with a specific verb and resource ('Creates a road trip on Stopful, or updates one plotted earlier') and immediately distinguishes the tool's dual create/update role. It names the concrete behaviors (adding/removing/reordering stops, changing nights/dates/party size, redrawing the route) and the output (interactive map link), so an agent knows exactly what this tool does and what it produces.

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

Usage Guidelines5/5

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

The description gives explicit when-to-use guidance: it covers road trips and multi-stop routes, and states that a single destination or a route with no stops has nothing to render. The `id` parameter description goes further, explaining when to send it (updating an existing trip) versus when to omit it (creating a new one), and warns against leaving the traveller with near-duplicate maps. This is strong usage guidance embedded in the description.

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