Skip to content

feat(read_file): opt-in DC_NO_IMAGE_STRUCTURED_BASE64 to omit duplicate image base64 from structuredContent#522

Open
carrotRakko wants to merge 1 commit into
wonderwhy-er:mainfrom
carrotRakko:feat/opt-in-image-structured-content-base64
Open

feat(read_file): opt-in DC_NO_IMAGE_STRUCTURED_BASE64 to omit duplicate image base64 from structuredContent#522
carrotRakko wants to merge 1 commit into
wonderwhy-er:mainfrom
carrotRakko:feat/opt-in-image-structured-content-base64

Conversation

@carrotRakko

@carrotRakko carrotRakko commented Jun 23, 2026

Copy link
Copy Markdown

Summary

Refs #521 (server-side opt-in path).

When read_file returns an image, the image bytes are currently emitted twice:

  • in content[1] as the MCP image block (so the host model can see the image natively)
  • in structuredContent.content and structuredContent.imageData (intended for the preview widget)

MCP clients that serialize structuredContent into the model's text input alongside the rendered image block end up paying for ~100 KB of duplicate base64 per image read (see #521 for a measured ~2.7× context bloat with Claude Code CLI). The image block already conveys the image; the structuredContent-side base64 is duplicate.

This PR adds an opt-in env var DC_NO_IMAGE_STRUCTURED_BASE64=true that omits the content / imageData fields from structuredContent in handleReadFile's image branch. The MCP content[image] block and all other structuredContent metadata (fileName, filePath, fileType, sourceTool, mimeType) stay intact, so:

  • the host model still sees the image natively
  • preview widget consumers that don't read the embedded base64 are unaffected
  • consumers that do read the embedded base64 keep working by default (the env var is off by default)

#521 lists four possible directions; this PR takes the smallest one (a config-flag opt-in). The other directions (resource_link, audience annotations, currentClient-based adaptation) remain viable — if the review prefers one of them, the PR can be reshaped accordingly.

Changes

  • src/handlers/filesystem-handlers.ts: read the env var in the image branch of handleReadFile, conditionally spread content / imageData into structuredContent
  • test/test-image-structured-content-toggle.js (new): three subtests — default keeps base64, =true omits it (while keeping content[image] and metadata), only the literal string "true" enables the opt-in

Test plan

  • npm run build clean
  • node test/test-image-structured-content-toggle.js — all three subtests pass
  • node test/test-file-handlers.js — existing image read test (Test 9) still passes (no regression)

Related

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

Summary by CodeRabbit

  • New Features

    • Image base64 data in structured content responses can now be optionally excluded using an environment variable control, reducing serialized output size while preserving image rendering in content arrays.
  • Tests

    • Added comprehensive test coverage validating the image data exclusion toggle behavior across multiple configuration states.

…te image base64 from structuredContent

The image base64 is currently emitted twice in read_file's image response:
- in content[1] as the MCP image block (so the host model can see the image)
- in structuredContent.content / .imageData (for the preview widget)

For MCP clients that serialize structuredContent into the model's text input
alongside the rendered image block, this duplicate becomes large per-call
context bloat. This adds an opt-in env var (DC_NO_IMAGE_STRUCTURED_BASE64=true)
that omits content/imageData from structuredContent's image branch. The
content[image] block and all other structuredContent metadata stay intact;
default behavior is unchanged.

Refs wonderwhy-er#521
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ef0be93-9645-4d93-bd0c-6e6e3c1c3f98

📥 Commits

Reviewing files that changed from the base of the PR and between be82290 and 2865e33.

📒 Files selected for processing (2)
  • src/handlers/filesystem-handlers.ts
  • test/test-image-structured-content-toggle.js

📝 Walkthrough

Walkthrough

Adds a DC_NO_IMAGE_STRUCTURED_BASE64 environment variable check to handleReadFile's image branch. When set to the literal string 'true', the base64 fields (content, imageData) are omitted from structuredContent while the MCP content[] image block retains the base64 data. A new test script validates the three behavioral cases.

Changes

Image base64 structuredContent toggle

Layer / File(s) Summary
omitStructuredBase64 flag and structuredContent construction
src/handlers/filesystem-handlers.ts
Introduces omitStructuredBase64 boolean from process.env.DC_NO_IMAGE_STRUCTURED_BASE64 === 'true' and conditionally spreads or omits content/imageData fields from structuredContent in the image branch of handleReadFile. The content[] image block with base64 is always emitted regardless of the flag.
Test script for toggle behavior
test/test-image-structured-content-toggle.js
New standalone test script that creates a temp directory, writes a tiny PNG, and verifies: (1) default behavior preserves base64 in structuredContent, (2) DC_NO_IMAGE_STRUCTURED_BASE64='true' omits structuredContent.content and structuredContent.imageData while keeping the content[] image block, and (3) non-'true' values such as '1', 'yes', 'TRUE', '' do not trigger omission. Exports runTests() and includes a CLI entry point.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐇 A bunny found images, plump and quite grand,
Base64 doubling — too much to withstand!
One env-var set, the duplicates flee,
structuredContent slims down, light and free.
Yet content[] stays, the image still shines — 🖼️
Toggle it wisely, and all will be fine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding an opt-in environment variable to omit duplicate image base64 from structuredContent, which directly aligns with the PR's core objective and all file changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant