XML tool-call converter drops content parameter (size + parallel-batch triggers)
Summary
Tool-calls invoked from main-context with a <parameter name="content"> value larger than approximately 5500-11000 chars are converted to JSON-RPC bodies where arguments.content is "" (empty) and the original content text leaks as XML markup into a sibling parameter (e.g. summary_l1). Below the threshold the same tool-call works correctly. The same content delivered via a Background-Subagent (Agent-Tool with internal tool-use) goes through correctly — confirming the bug is in the main-context XML→JSON conversion path.
Update 2026-05-06: Bug also fires at much smaller body sizes (~150 words / ~800 chars) when the tool-call is part of a parallel-batch with other tool-calls in the same message. Parallel-batch position appears to be a confounding factor independent of body size. Threshold may not be size-only.
Reproduction
- Use any MCP server tool that takes a
content: stringparameter (mxLoremx_create_docworks as live target) - From main-context, invoke tool with
content= ~15000 chars Markdown body containing tables, unicode arrows, code blocks - Observe immediate (<1s) reject from server with content-validator error
- Repeat with same content via
Agenttool (general-purpose subagent) → succeeds
Server-side evidence
- HTTP body received intact:
bytes=15636 chars=15511(correct UTF-8 size) - JSON parser accepts body
arguments.contentfield is empty string in parsed JSON- Body tail shows
...\"master\"]</parameter>\n</invoke>\n\"},\"_meta\":...— XML closing tags landed as TEXT inside a JSON string value - 0 transport-level errors, dozens of validator-level "got 0 chars" rejects across logs
Threshold pattern
| content size | result |
|---|---|
| 4500 chars | success |
| 2800 chars | success |
| ~800 chars (parallel-batch context) | fail |
| 11488 chars | fail |
| 15511 chars | fail |
Threshold inconsistent at ~5500-11000 chars in solo calls; smaller sizes also fail when in parallel-batch with other tool-calls. Current Claude Code Opus 4.7 1M-context build.
Workaround
Delegate the call to a Background-Subagent: subagent constructs the tool-call internally using its own JSON args path, not the main-context XML-parameter encoding. Same content, same MCP server, same tool — succeeds reliably.
Environment
- Claude Code Opus 4.7 (1M context)
- Tool: any MCP server with content: string parameter
- Repro confirmed: Win32 stdio + Windows MCP-Proxy bridge AND HTTP Streamable MCP — bug is upstream of both bridge layers
- Date first observed: 2026-04-27
- Date re-confirmed in parallel-batch context: 2026-05-06
Impact
Silent data-loss: the user-visible error is a server-side validator reject saying "content required", which masks the real bug location. Reporters chase server-side phantoms instead of escalating to CC-CLI. MCP server implementers have to add empty-body server-side guards as defense-in-depth (see e.g. mxLore Bug#4378 fix in build 112).
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗