Fix static_map_image_tool's hosted stateless follow-up (fast follow to #257) - #258
Open
mattpodwysocki wants to merge 1 commit into
Open
Fix static_map_image_tool's hosted stateless follow-up (fast follow to #257)#258mattpodwysocki wants to merge 1 commit into
mattpodwysocki wants to merge 1 commit into
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fast follow-up to #257, for the one tool deliberately deferred there:
static_map_image_tool.Same bug: images over the 700KB inline threshold were stashed in
temporaryResourceManager(an in-processMap, 30-minute TTL) behind amapbox://temp/static-map-{id}ref. On the hosted deployment's stateless, multi-ECS-task setup with no session stickiness, a follow-upresources/readlanding on a different task than the one that fetched the image found nothing.Why this isn't just "apply #257's fix to this tool too"
#257's
mapbox://inline-response/scheme encodes the tool's full JSON output directly into the ref. That doesn't work for images: base64-encoding raw bytes into a URI blows past the MCP SDK's own hard 1,000,000-character resource-URI cap almost immediately. Confirmed live — a 750KB image (barely over this tool's 700KB threshold) alone encodes to a 1,024,055-character URI, and the SDK rejects the read. Images that actually need this fallback can run into multiple megabytes (e.g. 1280x1280@2x), so there's no realistic threshold below which encoding bytes directly would be safe.Fix
The new
mapbox://inline-image/static-map?data=...ref encodes only the original request params (center, zoom, style, overlays — a few hundred bytes at most), not the image.resources/readre-issues the Static Images API request at read time, using those params and the reader's own resolved access token. The Static Images API is a deterministic renderer of those params, so this reproduces the exact same image on demand instead of storing it:Extracted
buildStaticMapRequestUrl.ts(URL building + overlay encoding, previously inlined in the tool) so bothStaticMapImageTooland the newInlineImageResourceshare the exact same request-construction logic.Verification
test/integration/hostedMultiTaskFollowupStaticMap.test.ts: a real two-process integration test — fetches a large image in one spawned server process, kills that process outright, and re-fetches the identical bytes from a second, completely independent process via a realresources/readcall.mapbox://temp/code path, then restored the fix and confirmed it passes.npm run build,npx vitest run(951 tests passing),npx eslint --fixon all changed/new files — all clean.Test plan
npm run buildnpx vitest run— 951 tests passingnpx eslint --fix— clean🤖 Generated with Claude Code