Skip to content

fix: static_map_image_tool large images work on the hosted server (fast follow to #257) - #258

Open
mattpodwysocki wants to merge 4 commits into
mainfrom
fix/static-map-hosted-stateless-followup
Open

mattpodwysocki wants to merge 4 commits into
mainfrom
fix/static-map-hosted-stateless-followup

Conversation

@mattpodwysocki

@mattpodwysocki mattpodwysocki commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #257 for the one tool it deferred: static_map_image_tool.

Same bug: images over the 700 KB inline limit were stored in temporaryResourceManager (one process's memory, 30-minute TTL) behind a mapbox://temp/static-map-{id} ref. On the hosted deployment (several stateless tasks, no session stickiness), a follow-up resources/read that landed on another task found nothing.

Fix

Large images now get a mapbox://response/static-map?data=... ref, the same scheme #257 uses for large directions_tool and isochrone_tool responses. The ref carries the request's inputs (center, zoom, size, style, overlays), not the image, and ToolResponseResource renders the image again with the reader's token and returns it as a blob. The Static Images API returns the same image for the same parameters.

  • The ref stays a few hundred bytes however big the image is. Encoding the bytes themselves would blow past the SDK's 1,000,000-character URI cap: a 750 KB image alone encodes to over 1,000,000 characters.
  • Any process can answer a read; nothing is kept between the call and the read.
  • Costs one extra Static Images request per follow-up read.
  • URL building moved to buildStaticMapRequestUrl.ts (same { input, accessToken, apiEndpoint } shape as buildDirectionsRequestUrl), shared by the tool and the resource.

Updated after #257 and #296 merged: this first added its own mapbox://inline-image/ scheme and InlineImageResource. #257 landed with a generic mapbox://response/ scheme that does the same thing, so static map is now a third tool on it instead, and the separate resource and inlineImageRef.ts are gone. Tests are ported to SDK v2.

Testing

  • test/integration/hostedMultiTaskFollowupStaticMap.test.ts: fetches a 750 KB image in one spawned server process, kills it, and reads the ref from a second independent process over real MCP, checking the bytes match exactly.
  • ToolResponseResource tests: the static map ref renders the same request URL and returns the exact bytes with the right MIME type; bad inputs come back as text without making a request, and API errors come back as text.
  • Typecheck clean, build OK, 97 files / 1087 tests pass (plus the 3 integration tests), lint 0 errors.

🤖 Generated with Claude Code

…ching inline-image ref

Same hosted multi-task bug as directions_tool/isochrone_tool (#257):
static_map_image_tool stashed large images in temporaryResourceManager
(an in-process Map, 30-min TTL) behind a mapbox://temp/static-map-{id}
ref, which a follow-up resources/read landing on a different ECS task
couldn't see.

That fix's JSON-in-ref approach doesn't transfer to images: base64-
encoding raw bytes into a URI blows past the MCP SDK's own 1,000,000-
character resource-URI cap almost immediately (a 750KB image alone
encodes to 1,024,055 characters), and images needing this fallback can
run into multiple megabytes.

Instead, the new mapbox://inline-image/static-map?data=... ref encodes
only the original request params (center, zoom, style, overlays - a
few hundred bytes), and resources/read re-issues the Static Images API
request at read time using those params and the reader's own resolved
access token. The API is a deterministic renderer, so this reproduces
the exact same image on demand instead of storing it - no size
ceiling, works from any task. Extracted buildStaticMapRequestUrl.ts so
the tool and the resource share the same URL-building logic.

Verified with a real two-process integration test (fetch in one
spawned server, kill it, re-fetch identical bytes from a second,
independent process), and confirmed it fails against the old
mapbox://temp/ code path before the fix and passes after.
@mattpodwysocki
mattpodwysocki requested a review from a team as a code owner August 27, 2026 17:50
…-stateless-followup

Moves the large-image ref onto #257's mapbox://response/ scheme instead of a
separate mapbox://inline-image/ one: static-map is a third ResponseTool and
ToolResponseResource renders the image again on read. Drops
InlineImageResource and inlineImageRef.ts, and ports the tests to SDK v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mattpodwysocki mattpodwysocki changed the title Fix static_map_image_tool's hosted stateless follow-up (fast follow to #257) fix: static_map_image_tool large images work on the hosted server (fast follow to #257) Oct 26, 2026
@mattpodwysocki mattpodwysocki added the enhancement New feature or request label Oct 26, 2026
mattpodwysocki and others added 2 commits October 28, 2026 15:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant