claude-code - 💡(How to fix) Fix [BUG] MCP tool wrapper concatenates parameter XML into one string field instead of serializing structured args

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…

Fix Action

Fix / Workaround

  • MCP 2026-07-28 (release candidate locked 2026-05-21) allows servers to advertise permissive schemas during transition. Servers that have not yet derived per-command schemas are uncallable from Claude Code's MCP wrapper for any tool with complex args.
  • Consumer-side workaround: bypass the wrapper and POST JSON-RPC directly via curl. Works, but defeats the integration ergonomics MCP is supposed to provide.

Code Example

{
  "name": "example_tool",
  "inputSchema": { "type": "object", "additionalProperties": true }
}

---

{
  "name": "example_tool",
  "arguments": {
    "body": "...the prose...</body>\n<parameter name=\"attributes\">{\"key1\": \"value1\", ...}</parameter>",
    "attributes": {}
  }
}
RAW_BUFFERClick to expand / collapse

Environment

  • Claude Code 2.1.150
  • Model: Claude Opus 4.7 (1M context) — claude-opus-4-7[1m]
  • MCP server: any server advertising an additionalProperties: true input_schema for a tool with multiple parameters (one long-text, one object-shaped), reachable over Streamable HTTP.

What's wrong

When Claude Code's MCP wrapper calls a tool whose input_schema is permissive ({"type": "object", "additionalProperties": true}) and the model emits a tool_use block with multiple parameters — one with multi-line string content, another with object content — the on-the-wire JSON-RPC payload concatenates ALL parameters as text into the FIRST parameter's slot, with the subsequent parameters appearing as literal XML tag wrapping inside that string. The structured non-first parameters arrive empty.

Minimal reproduction

Any MCP server advertising:

{
  "name": "example_tool",
  "inputSchema": { "type": "object", "additionalProperties": true }
}

Invoke this tool with:

  • body = a multi-line string of prose
  • attributes = a JSON object like {"key1": "value1", "key2": "value2"}

The MCP server receives a JSON-RPC tools/call with:

{
  "name": "example_tool",
  "arguments": {
    "body": "...the prose...</body>\n<parameter name=\"attributes\">{\"key1\": \"value1\", ...}</parameter>",
    "attributes": {}
  }
}

Two consecutive corrupted records were observed in this state, each with:

  • body containing a literal </body>\n<parameter name=\"attributes\">{...JSON...}</parameter> suffix
  • attributes field arriving as empty object {}

Direct curl POST to the same endpoint with the same tool call content (structured JSON arguments in JSON-RPC) lands cleanly. The MCP server parses JSON-RPC correctly. The corruption is upstream of the wire — in how Claude Code's wrapper serializes the tool_use XML into JSON-RPC arguments.

Hypothesis

When the input_schema is open (additionalProperties: true), the wrapper's tool-arg serializer appears to fall back to concatenating the emitted parameter XML as text instead of parsing each <parameter name=\"..\">value</parameter> block into a structured arguments field. Tight-typed schemas (e.g. properties: {body: {type: \"string\"}}) likely route through the correct code path; permissive schemas trigger the broken path.

Why it matters

  • MCP 2026-07-28 (release candidate locked 2026-05-21) allows servers to advertise permissive schemas during transition. Servers that have not yet derived per-command schemas are uncallable from Claude Code's MCP wrapper for any tool with complex args.
  • Consumer-side workaround: bypass the wrapper and POST JSON-RPC directly via curl. Works, but defeats the integration ergonomics MCP is supposed to provide.

Expected behavior

Claude Code's wrapper should serialize each <parameter> block's value as a structured JSON-RPC argument, regardless of how permissive the server's input_schema is. The schema's role is validation, not serialization control.

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…

FAQ

Expected behavior

Claude Code's wrapper should serialize each <parameter> block's value as a structured JSON-RPC argument, regardless of how permissive the server's input_schema is. The schema's role is validation, not serialization control.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING