[BUG] MCP tool ImageContent is duplicated into structuredContent and injected as text (~25K-token truncation), despite the image also rendering natively

Resolved 💬 1 comment Opened Jun 23, 2026 by Clare113 Closed Jul 7, 2026

Related to #31208 (closed as stale + locked; the auto-bot said to file a new issue and reference it). Same root cause, now with protocol-level proof and a controlled A/B repro.

What's wrong

When an MCP tool returns an ImageContent block, Claude Code renders the image natively (good) but also serializes the tool result's structuredContent into the model context as text — and for such tools structuredContent contains the image's base64. So the model receives the full base64 as text on top of the rendered image, blowing past the ~25,000-token tool-output cap and triggering [OUTPUT TRUNCATED - exceeded 25000 token limit], plus large context waste.

Why structuredContent contains the base64

FastMCP auto-enables structured output from a tool's return type annotation (e.g. -> list[ImageContent | TextContent]) and copies the return value (including the base64) into structuredContent; the MCP spec also mandates a backward-compat text mirror. Claude Code feeds that text (with base64) to the model instead of de-duplicating against the already-rendered image block.

Evidence

  1. Cross-client: claude.ai web handles the identical server correctly (renders image + a small text block, no base64 text, no truncation). Claude Code (VSCode extension and CLI) dumps the base64 as text and truncates.
  2. Protocol-level: the raw CallToolResult shows content carries the image block's base64 and structuredContent separately carries the same base64 (a multi-hundred-KB string).
  3. Controlled A/B (same Claude Code CLI client): two identical servers — one with structured output ON → truncation + base64-as-text; one with structured_output=False → clean (image still renders). The only difference is structured output.

| server | truncated | base64-as-text | image rendered |
|---|---|---|---|
| structured output ON | yes | yes | yes |
| structured_output=False | no | no | yes |

Expected

When a tool result has image content blocks and a structuredContent that embeds the same image data, Claude Code should render the image natively and not inject the base64 as text. More generally, don't serialize large binary data fields from structuredContent into the model's text context.

Server-side workaround (not a real fix)

Set structured_output=False on image-returning FastMCP tools (or drop the return annotation). But this requires every server author to know about it; the proper fix is client-side.

Environment

Claude Code 2.1.170; reproduced on both the VSCode extension and the CLI.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗