feat: return image attachments as native MCP image content#237
Open
vbichkovsky wants to merge 1 commit intokorotovsky:masterfrom
Open
feat: return image attachments as native MCP image content#237vbichkovsky wants to merge 1 commit intokorotovsky:masterfrom
vbichkovsky wants to merge 1 commit intokorotovsky:masterfrom
Conversation
Previously, attachment_get_data returned image files as base64-encoded strings inside a JSON text response. For typical images (100-200KB), the base64 expansion produces 130-270KB of text that exceeds MCP client token limits, forcing clients to save overflow to temp files and manually decode base64 — defeating the purpose of the tool. Use the MCP SDK's NewToolResultImage to return images as native image content, which MCP clients can render directly. File metadata (file_id, filename, mimetype, size) is returned as the text component. Non-image binary files retain the existing base64-in-text behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
chriscoey
reviewed
Mar 23, 2026
chriscoey
left a comment
There was a problem hiding this comment.
Nice, focused change. Returning images as native MCP image content via mcp.NewToolResultImage is a clear improvement over embedding base64 inside a JSON text result.
The isImageMimetype prefix check handles all image subtypes correctly, and the metadata JSON uses the existing escapeJSON helper to handle filenames with special characters. Good that it falls through to the existing text/binary path for non-image files — no behavior change for other file types.
LGTM — this would be useful for multimodal MCP clients.
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
image/*mimetype) are now returned usingmcp.NewToolResultImageinstead of embedding base64 inside a JSON text responsemcp-goSDK capabilityProblem
attachment_get_datareturns binary files as base64-encoded strings inside a JSON text response. A typical Slack image (100-200KB) expands to 130-270KB of base64 text. This exceeds the token limits of MCP clients (e.g. Claude Code), which then save the overflow to a temp file — requiring the user to manually decode base64, write to disk, and open the image separately.This turns a single tool call into a multi-step workaround involving bash, python, and manual file management.
Solution
The MCP SDK already provides
NewToolResultImage(text, imageData, mimeType)which returns images as nativeImageContent. MCP clients that support image rendering (Claude Code, Claude Desktop) can display these directly.For
image/*mimetypes, the handler now returns:file_id,filename,mimetype,size)This is a non-breaking change — text files and non-image binary files are unaffected.
Test plan
attachment_get_dataon a Slack PNG attachment now returns the image inline in a single tool call, rendered directly by the clientFixes #88 (partially — improves the image attachment experience specifically)
🤖 Generated with Claude Code