You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE] Forward MCP EmbeddedResource blob to Anthropic API content blocks #72271
When an MCP server returns binary content through the standard EmbeddedResource content block ({ "type": "resource", "resource": { "uri": "...", "mimeType": "application/pdf", "blob": "<base64>" } }), Claude Code CLI v2.1.x persists the blob to a file under ~/.claude/projects/<encoded-cwd>/tool-results/mcp-<server>-blob-<id>.<ext> and surfaces only a placeholder text to the model:
[Resource from <server> at <uri>] Binary content (<mimeType>, <size>) saved to <path>
The blob bytes themselves are not forwarded to the Anthropic API as a document / image / audio content block, so the model cannot natively parse the PDF / image / audio that the server tried to deliver.
The built-in Read tool, in contrast, attaches PDFs as Anthropic API document content blocks (delivered via isMeta user messages) so Sonnet+ can read them natively. This means an MCP filesystem server (= e.g. a sandboxed mirror of the built-in Read) cannot match the upstream PDF-reading fidelity: a PDF returned through MCP becomes a disk path placeholder, while the same PDF returned through the built-in Read becomes a multi-modal document block the model reads end-to-end. The same gap applies to images and audio that a server might want to deliver via EmbeddedResource.
Proposed Solution
When an MCP tool result contains an EmbeddedResource content block with resource.blob and resource.mimeType set, forward the bytes to the Anthropic API as the corresponding content block type:
mimeType: "audio/mp3" / "audio/wav" / etc. → audio content block
Other MIME types fall through to the current disk-save behaviour with a placeholder
The MIME-type routing mirrors what the built-in Read tool already does internally for PDFs.
Alternative Solutions
An MCP server could implement its own pdftoppm + image-cap pipeline (= mirror the built-in Read's parts-mode) and return image content blocks per page. This works (parts-mode is reproducible at the server side) but loses the upstream pdf-mode fidelity and pushes the complexity onto every server author. Image and audio servers have no equivalent fallback.
An MCP server could base64-embed the PDF into a text content block. The model sees the base64 text but cannot natively parse it.
The user could open the file separately and drag-drop it into Claude Code. This bypasses the agent's tool-driven workflow.
None of these substitute for the client honouring the standard MCP EmbeddedResource mechanism for binary content.
Priority
Medium — Would be very helpful
Feature Category
MCP server integration
Use Case Example
I am building an MCP server that exposes a filesystem Read tool to a sandboxed agent. For PDFs I want the agent to receive the same multi-modal experience the built-in Read provides: the model parses the PDF natively, fonts and figures intact.
The client persisted the blob to ~/.claude/projects/<encoded-cwd>/tool-results/mcp-<server>-blob-<id>.pdf.
The model's tool result content was the placeholder [Resource from <server> at file:///path/to/file.pdf] Binary content (application/pdf, <size>) saved to <path>.
The model could only see the path, not the PDF.
If the client had forwarded the blob into an Anthropic document content block, the model would have read the PDF directly, just as it does for built-in Read calls.
Built-in Read's PDF transport (= document content block on an isMeta user message) gives the model the native PDF experience. The MCP EmbeddedResource path is the closest standard equivalent for MCP servers, but it currently degrades to a disk-save placeholder.
Related but distinct: [DOCS] Custom tools docs do not explain unsupported MCP image MIME fallback #60408 ([DOCS] Custom tools docs do not explain unsupported MCP image MIME fallback) covers the docs side for unsupported image MIME fallbacks. This request is about forwarding supported MIME types (application/pdf, supported image and audio types) into the corresponding Anthropic API content blocks rather than degrading them.
✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
Problem Statement
When an MCP server returns binary content through the standard
EmbeddedResourcecontent block ({ "type": "resource", "resource": { "uri": "...", "mimeType": "application/pdf", "blob": "<base64>" } }), Claude Code CLI v2.1.x persists the blob to a file under~/.claude/projects/<encoded-cwd>/tool-results/mcp-<server>-blob-<id>.<ext>and surfaces only a placeholder text to the model:The blob bytes themselves are not forwarded to the Anthropic API as a
document/image/audiocontent block, so the model cannot natively parse the PDF / image / audio that the server tried to deliver.The built-in
Readtool, in contrast, attaches PDFs as Anthropic APIdocumentcontent blocks (delivered viaisMetauser messages) so Sonnet+ can read them natively. This means an MCP filesystem server (= e.g. a sandboxed mirror of the built-inRead) cannot match the upstream PDF-reading fidelity: a PDF returned through MCP becomes a disk path placeholder, while the same PDF returned through the built-inReadbecomes a multi-modaldocumentblock the model reads end-to-end. The same gap applies to images and audio that a server might want to deliver viaEmbeddedResource.Proposed Solution
When an MCP tool result contains an
EmbeddedResourcecontent block withresource.blobandresource.mimeTypeset, forward the bytes to the Anthropic API as the corresponding content block type:mimeType: "application/pdf"→documentcontent block (={ type: "document", source: { type: "base64", media_type: "application/pdf", data: <base64> } })mimeType: "image/png"/"image/jpeg"/"image/gif"/"image/webp"→imagecontent blockmimeType: "audio/mp3"/"audio/wav"/ etc. →audiocontent blockThe MIME-type routing mirrors what the built-in
Readtool already does internally for PDFs.Alternative Solutions
pdftoppm+ image-cap pipeline (= mirror the built-inRead's parts-mode) and returnimagecontent blocks per page. This works (parts-mode is reproducible at the server side) but loses the upstream pdf-mode fidelity and pushes the complexity onto every server author. Image and audio servers have no equivalent fallback.textcontent block. The model sees the base64 text but cannot natively parse it.None of these substitute for the client honouring the standard MCP
EmbeddedResourcemechanism for binary content.Priority
Medium — Would be very helpful
Feature Category
MCP server integration
Use Case Example
I am building an MCP server that exposes a filesystem
Readtool to a sandboxed agent. For PDFs I want the agent to receive the same multi-modal experience the built-inReadprovides: the model parses the PDF natively, fonts and figures intact.I returned the PDF bytes through the Go SDK as:
Observed against Claude Code CLI 2.1.x:
~/.claude/projects/<encoded-cwd>/tool-results/mcp-<server>-blob-<id>.pdf.[Resource from <server> at file:///path/to/file.pdf] Binary content (application/pdf, <size>) saved to <path>.If the client had forwarded the blob into an Anthropic
documentcontent block, the model would have read the PDF directly, just as it does for built-inReadcalls.Additional Context
MCP specification,
EmbeddedResource/ResourceContents: https://modelcontextprotocol.io/specification.ResourceContents.blobis the standard MCP mechanism for binary resources.MCP Go SDK type definition (
github.com/modelcontextprotocol/[email protected]/mcp/content.go):Built-in
Read's PDF transport (=documentcontent block on anisMetauser message) gives the model the native PDF experience. The MCPEmbeddedResourcepath is the closest standard equivalent for MCP servers, but it currently degrades to a disk-save placeholder.Related but distinct: [DOCS] Custom tools docs do not explain unsupported MCP image MIME fallback #60408 (
[DOCS] Custom tools docs do not explain unsupported MCP image MIME fallback) covers the docs side for unsupported image MIME fallbacks. This request is about forwarding supported MIME types (application/pdf, supported image and audio types) into the corresponding Anthropic API content blocks rather than degrading them.✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)