Skip to content

fix: directions_tool geojson always returns coordinates, any trip length - #255

Open
mattpodwysocki wants to merge 3 commits into
mainfrom
feat/directions-geometry-design
Open

mattpodwysocki wants to merge 3 commits into
mainfrom
feat/directions-geometry-design

Conversation

@mattpodwysocki

@mattpodwysocki mattpodwysocki commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Someone building an app with the MCP server couldn't get a drawable route for a long trip (London to a point in Scotland).

Cause: geometries="geojson" always asked the Directions API for overview=full, every vertex of every road. Fine for a short trip, but a long one is tens of thousands of coordinate pairs, past the tool's 50 KB response limit. Past that limit the tool returns a summary and a ref instead of the geometry, so an agent that asked for coordinates got a different response shape depending on trip length, with no way to know in advance.

Fix: a new optional overview input ("full" or "simplified"):

  • Defaults to "simplified" when geometries="geojson". Live, London to Edinburgh (about 420 miles) goes from 10,057 coordinate pairs (about 700 KB) to 46 (about 4.7 KB), and the line still draws accurately.
  • Defaults to "full" when geometries="none", as before, since no geometry comes back either way.
  • overview="full" stays available as an explicit opt-in. On a long trip it still goes past the limit and returns the summary plus a mapbox://response/ ref (fix: large directions/isochrone responses return a short ref that works on the hosted server #257), now a deliberate choice instead of a surprise.
  • Same overview parameter optimization_tool already has, also defaulting to "simplified".

Tradeoff: the Directions API rejects the congestion annotation unless overview=full (422: Overview option must be full for congestion, checked live). So congestion_information only comes back when the effective overview is "full". distance and speed annotations work at any level. Along the way: the tool used to report an all-zero congestion breakdown when congestion wasn't requested, which reads as "no traffic" rather than "not checked". It's now left out instead.

Unaffected: render_map_tool's map fetches its own full-detail route in the browser, whatever directions_tool returned.

Updated after #257, #276 and #296 merged

Testing

  • New tests in buildDirectionsRequestUrl.test.ts, cleanResponseData.test.ts, DirectionsTool.test.ts and directionsRef.test.ts: short and long route fixtures, the overview defaults, congestion only with full overview, and the ref asking for full geometry.
  • Typecheck clean, build OK, 97 files / 1092 tests pass, lint 0 errors. CI green.
  • Live against the real Directions API and the built server (before the main merge): long route with the geojson default came back at 4.9 KB with 46 coordinates and no fallback; a short route at 2 KB with the same shape; a long route with geometries="none" still had congestion; explicit overview="full" on a long route fell back as documented.

🤖 Generated with Claude Code

An agent asking for raw coordinates (geometries="geojson") got them
directly in the response for a short trip, but for a long one (reported:
London to a point in Scotland) the response exceeded 50KB and the tool
silently swapped to a completely different contract -- geometry and legs
stripped out, replaced by a mapbox://temp/... resource URI that isn't
even a fetchable HTTP URL. There was no way for a caller to know in
advance which contract it would get, since the split was driven by trip
length rather than anything the caller controlled.

Root cause: the tool always requested overview=full (maximum-precision
geometry) regardless of trip length. New optional `overview` input
("full" | "simplified") now defaults to "simplified" whenever
geometries="geojson" (matching the parameter optimization_tool already
exposes, and already defaults to). Confirmed live against the real
Directions API: a real London->Edinburgh route (~420 miles) drops from
10,057 coordinate pairs / ~700KB down to 46 pairs / ~4.7KB under
simplified overview -- comfortably inside the response limit, and still a
fully accurate, drawable line. overview="full" stays available as an
explicit opt-in for callers who need maximum precision, accepting the
same large-response fallback as before.

Tradeoff: the Directions API rejects the congestion annotation unless
overview=full (422, confirmed live) -- distance/speed annotations have no
such restriction. congestion_information is now correctly omitted (not
reported as a misleading all-zero breakdown, which the code did
previously whenever congestion was unavailable for any reason) when it
wasn't requested. render_map_tool's live map preview is unaffected either
way, since it already always fetches its own full-detail geometry
client-side, independent of directions_tool's own response.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mattpodwysocki
mattpodwysocki force-pushed the feat/directions-geometry-design branch from 69f6e03 to 5b60e42 Compare October 1, 2026 14:16
…try-design

# Conflicts:
#	src/tools/directions-tool/DirectionsTool.input.schema.ts
#	src/tools/directions-tool/DirectionsTool.ts
'Use geometries="none" (default) for compact text/data responses (distance, duration, ' +
'turn-by-turn instructions). Use geometries="geojson" only when you need the raw route ' +
'coordinates in the response yourself - render_map_tool works either way.';
'turn-by-turn instructions, congestion). Use geometries="geojson" when you need the raw route ' +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if I don't want to use the render_map_tool and require the full geometry? Maybe I call this tool and render my own map, would this degrade my mapping experience?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. The default simplified geometry keeps the route's shape when zoomed out but cuts corners up close, so if you render your own map and let people zoom in on the route, pass overview="full" and you get every vertex. Made that explicit in the tool description and the overview parameter (d384970) so the model knows to ask for it.

The simplified default cuts corners up close, so a caller drawing its own
zoomable map should pass overview="full". From review on #255.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants