Skip to content

Tool responses are serialized twice on the wire, inflating token cost for structured-content clients #85

Description

@jakewan

Context

Discovered while sizing the response budget for #74. When a tool returns typed structured output, the MCP SDK emits the result twice — once as structuredContent and once as a back-compat TextContent block (the spec's backward-compatibility suggestion for clients that don't read structuredContent).

Problem

Every tool response crosses the wire at roughly twice its necessary size. For a client that reads structuredContent (which the current consumers do), the TextContent copy is pure overhead: it inflates token cost on every call and doubles the pressure against the tool-result token cap that #74's size bound exists to respect — so the bound has to budget for the doubling and trims earlier than it otherwise would.

Evidence

The SDK sets StructuredContent and, when the handler returns no explicit Content, also copies the same JSON into a TextContent block (go-sdk v1.6.1, mcp/server.go). #74's size-bound default is set conservatively specifically to account for this ~2× wire payload.

Suggested approaches (options)

Suppressing the redundant copy (e.g. returning a non-nil Content so the SDK omits the back-compat block) roughly halves every response — but it should be decided on generic-user grounds, not the current sole-consumer set (per this project's design-fork-adjudication lens):

  • Verify what target clients actually consume — does the client read structuredContent or the text block, and does the token cap count one copy or both? Suppression breaks any client that reads only the text block.
  • Survey whether MCP clients broadly support structuredContent (the 2025-06-18 spec direction); if so, the back-compat copy is vestigial for all users and suppression is safe generically.

Activity

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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions