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.

5 min readSume
All posts

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.

script_run limits on hosted MCP (read 2026-10-02)
LimitDefaultCeiling or floor
timeout_seconds (whole run, tool calls included)455 to 55
max_calls3264
max_paid_calls1632
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 than max_calls. Raise it up to 64 or split the batch.
  • script_paid_budget_exceeded: more paid creates than max_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) and script_run itself 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

All Developers posts

Written by Sume