claude-code - 💡(How to fix) Fix MCP tool-call parser appends `</payload></invoke>` to string parameter values (100% repro within affected session) [1 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#48679Fetched 2026-04-16 06:53:56
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Author
Timeline (top)
labeled ×4commented ×1

In a recent Claude Code session, every call to an MCP tool that accepted a string parameter containing multi-paragraph markdown had the literal suffix </payload>\n</invoke> appended to the parameter value. The tags shipped verbatim to the downstream service (in this case, a Slack MCP server that forwards the string to Slack), making them visible to message recipients.

Root Cause

In a recent Claude Code session, every call to an MCP tool that accepted a string parameter containing multi-paragraph markdown had the literal suffix </payload>\n</invoke> appended to the parameter value. The tags shipped verbatim to the downstream service (in this case, a Slack MCP server that forwards the string to Slack), making them visible to message recipients.

Fix Action

Fix / Workaround

The trailing tags appear inside the JSON-encoded input.payload string of the tool_use object stored in the session JSONL (~/.claude/projects/<slug>/<session-id>.jsonl). This means the tags were inside the parameter value by the time the harness dispatched the MCP call — upstream of the MCP server, which is a passive pipe that just forwards whatever string it receives.

Code Example

</payload>\n</invoke>
RAW_BUFFERClick to expand / collapse

Summary

In a recent Claude Code session, every call to an MCP tool that accepted a string parameter containing multi-paragraph markdown had the literal suffix </payload>\n</invoke> appended to the parameter value. The tags shipped verbatim to the downstream service (in this case, a Slack MCP server that forwards the string to Slack), making them visible to message recipients.

Evidence

Repro rate: 6 of 6 sends in the affected session (100%).

Exact trailing suffix — byte-identical across all 6 calls:

</payload>\n</invoke>

(\n is a real newline character, not the two-character literal.)

Examples (last ~60 characters of the payload parameter, verbatim from the session JSONL):

  • ...paste me your config file (redact tokens) and I'll have a look.</payload>\n</invoke>
  • ...isn't exported in your `.zshrc`/`.bashrc`.</payload>\n</invoke>
  • ...That path's 100% reliable.</payload>\n</invoke>

Where the leak originated

The trailing tags appear inside the JSON-encoded input.payload string of the tool_use object stored in the session JSONL (~/.claude/projects/<slug>/<session-id>.jsonl). This means the tags were inside the parameter value by the time the harness dispatched the MCP call — upstream of the MCP server, which is a passive pipe that just forwards whatever string it receives.

The corresponding tool_result echo confirms the server received and shipped the full string including the trailing tags.

Observed pattern

  • 100% repro rate within the affected session (6/6 calls).
  • Byte-identical trailing suffix — zero variance in form.
  • Always terminal, never mid-string.
  • No mismatched tags, no duplicates, no mid-content occurrences.
  • All affected payloads were multi-paragraph markdown (numbered lists, inline code, bold).
  • Earlier Claude-authored messages in the same downstream Slack DM (from a prior session) show no leak, so the bug is session-scoped — not universal to the tool or the markdown content.
  • Short, non-tool-authored messages in the same window are also clean (they bypass the tool-call path entirely).
  • The assistant's human-facing text blocks in the same transcript are clean — the leak is confined to MCP tool_use.input string values.

Hypothesis

The deterministic, byte-identical signature suggests a parser over-capture rather than a model-emission issue. A model hallucinating structural tags would typically produce variance (mismatches, duplicates, malformed tags). A parser whose terminator matches the outer </invoke> instead of the innermost </payload> (or equivalent parameter close) would produce exactly this signature.

Environment

  • Claude Code terminal CLI
  • macOS (darwin 25.3.0)
  • Session occurred within the week ending 2026-04-15
  • MCP server was a passthrough — it just forwards the payload string it receives

Impact

Visible to end recipients of any MCP tool that treats the leaked parameter as user-visible content (Slack, email, webhook bodies, etc.). Silent on the sender's side unless they grep their transcript — the human-facing text stream is clean, so the model doesn't know its tool call shipped garbage.

Repro artefacts

Happy to share the session JSONL privately if useful for root-causing. The relevant file lives at ~/.claude/projects/<slug>/<session-id>.jsonl and shows both the input.payload with the trailing tags and the tool_result echoing them back.

extent analysis

TL;DR

The issue can be fixed by modifying the parser to correctly identify the innermost </payload> tag instead of the outer </invoke> tag.

Guidance

  • Investigate the parser's logic for handling nested tags and terminator matches to identify the over-capture issue.
  • Verify that the tool_use.input string values in the session JSONL file contain the trailing tags by checking the ~/.claude/projects/<slug>/<session-id>.jsonl file.
  • Check the MCP server's forwarding logic to ensure it doesn't modify the received payload string.
  • Consider adding input validation or sanitization to remove any unwanted tags from the payload string before forwarding it to the downstream service.

Example

No code snippet is provided as the issue doesn't contain enough information about the parser's implementation.

Notes

The issue seems to be specific to the Claude Code terminal CLI and the MCP server's passthrough behavior. The fix may require modifications to the parser or the MCP server's logic.

Recommendation

Apply a workaround by adding input validation or sanitization to remove the unwanted tags from the payload string before forwarding it to the downstream service, as the root cause of the issue is likely related to the parser's logic and may require further investigation to fix.

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 MCP tool-call parser appends `</payload></invoke>` to string parameter values (100% repro within affected session) [1 comments, 2 participants]