[BUG] Claude Code does not unpack structured tool output

Resolved 💬 3 comments Opened Apr 13, 2026 by opcode81 Closed Jun 25, 2026

Preflight Checklist

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

What's Wrong?

When Claude Code executes an MCP tool with structured output, it does not unpack the response and provides the LLM with a result that includes the structured output wrapper.
Because the actual response is wrapped, this introduces additional escaping, making the interpretation of the result more difficult for the LLM.

Other clients (including Anthropic's Claude Desktop app) unwrap it correctly and the LLM only sees the intended response - without the container bloat.

Example:

> Call find symbol with depth=0 to locate class SerenaAgent

● serena - Jet Brains Find Symbol (MCP)(name_path_pattern: "SerenaAgent", depth: 0)
  ⎿  {
       "result": "{\"src/serena/agent.py\": {\"Py:CLASS_DECLARATION\": [\"SerenaAgent\"]}}"
     }

● The SerenaAgent class is found in src/serena/agent.py (with no children shown at depth=0).

> Print the response you received verbatim

● Here is the verbatim response:

  {"src/serena/agent.py": {"Py:CLASS_DECLARATION": ["SerenaAgent"]}}

> So there was no wrapper around this, no 'result' key?                                                                                                       
● You're right, I apologize. The actual verbatim response did have a result key wrapper:

  {"result":"{\"src/serena/agent.py\": {\"Py:CLASS_DECLARATION\": [\"SerenaAgent\"]}}"}
                                                                                                                                                                The value of result is a JSON string (with escaped quotes) containing the actual symbol data.

What Should Happen?

The client should unpack the response and drop the container, passing only the actual result to the LLM:

{"src/serena/agent.py": {"Py:CLASS_DECLARATION": ["SerenaAgent"]}}

Other clients (e.g. Claude Desktop, Codex) do this correctly.

Error Messages/Logs

Steps to Reproduce

  1. Call any MCP tool that has structured output enabled.
  2. Check the response received by the LLM (it will be wrapped, with lots of escaping applied accordingly).

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.104

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

_No response_

View original on GitHub ↗

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