jobs_cancel on Sume MCP: Write scope, idempotency_key, early moment

jobs_cancel is a write tool marked destructive. It needs the mcp:write scope or an API key, an idempotency_key, and a job that has not started generating.

5 min readSume
All posts

jobs_cancel on Sume's hosted MCP server has three conditions. The session must be able to write, meaning an OAuth grant with mcp:write or an API key. The call must carry an idempotency_key. And the job must not have started generation, because after that the API returns 409 job_generation_already_started with details.cancelable: false. The tool is also marked destructive in its annotations, which lets a client show a stronger confirmation than for a read.

That is why a read-only OAuth session cannot cancel anything: the tool is not even listed, and a direct call returns insufficient_scope.

A fast way to see where you stand is mcp_health, which reports the auth source, and tools_list, which lists jobs_cancel only for sessions that can write. If you do not see it, the session is read-only, and the cure is the consent toggle or an API key.

Where the tool sits

Cancel is the only job tool that changes state. The other job tools read: jobs_list, jobs_get, jobs_status, jobs_result, jobs_events and jobs_wait.

The ownership row matters for teams. A job belongs to its workspace and to the member whose key or Agent turn created it, and only that member can cancel it. A teammate who can read a job in a shared thread still cannot cancel it unless they are the member who made it.

jobs_cancel requirements on hosted Sume MCP (read 2026-10-05)
RequirementDetailIf missing
Write accessmcp:write grant or API keyinsufficient_scope
idempotency_keyRequired, a stable stringCall is rejected
Job stateBefore generation starts409 job_generation_already_started
OwnershipOnly the member who created the jobThe job is not visible to you

The window is the queue

Queued is a normal accepted state, and workspace concurrency limits apply when workers move jobs into processing. So the window in which a cancel works is the time a job spends queued. A long queue gives you a long window; an empty queue gives you almost none.

Because the window is tied to the queue, an agent that wants to be able to cancel should check the queue state before it submits. generation_admission_preview shows the queue and balance behavior ahead of a paid call, and a dry run shows the estimate without making a job at all, which is the cleanest cancel of all.

Safe to repeat

A cancel of a job that is already canceled is idempotent and returns the same canceled job. That makes the idempotency key a real safety net: if the connection drops after you send a cancel, send the same call with the same key and the answer is the same.

Repeat the call after a network error with the same key. Do not generate a new key for a retry, because a new key looks like a new intent. For a different job, use a different key.

A cancel request has the same shape as other write calls. The job id goes in job_id, next to the key.

Add a clear comment in your own tooling about what the key is for. A good pattern is the action, the job id and the date, as in the example, so a person reading logs can tell what a retry was meant to do.

{
  "job_id": "job_123",
  "idempotency_key": "cancel-job-123-2026-10-05"
}

After a 409

After a 409, do not retry the cancel. The job will run to completion, and the money is spent. The right next step is to wait for the result with jobs_wait, read it with jobs_result, and decide whether to use it. If the reason to cancel was a wrong prompt, wait for the output and make a new request with a fixed one, with its own key.

For the scope side, see MCP OAuth and API keys. The full cancel semantics are on Jobs and results.

If the job is already running, your options are to wait for it, to use the result, or to let it expire from your attention. There is no call that stops a started generation, and Sume does not hide that: the docs say the job runs to completion.

Sources

Related posts

More in Agents

All Agents posts

Written by Sume