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.

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.
| Requirement | Detail | If missing |
|---|---|---|
| Write access | mcp:write grant or API key | insufficient_scope |
| idempotency_key | Required, a stable string | Call is rejected |
| Job state | Before generation starts | 409 job_generation_already_started |
| Ownership | Only the member who created the job | The 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
- Sume jobs_wait with 20 ids: one unknown id fails the whole call
A batch jobs_wait takes 1 to 20 ids. One unknown or foreign-workspace id makes the full call fail, so validate ids with jobs_list or jobs_status first.
- jobs_wait returned early during a deploy: retry the same job ids
A Sume MCP jobs_wait can return before its 50 second slice when the API host is draining for a deploy. The job is fine: call jobs_wait again on the same ids.
- jobs_wait with timeout_seconds 0: a single status snapshot on Sume MCP
Sume's jobs_wait accepts timeout_seconds 0 to 600 (clamped to 55) and interval_seconds 1 to 60. A value of 0 reads the status once and returns right away.
- poll_after_seconds in Sume MCP results: where the 5 comes from
Sume MCP jobs_status and jobs_wait results add poll_after_seconds for running jobs: the API's own interval, else 5. It is null once the job is terminal.
Written by Sume