script_run budgets: call, paid-call and timeout limits on MCP
script_run caps a Sume MCP program by timeout (5-55 s), max_calls and max_paid_calls, and stops with a named error code. Defaults, ceilings and what to do next.

script_run on Sume's hosted MCP bounds every program with a wall-clock timeout_seconds (5 to 55, default 45), a max_calls budget (default 32, ceiling 64) and a max_paid_calls budget (default 16, ceiling 32). Go past one and the run ends with a named error such as script_paid_budget_exceeded, while the calls[] journal and jobs[] list still tell you exactly what already ran.
Our overview of programmatic tool calling explains what the tool is. This post is the limits reference: the numbers, the error codes, and the order to read them in when a batch stops early.
What are the script_run limits?
The numbers below come from the tool contract in the Sume repository (packages/mcp-server/src/script-run-tool.ts and its agent-facing description), and the tools and gates page documents the same timeout and budget parameters. Numeric inputs are clamped into their ceilings instead of rejected, so a script that asks for 120 seconds still runs, inside the request budget.
| Limit | Default | Ceiling or floor |
|---|---|---|
| timeout_seconds (whole run, tool calls included) | 45 | 5 to 55 |
| max_calls | 32 | 64 |
| max_paid_calls | 16 | 32 |
| Script size | - | 64 KB |
| args size | - | 64 KB |
| Calls in flight / call starts per second | - | 4 / 8 |
| Guest memory | - | 64 MB |
Which error code means what?
A budget stop ends the run with error.code set to one of four values, and ok is false. Read the code first, then calls[], then jobs[].
script_timeout: the wall clock ran out. Submit the creates, return the job ids, and do the waiting outside the script.script_call_budget_exceeded: more tool calls thanmax_calls. Raise it up to 64 or split the batch.script_paid_budget_exceeded: more paid creates thanmax_paid_calls. Raise it up to 32, or run a second script.script_tool_forbidden: the script called a tool that cannot run inside one. Discovery tools (tools_list,tools_schema,mcp_health) andscript_runitself are refused.
What counts as a paid call, and what stays safe?
A paid create inside a script behaves like a direct call: the same gates, redaction and errors, and its own idempotency_key. The agent-facing description suggests building distinct keys from the loop index, for example "tts-" + i. If the same script is re-run after a stop, reusing the same keys means calls that already registered a job replay their original receipt instead of billing again.
The response carries a script_run_id, and every child job's ledger row carries it too, so usage_get can say what the script cost. Treat the tally in tools[] (calls per tool and model) as the quick read, because the transcript row keeps a bounded preview of the JSON.
How do you size a batch that is bigger than one script?
Do the arithmetic on the ceilings. At 32 paid calls per script, 100 scene images means four scripts at least, each with its own distinct key range. A script is also bounded by one HTTP request, so the pattern is to submit creates in the script, return the child job ids, and wait outside it: jobs_wait takes up to 20 ids per call and holds at most 55 seconds (Jobs and results).
Inside a script, sume.jobs.wait is clamped to the time the script has left minus a short margin, so a wait cannot outlive the run. Here is a dry-run loop that previews several avatar creates in one call; it follows the payload shape in the docs' avatar playbook.
const out = [];
for (const [i, prompt] of args.prompts.entries()) {
try {
out.push(await sume.call("avatars_create", {
idempotency_key: "avatar-preview-" + args.batch + "-" + i,
dry_run: true,
max_spend_usd: 2,
payload: {
avatar_handle: "presenter_" + i,
input: { type: "prompt", prompt },
},
}));
} catch (e) {
out.push({ i, code: e.code, message: e.message });
}
}
return out;When should you not use script_run?
For one or two calls, call the tools directly; the description says script_run pays off at three or more independent calls of the same shape. It also does not replace judgment about spend: max_spend_usd is enforced only when you pass it inside each call, and there is no mcp:paid scope, so under an API key a script can spend wallet credit up to its paid-call budget. A failed call throws SumeToolError, which you can catch to retry or skip; uncaught, it fails the run, with the journal intact.
Sources
Related posts
More in Developers
- Seedance 2.5 first frame plus references in one request: 400
On Sume's Video Router, image_url plus reference_*_urls returns 400 for seedance-2.5. Pick image-to-video or reference-to-video; /v1/videos lets frames win.
- Seedance 2.5 references: input_references or reference_image_urls?
POST /v1/videos takes frame_images and input_references for seedance-2.5; the Video Router takes image_url and reference_*_urls. The wrong shape gets 400.
- Seedance 2.5 reference audio alone returns 400: add an image
On Sume's Video Router, reference_audio_urls with no reference image or video returns 400. Pair the audio with an image or clip, within 3 audio and 12 total.
- Seedance 2.5 seed, size and provider options: why Sume returns 400
Sume rejects seed, size and non-empty provider.options on seedance-2.5 with 400 instead of dropping them. What to send to repeat a clip or fix the frame size.
Written by Sume