Claude Code 2.1.288: MCP call ran twice on a 16 MB result

Claude Code 2.1.288 fixed MCP tool calls that ran twice when a result passed 16 MB or would not parse. Sume caps output at 256 KiB and keys paid calls.

5 min readSume
All posts

Can a Claude Code MCP call run twice against Sume and bill twice? On 2.1.288 the specific double-run bug for oversized results is fixed, and Sume's hosted MCP never returns anywhere near that size: it replaces any tool output above 256 KiB with a mcp_output_too_large error. Paid creates also carry an idempotency_key, so a repeat with the same key is a retry, not a second charge.

What did 2.1.288 fix?

The Claude Code changelog (read 2026-10-03) lists under version 2.1.288, dated October 2, 2026: "Fixed MCP tool calls sometimes running twice when a remote server's result was over 16 MB or could not be parsed". Two triggers are named: a result over 16 MB, and a result that could not be parsed.

Version 2.1.287 had already fixed a related double-run when a connector's server changed which protocol version it supports. See the related posts for that one.

How big can a Sume hosted MCP result be?

Sume's server checks the serialized text of a tool result against a 256 KiB budget (MCP_OUTPUT_MAX_BYTES, 256 * 1024 in packages/mcp-server/src/output-budget.ts). Over the budget, the tool returns an error result with code mcp_output_too_large, max_bytes, and a note that it is an output limit, not a job failure, and that a paid create must never be resubmitted.

jobs_wait with inline results has its own, lower budget of 160 KiB in the repo. Sume tools return ids and media.sume.com URLs rather than file bytes, so a normal generation result is a few kilobytes.

Size limits that touch a Sume call (read 2026-10-03)
LimitValueWhere
Claude Code double-run fixResults over 16 MBClaude Code 2.1.288 changelog
Sume tool output budget256 KiBpackages/mcp-server output-budget.ts
Sume jobs_wait inline results160 KiBpackages/mcp-server jobs-wait.ts

What stops a repeated call from billing twice?

Per Sume's tools and gates, every write and paid tool requires an idempotency_key, described as a stable key for transport and dedup. If a client re-sends the same call, reuse of that key is what makes it a retry. Generate one key per intended job, not per attempt.

A client that loses the response should look before it resubmits. jobs_list and jobs_status are read-only and show whether the first call created a job; the jobs and results page covers the same rule for the HTTP API.

{
  "idempotency_key": "hero-shot-2026-10-03-001",
  "dry_run": true,
  "max_spend_usd": 1
}
// Same key on every retry of this one job. A new job gets a new key.

What should I do on Claude Code before 2.1.288?

Update. If you cannot, keep results small, which Sume already does, keep idempotency_key stable across retries, and check jobs_list after any call that errored or hung before sending the create again. Sume does not de-duplicate calls that use different keys, so two keys mean two jobs.

Where do big results come from, and how do I keep Sume's small?

Sume's tools are built to return references. A completed image or video job returns an id and a media.sume.com URL; the bytes never travel through the MCP channel. Uploads go the other way: assets_upload_url returns a URL, your client PUTs the bytes there, and assets_complete finishes it. Hosted MCP cannot read files from your laptop, per the tools page.

The places a result can grow are list reads and batched waits. Ask jobs_list for a narrow window, and call jobs_result on the same group of ids instead of one call per id. If you see mcp_output_too_large, narrow the read. Do not resubmit the create: the error text itself says it is an output limit, not a job failure.

None of this removes the need to update Claude Code. A different MCP server in the same session can still return a huge result, and the 2.1.288 fix protects calls to that server too.

Which retry habits keep a paid Sume call safe?

Three habits cover almost every double-run scare. Mint the idempotency_key once, when you decide to create the thing, and store it with the task, not inside the retry loop. Before any resend after a timeout or a parse error, read state with jobs_list or jobs_status, because the first call may have created a job even though the client never saw the answer. And when a long job is simply not finished, repeat jobs_wait on the same job id; a timed-out wait is not a failed job.

The Sume docs add one more rule worth copying into agent instructions: a tool call that errors or times out is that one call failing. Retry it once, report that tool's error, and do not describe the whole server as down. That keeps a single bad response from turning into a cascade of fresh creates.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume