[FEATURE] Honour MCP Annotations.Audience on tool-result content blocks
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.audienceincludes"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.audienceincludes"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-inReadshowsRead 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
--quietflag 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; honouringAnnotations.Audienceadds an axis the global flag cannot reach. - Wrapping the MCP server in a custom client (the same pattern that turns the built-in
ReadintoRead 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.Audiencehad 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 theAnnotationstype withaudience,priority, andlastModifiedfields). - 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 —
--quietflag to suppress tool call output - #69919 —
/contextcollapse 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)
3 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
This split really does belong with the server — a global collapse flag can't express "short summary to the user, full body to the model" per response, which is exactly what
Annotations.Audienceis for. The complementary lever, until clients honor it, is servers just not emitting bloated output in the first place: I build Pare as MCP wrappers that return compact, schema-validated JSON instead of raw CLI text (~85% fewer tokens for the same result), so the model-side payload stays small regardless of TUI handling. Would still very much wantAudiencehonored for the human-facing summary, though.Another use case for this, from the file-delivery side. Our MCP connector's deliverable is a Word document for a non-technical end user, and there is currently no way for a tool to hand a file to the user at all. Honoring
audience: ["user"]is the cheapest fix for that: forwarding bytes to the model is O(file size) in context, while a user-audience block the client renders and does not forward is free. Details, what we tried, and measurements are inanthropics/claude-ai-mcp#287.