Skip to content

get_file_contents on protocol 2026-07-28 doubles payload and breaks clients with 1 MiB message limits #3603

Open

Description

@danidra

Describe the bug

On protocol 2026-07-28, get_file_contents sends the file body twice: once in content[].resource.text and again in structuredContent. This was raised in #3500, which was closed arguing that clients should dedupe. That works for token cost, but it doesn't help with transport size limits. These limits apply before any client-side dedupe can happen.

Affected version

Remote GitHub MCP server (hosted). Behavior matches main @ f385262. Typed output is added in pkg/inventory/typed_output.go, and the body is mirrored in repositoryContentOutput (pkg/github/repository_tool_types.go).

Steps to reproduce the behavior

  1. Use an MCP client that negotiates protocol 2026-07-28 and enforces a 1 MiB SSE event limit.
  2. Call get_file_contents on a text file of 517,740 bytes.
  3. The tool result is 1,113,189 bytes (~518 KB in content + ~595 KB in structuredContent, with JSON escaping), and the client fails with:
    JSON-RPC -32000: SSE stream failed: Server-sent event exceeded the 1048576 byte limit
    
  4. The same file works on protocol 2025-11-25, where structuredContent is not emitted.

Expected vs actual behavior

Expected: a ~518 KB file is delivered as ~518 KB plus metadata, as on the legacy protocol.

Actual: the payload doubles and goes over common 1 MiB message limits.

Why this should be fixed server-side

I respectfully disagree that this should be solved client-side:

  • Client-side dedupe only helps once the message has been received. It can't help when the transport rejects the message first.
  • It forces every MCP client to implement the same workaround. Until they do, all of them pay double bandwidth and memory.
  • As noted in fix(repos)!: stop mirroring file bodies in get_file_contents structured output #3500, the spec doesn't require mirroring the body in structuredContent.
  • Files ≥ 1 MB already return a ResourceLink (maxContentSize), but this threshold doesn't account for the duplication. Files of roughly 470 KB to 1 MB now fail on modern-protocol clients with message limits. The usable file size is effectively halved.

Proposed fixes (non-breaking alternatives to #3500)

  1. Account for the duplication in the ResourceLink threshold: on the modern protocol, return a ResourceLink for files above ~500 KB, so the full result stays under 1 MiB. Existing structuredContent consumers keep the same schema.
  2. Opt-in flag/header: a server option (e.g. a header for the remote server) to omit the body from structuredContent. Default behavior is unchanged, and clients with message limits can opt in.

Happy to provide more details or test a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions