KEY TAKEAWAYS

  • The reviewed extension uses completed even for a tool result with isError: true; the legacy document places that case in failed. Inspect the output, not just status.[1][4]
  • A received, saved handle supports follow-up while state remains retained and accessible. A lost initial handle or expired record needs a separate recovery decision.[1][4]
  • Legacy cancelled confirms a required task-state transition, not stopped execution. The extension cancellation acknowledgment guarantees neither.[1][4]

The same status can mean a different outcome

Suppose an expensive agent tool reports a completed task, but its result says isError: true. The reviewed 2026-07-28 extension requires completed for that tool-error case; failed is reserved for JSON-RPC execution errors.[4] The 2025-11-25 Tasks document instead says it should reach failed.[1] This example comes from the documents, not a tool we ran.

A small team migrating a polling adapter must identify the exact client/server contract, retrieve its result and inspect the contents. Keeping the same status test can misclassify the output. Tasks provide deferred retrieval; our conclusion is that a handle alone does not establish application acceptance or make repeating the original operation safe.

The result path changes too. Legacy tasks/get reports state; tasks/result retrieves what the underlying request would have returned.[1] The pinned extension puts a completed result or failed error directly into tasks/get.[4][5] A polling adapter must follow the chosen contract.

Identify the era before interpreting the handle

The 2025-11-25 lifecycle begins with initialize, version agreement and capability exchange.[2] Its Tasks document calls the feature experimental.[1] The 2026-07-28 Versioning and Compatibility document calls that handshake era legacy; modern requests carry version and capabilities individually.[3] A recognized modern version error calls for selecting a supported version, not automatically falling back to initialize.[3]

Legacy task creation is requestor-directed, subject to declared capabilities and the tool's execution.taskSupport: required, optional or forbidden.[1] In the reviewed extension, the client declares io.modelcontextprotocol/tasks on each request; the server chooses a task or normal result. The supported-method list contains only tools/call.[4] A shared method name does not establish identical behavior.

Documented contracts, not tested compatibility. The extension column uses the pinned 2026-07-28 spec and schema.
Question2025-11-25 TasksPinned 2026-07-28 extension
Who chooses task creation?Requestor augments an eligible request, respecting negotiated capabilities and tool-level taskSupport.[1]Client opts into the extension per request; server chooses task or direct result.[4]
Where is final output?tasks/result returns the underlying result/error; tasks/get provides state.[1]tasks/get carries result for completed or error for failed.[4][5]
What if the tool returns isError: true?Document says the task should reach failed.[1]Task uses completed with the tool error inside result; failed must not represent that case.[4]
What happens at input_required?Requestor should call tasks/result to receive required messages.[1]tasks/get exposes inputRequests; client replies with inputResponses through tasks/update.[4]
How is retention expressed?Requestor may request ttl; receiver may override it and returns actual ttl, or null.[1]ttlMs is returned task metadata, may change; this creation contract defines no requested-ttl parameter.[4][5]
What does successful cancellation establish?Receiver must set cancelled before responding, even if execution continues.[1]Intent acknowledged; neither stopped work nor eventual cancelled is guaranteed.[4]
Can the client list tasks?tasks/list is conditional on declared support and access controls.[1]No tasks/list in this extension.[4]

What a saved handle supports

The extension imposes a useful creation requirement: a server MUST NOT return CreateTaskResult until the task is durably created, defined here as a tasks/get for that ID being able to resolve. It must wait for consistency before responding.[4] A compliant server cannot return a handle before its state becomes queryable. This is a specific protocol requirement, not proof of server-restart survival.

Clients SHOULD save received IDs to durable storage so polling can resume after a crash or restart.[4] Follow-up still depends on retained state and authorized access. Over Streamable HTTP, tasks/get, tasks/update and tasks/cancel must set Mcp-Name to the task ID, allowing routing to the instance holding state.[4] That routing requirement does not establish recovery after the instance is lost.

Time to live (TTL) limits retrieval. Legacy receivers may override requested ttl and delete tasks and results after expiry regardless of status; cancelled tasks can disappear immediately.[1] Extension ttlMs runs from creation and may change; expiry permits failure and deletion, including a compliant not-found response after purging.[4][5] Use effective retention rather than a requested lifetime. A null TTL means unlimited TTL, not protection against storage loss.

Legacy notifications/tasks/status is optional: requestors MUST NOT rely on it and should continue polling.[1] The extension offers notifications/tasks through subscriptions/listen for acknowledged task IDs; clients may poll alongside it but need not.[4] Neither the legacy polling rule nor a notification-replay guarantee should be assumed for the newer mechanism.

For input during execution, extension inputRequests keys must be unique over the task's lifetime; clients SHOULD deduplicate repeated keys across polls. A tasks/update acknowledgment may precede a visible state change.[4] Key uniqueness removes response ambiguity, and deduplication helps avoid repeated input presentation. Neither makes a second tools/call the same business operation.

Three interruptions that need different answers

Consider a hypothetical, unexecuted interruption: a client sends an expensive tool call; the server may begin work; the handle response is lost. The operator must decide whether to submit again. That differs from disconnecting after saving the handle or returning after retention expires.

Our interpretation of hypothetical interruption cases; no recovery outcome was measured.
InterruptionWhat the documents supplyDecision still required
Received handle was saved; client disconnectedExtension creation barrier plus durable-ID guidance supports later polling, subject to retained accessible state.[4]Use the existing handle when the exact implementation supports it; inspect result/error and application acceptance.
Initial handle response was lostLegacy optional listing may help only where supported; the extension has no tasks/list.[1][4]Find authorized evidence correlating the original call with the external operation before automatically repeating consequential work.
Known task can no longer be retrieved after expiryBoth contracts permit loss of retrieval after expiry.[1][4]Treat execution outcome as unresolved; not-found is not evidence that the operation never ran.

Legacy listing is optional and access-scoped; the documented list does not itself uniquely correlate a task with a lost original call.[1] The complete extension spec and task schema define neither general lost-ID enumeration nor an original-call idempotency key.[4][5] A particular implementation may supply a separate job lookup or reconciliation API; we did not establish one.

Legacy Streamable HTTP says disconnect should not imply request cancellation and permits optional resumable server-sent events (SSE).[8] The 2026-07-28 HTTP document treats closing an SSE response stream as cancellation of that request and does not support Last-Event-ID resumption.[9] The Tasks extension separately requires tasks/cancel for task cancellation.[4] A broken stream therefore cannot settle the outcome of the request, retained task and external job together.

A request ID correlates messages; a task ID identifies retained task state. Our proposed application operation record would track the intended external action and reconciliation evidence. These identifiers are not interchangeable duplicate-prevention guarantees. The imported core schema also warns that ToolAnnotations, including idempotentHint, are hints rather than guaranteed descriptions of behavior.[10]

Cancellation is not compensation

Legacy tasks/cancel requires cancelled state before responding to a valid request. The task must remain cancelled even if execution continues to completion or fails.[1] A compliant cancelled response therefore establishes the state transition, not that work stopped.

Extension cancellation is cooperative. Success acknowledges intent; status may remain working, and the server need not stop work or eventually reach cancelled.[4] Its resultType: complete identifies the cancellation RPC's standard result shape, not completion of the underlying task.[4][5]

In a hypothetical, unexecuted case where a tool already sent a message, neither cancellation contract supplies reversal of that earlier effect.[1][4] The application would still need evidence about the external action. We recommend keeping task cancellation separate from any reconciliation or compensation it requires.

Use Tasks for follow-up; add reconciliation when loss matters

Tasks can be sufficient for bounded follow-up when the exact client/server pair implements the chosen era, the received handle is saved, retention covers the workflow, and result/error and input handling fit the application. The extension's queryable-before-response requirement supports that choice.[4] Asynchronous execution alone is not a reason to build a new job service.

Conditional decision guidance, not a tested architecture or adoption ranking.
RequirementReasonable next choice
A retained result is useful; missing or repeated work has limited consequencesUse supported Tasks as the follow-up mechanism, preserving handles and inspecting outputs. Do not add infrastructure solely because execution is asynchronous.
Losing the initial response or repeating an external effect is costlyRequire an application/provider operation record and a documented, authorized reconciliation or idempotency mechanism before relying on automatic resubmission.
Server-restart survival, failover or strict cancellation is mandatorySeek evidence for that exact implementation and workload. This documentary comparison does not establish those outcomes.
Client/server era, task support or retention is unknownKeep automatic recovery unresolved; establish the missing contract rather than treating a task ID as sufficient evidence.

Consequential recovery needs implementation-specific evidence. Documentation and, where separately authorized, observed loss/restart/reconciliation behavior could resolve the missing requirements. This comparison demonstrates no recovery success, exactly-once effects, uptime, latency, savings or adoption; it separates deferred retrieval from recovery assurance.

Method, revision and source limits

We compared selected primary documents, not a statistical sample or market census: complete legacy Tasks/lifecycle, modern Versioning and Compatibility, and the full dated extension spec and task schema, with relevant transport and annotation passages. Their requirements and publisher explanations inform our decision guidance; they are not observed implementation behavior.

The modern Tasks path redirected to the extension overview; we recovered the actual specification through its linked official repository.[6][7] The repository labels the 2026-07-28 schema Stable and draft Development.[7] Our analysis uses commit 5246bc3d0253c1c4b09e682f690b7e8b97362500, not a claim that these are the original July bytes.[4][5]

The pinned documents have inconsistencies: creation prose refers to an embedded task, while its type/example and schema define a flat handle. Some tasks/get error examples use resultType: task, while the response rule and schema require complete.[4][5] We use the explicit rules and schema, provide no copy-and-run recipe, and do not infer a deployed defect from these discrepancies.

Sources were checked on 5 October 2026 KST; page publication/update dates were not established. Edition and retrieval dates are not launch or rollout dates. All sources belong to the MCP publisher family, not independent empirical confirmation. No credentials, protected API calls or external actions were involved. Actual implementation support, retention limits and restart/failover behavior remain unknown.

Sources & scope

Documentary comparison checked 5 October 2026 KST: Model Context Protocol (MCP) 2025-11-25 Tasks/lifecycle versus 2026-07-28 compatibility and the Tasks extension spec/schema at ext-tasks commit 5246bc3d0253c1c4b09e682f690b7e8b97362500. No client/server, SDK, restart or recovery experiment was run. Examples are hypothetical and unexecuted; edition labels are not launch dates.

  1. MCP 2025-11-25: Tasks ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  2. MCP 2025-11-25: Lifecycle ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  3. MCP 2026-07-28: Versioning and Compatibility ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  4. Tasks extension: 2026-07-28 specification, pinned revision ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established. Pinned to ext-tasks commit 5246bc3d0253c1c4b09e682f690b7e8b97362500; not a runtime or adoption finding.

  5. Tasks extension: 2026-07-28 task schema, pinned revision ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established. Pinned to ext-tasks commit 5246bc3d0253c1c4b09e682f690b7e8b97362500; not a runtime or adoption finding.

  6. MCP Tasks extension overview ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  7. Official ext-tasks repository README, pinned revision ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established. Pinned to ext-tasks commit 5246bc3d0253c1c4b09e682f690b7e8b97362500; not a runtime or adoption finding.

  8. MCP 2025-11-25: Transports ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  9. MCP 2026-07-28: Streamable HTTP ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established.

  10. Imported core schema: ToolAnnotations, pinned revision ↗

    Official primary source; checked 5 October 2026 KST. Publication/update date not established. Pinned to ext-tasks commit 5246bc3d0253c1c4b09e682f690b7e8b97362500; not a runtime or adoption finding.

Publication history
  • — Initial documentary comparison, edited for clarity and normative precision. Prepared edition timestamp; actual release requires separate activation evidence.

Have a correction or a different perspective? Contact Palanthos.