[FEATURE] Mods: structured fields for saved and backgrounded MCP results on $.tool.call / $.mcp.call

Status Open
Reported on v2.1.296
Maintainer reply None cached
Activity 0 comments · opened Oct 12, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

A mod that calls an MCP tool through $.tool.call or $.mcp.call can get a notice instead of the data, and nothing structured tells it so.

Two limits apply to these calls exactly as they do to the model's own calls:

| Case | What the mod gets |
|---|---|
| Result over MAX_MCP_OUTPUT_TOKENS | result is the string "Error: result (1,000,000 characters across 1 line) exceeds maximum allowed tokens. Output has been saved to …/tool-results/mcp-….txt …", isError false |
| Call still running after CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS (120 s) | result is [{ type: 'text', text: 'MCP tool "…" is still running after 120s. It was moved to the background as task k4kfzxe4i …' }], isError false |

Both resolve as success. The only way to find the saved file or the task id is to parse the notice wording, which can change in any release. The later task notification also carries the task id only in its text.

These limits protect the model's context. A mod's result does not go into the context, so here they protect nothing, and the mod cannot recover the data.

Bash already has the structured version. A nested Bash call returns persistedOutputPath and persistedOutputSize when its output was saved, and backgroundTaskId when it runs in the background. A mod can read the saved file and give its caller the full output without reading any message text.

Proposed Solution

On the result $.tool.call and $.mcp.call resolve for an MCP tool, set the same fields Bash has:

  • persistedOutputPath and persistedOutputSize when the result was saved to the tool-results directory instead of returned.
  • backgroundTaskId when the call was moved to a background task, and a way for a mod to wait for or read that task by id.

Alternative Solutions

A per-call option on $.tool.call / $.mcp.call that skips both limits for the mod's own call, for example { background: false, maxResultSizeChars }. The limits would then apply only when a result is written into the conversation.

Tried and ruled out:

  • _meta["anthropic/maxResultSizeChars"] works only when the MCP server sets it on its own tools. A mod calling third-party servers cannot set it. Setting it on the mod's own tool does not carry over to the MCP calls that tool makes.
  • CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS=0 turns off backgrounding for the whole session, including the model's own calls.
  • MCP progress notifications do not delay the 120 s move.

Priority

Medium - Would be very helpful

Feature Category

Developer tools/SDK

Use Case Example

A mod gives the model one run tool that executes a short script, and the script calls session tools: for example, one log search per service, then filtering the results. Only the filtered result goes back to the model. When one search returns a large result, the script gets the "saved to file" notice in place of the data. When a search is slow, it gets the "moved to the background" notice. In both cases the mod can tell the script only by matching message text.

Additional Context

Observed on Claude Code 2.1.296 with a stub stdio MCP server, through both $.tool.call and $.mcp.call.

View original on GitHub ↗