Skip to content

MCP resources/read: binary (blob) resources returned as TextResourceContents — base64 string forwarded as text #32330

Description

@juancarlosm

Version: v1.92.0-dev.2 (same code path on main).

Summary

Reading a binary MCP resource through the proxy returns TextResourceContents (base64 in text, mimeType e.g. application/gzip) instead of BlobResourceContents (base64 in blob). The bytes are intact but mislabeled: a client that reads blob for binary resources sees it empty, and one that treats text as UTF-8 mangles it.

Root cause

_normalize_resource_contents forwards a blob's base64 string as content:

elif isinstance(content, BlobResourceContents):
    normalized.append(ReadResourceContents(content=content.blob, ...))  # content.blob is a str

The MCP SDK then re-serializes ReadResourceContents via create_content (mcp/server/lowlevel/server.py), where ReadResourceContents.content: str | bytes is the discriminator: str -> TextResourceContents, bytes -> BlobResourceContents. Handed a str, it emits text. (The sibling TextResourceContents branch correctly passes content.text, a str.)

Reproduce

  1. Upstream MCP server exposing a binary resource (e.g. an application/gzip blob).
  2. resources/read through the proxy.
  3. Result is TextResourceContents with the base64 in text; blob is absent. Expected BlobResourceContents.

Expected

Binary resources round-trip as BlobResourceContents (base64 in blob), preserving the upstream text/blob distinction.

Suggested fix

Decode the blob to bytes so the SDK re-emits a blob (symmetric with the text branch; the SDK re-base64-encodes, so it round-trips exactly):

elif isinstance(content, BlobResourceContents):
    normalized.append(ReadResourceContents(content=base64.b64decode(content.blob), ...))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions