MCP tasks extension and Sume job statuses: mapping for render tools
In MCP 2026-07-28 tasks are an extension polled with tasks/get. Map task handles, polling, update and list onto Sume job ids, status reads and jobs_cancel.

The MCP tasks extension and a Sume job solve the same problem, a call that outlives a request, and the concepts line up one to one. In 2026-07-28, experimental tasks moved to the official extension io.modelcontextprotocol/tasks: the blocking tasks/result is replaced by polling tasks/get plus tasks/update, tasks/list is removed, and a server may return a task handle unsolicited. The details are in the changelog, read 2026-10-03.
The mapping
The table pairs each task concept from the changelog with the closest Sume construct. Sume's docs do not say that its server implements the tasks extension, so read this as a design comparison and not as a compatibility claim.
| Task concept | Sume equivalent |
|---|---|
| Task handle returned by a tool call | Job id from the submit response |
| Poll tasks/get | jobs_status, jobs_get or GET /v1/jobs/:id/status |
| Blocking result call, now replaced | jobs_wait slices of at most 55 s, then jobs_result |
| Cancel or update a running task | jobs_cancel, with an idempotency_key |
| tasks/list, now removed | jobs_list, scoped to what the caller may read |
Where they differ
A Sume job has five statuses: queued, processing, completed, failed and canceled. The last three are terminal. queued is a normal accepted state and not an error, because workspace concurrency limits apply when a worker moves the job to processing.
Sume jobs are also owned. A job belongs to its workspace and to the member whose key or Agent turn created it, and only that member can cancel it. Another member's job returns 404 not_found from an API key. If you adopt tasks on your own server, decide the same ownership rule before you expose a list call.
Polling without waste
The Sume docs recommend exponential backoff and stopping on a terminal status. They also say not to resubmit the original paid request because a local process timed out. That advice carries over to task polling: the handle is the recovery path.
For a wave of renders, one batch wait is better than many single waits. jobs_wait accepts 1 to 20 ids and an optional wait_for of all or any, and with include_results: true it returns completed results in the same answer.
{
"job_ids": ["job_a", "job_b", "job_c"],
"wait_for": "all",
"timeout_seconds": 50,
"include_results": true
}What to take from it
Design the handle first. If your tool returns a stable, owned, durable id and every follow-up takes it, you can sit behind either a task wrapper or a plain job API and change your mind later. The id is what outlives the connection, whatever the protocol calls it.
Sources
Related posts
More in Developers
- MCP TS SDK 2.3 enforces one server per request: where state lives
TypeScript SDK 2.3.0 enforces one server instance per request. For a media tool that means job state belongs in job ids, as Sume's jobs_wait does.
- Next.js 16.3.8 dev-server MCP disclosure and where the Sume key lives
Next.js 16.3.8 fixes a low-severity dev-server MCP disclosure and a high-severity image SSRF. How to keep a Sume API key server-side as you upgrade.
- Next.js 16.3.8 fixes ISR cache poisoning: keep job pages dynamic
Next.js v16.3.8 fixes cache poisoning in SSG and ISR and Draft Mode leaks. Why a Sume job status page should stay dynamic and uncached, whatever the version.
- Which Node versions to test the Sume SDK on: 22, 24 and 26
Node 26.10.0 is Current, 24.21.0 and 22.23.3 are LTS. A small CI matrix and smoke test for code that calls the Sume API with fetch and WebCrypto.
Written by Sume