claude-code - 💡(How to fix) Fix [BUG] MCP tool output not rendered in terminal when using native TextContent (fastmcp 3.x) [4 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#56874Fetched 2026-05-07 03:43:09
View on GitHub
Comments
4
Participants
2
Timeline
10
Reactions
0
Timeline (top)
labeled ×5commented ×4closed ×1

Error Message

Error Messages/Logs

Root Cause

Root cause from source analysis (cli.js):

Code Example

No errors. The behavior is silent — tool output simply doesn't appear.
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

MCP tool output is not displayed in the terminal ⎿ block when the server returns native TextContent via fastmcp 3.x. The text is consumed silently by the model — users cannot see what the tool returned.

When the same text is returned as -> str (which fastmcp wraps in structuredContent: {"result": "..."} automatically), it IS shown — but as a JSON blob with escaped \n characters, not as formatted multi-line text.

Built-in tools like Bash render multi-line output with real newlines. MCP tools have no equivalent path.

What Should Happen?

MCP tool text output should be rendered in the terminal identically to Bash stdout — with real newlines, passed directly to the uK display component. Specifically:

  1. When CallToolResult.content contains TextContent items, their .text should be displayed in the ⎿ block with newlines preserved.
  2. When structuredContent.result is a string, it should be displayed as plain text, not JSON-serialized.

Error Messages/Logs

No errors. The behavior is silent — tool output simply doesn't appear.

Steps to Reproduce

Minimal repro — two tools, same text, different visibility:

#server.py — requires: pip install fastmcp==3.2.4
from fastmcp import FastMCP
from mcp.types import TextContent

mcp = FastMCP("repro")

@mcp.tool()
async def visible() -> str:
"""Visible but JSON-escaped."""
return "Line 1\n Line 2\n Line 3"

@mcp.tool()
async def hidden() -> TextContent:
"""Hidden from terminal entirely."""
return TextContent(type="text", text="Line 1\n Line 2\n Line 3")

if name == "main":
mcp.run(transport="stdio")

Add to .mcp.json:
{"mcpServers": {"repro": {"command": "python3", "args": ["server.py"]}}}

  1. Call visible — terminal shows ⎿ {"result":"Line 1\n Line 2\n Line 3"} (JSON blob, newlines escaped)
  2. Call hidden — terminal shows nothing (output consumed by model, invisible to user)

Expected for both: terminal shows:
⎿ Line 1
Line 2
Line 3

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No response

Claude Code Version

2.1.116

Platform

AWS Bedrock

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

Root cause from source analysis (cli.js):

The MCP tool renderer in C2B() has two paths:

// Path 1: structuredContent present → JSON.stringify → visible but escaped
if ("toolResult" in W) {
return String(W.toolResult); // loses newlines when toString'd from object
}

// Path 2: content array → mapped but displayed differently
if ("content" in W && Array.isArray(W.content)) {
let F = W.content.map((V) => H2B(V, B)).flat();
return F; // array → renderer called but output not shown in terminal
}

The MCP renderer renderToolResultMessage correctly handles TextContent[] arrays and passes .text to uK. However, in practice the output is not displayed when structuredContent is absent from the wire response.

For comparison, Bash's renderer (mu component) passes stdout directly to uK as a plain string — newlines render correctly.

Suggested fix: When the MCP tool result contains only TextContent items, extract and join their .text values and pass directly to uK as a plain string (same as Bash stdout), instead of JSON-serializing the response object.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] MCP tool output not rendered in terminal when using native TextContent (fastmcp 3.x) [4 comments, 2 participants]