[FEATURE] Honour MCP Annotations.Audience on tool-result content blocks

Open 💬 2 comments Opened Jun 29, 2026 by carrotRakko

Problem Statement

When a Claude Code session uses MCP servers heavily (e.g. an MCP filesystem server, mcp__fetch__fetch, perplexity, webcrawler.ai, ...) and the agent makes many tool calls that return long text bodies (e.g. reading a few hundred lines of a file), the entire body of every MCP tool response is rendered in the interactive TUI. The transcript becomes dominated by tool output rather than by the agent's actual reasoning and conclusions.

Built-in tools like Read collapse to a single line (Read 10 lines), so the same workflow with the built-in stays readable. There is no equivalent collapsing for MCP tool output, even though the MCP specification has a standard mechanism for this.

Proposed Solution

Honour the MCP specification's Annotations.Audience field on tool-result content blocks:

  • A content block whose annotations.audience includes "user" but not "assistant" is intended for the user-visible UI. Render it in the TUI; do not forward it to the model.
  • A content block whose annotations.audience includes "assistant" but not "user" is intended for the model. Forward it to the model; render only a compact summary line in the TUI (similar to how the built-in Read shows Read N lines).
  • A content block with both, or neither (the current default for most servers), keeps the current rendering behaviour for back-compat.

This lets each MCP server decide, per response, what the human and the model should see. It is the standard MCP mechanism for exactly this kind of split, defined in the MCP spec under Annotations.

Alternative Solutions

  • A global "collapse MCP tool output" setting like #56423, or the --quiet flag proposed in #9340. Useful for users who want a uniform default, but neither gives the server any way to express "this particular response should show a short summary in the TUI but a long body to the model" on a per-call basis. The two approaches are complementary; honouring Annotations.Audience adds an axis the global flag cannot reach.
  • Wrapping the MCP server in a custom client (the same pattern that turns the built-in Read into Read 10 lines). Not portable across MCP servers and pushes the problem onto every server author.

Priority

Medium — Would be very helpful

Feature Category

MCP server integration

Use Case Example

I am building an MCP server that exposes filesystem tools. For a read tool I want the agent's user to see a single TUI line Read 10 lines from /path/to/file.md, while the agent itself receives the full file content (numbered cat -n style, exactly like the built-in Read).

I tried this against Claude Code 2.1.x by returning two content blocks from a Go-SDK-based MCP server:

return &mcp.CallToolResult{
    Content: []mcp.Content{
        &mcp.TextContent{
            Text:        "Read 10 lines from /path/to/file.md",
            Annotations: &mcp.Annotations{Audience: []mcp.Role{"user"}},
        },
        &mcp.TextContent{
            Text:        fullCatNStyleBody,
            Annotations: &mcp.Annotations{Audience: []mcp.Role{"assistant"}},
        },
    },
}, nil, nil

Observed behaviour:

  • The TUI showed both content blocks back-to-back (the summary line, then the full numbered body underneath), exactly as if Annotations.Audience had not been set at all.
  • The model also saw both blocks concatenated into a single string in its tool result.

Annotations.Audience appears to have no effect on either rendering or model-side delivery.

Additional Context

  • MCP specification, Annotations: <https://modelcontextprotocol.io/specification> (see the Annotations type with audience, priority, and lastModified fields).
  • MCP Go SDK type definition: github.com/modelcontextprotocol/go-sdk@v1.6.1/mcp/protocol.go, lines 16–37:

``go
type Annotations struct {
Audience []Role // intended customer ("user", "assistant", or both)
LastModified string
Priority float64
}
``

Each TextContent / ImageContent / etc. carries an optional *Annotations pointer (mcp/content.go).

  • Related but distinct asks:
  • #56423 — global "collapse tool outputs" setting
  • #9340 — --quiet flag to suppress tool call output
  • #69919 — /context collapse for the MCP tool list (not tool output)
  • #36857 — docs missing collapsed "Queried {server}" display for MCP read/search tool calls

This request is narrower and orthogonal: it asks the client to honour an existing spec hint so MCP servers can drive the user/model split themselves, rather than relying on a global setting.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗