| name | mcp-tasks |
| description | Use when implementing, exposing, polling, testing, or debugging MCP task vocabulary, including creation, updates, cancellation, result retrieval, client headers, and SDK support boundaries. |
| version | 0.1.0 |
MCP Tasks
Experimental: Tasks are not part of the frozen MCP 2026-07-28 core. The current io.modelcontextprotocol/tasks extension lives in modelcontextprotocol/ext-tasks; recheck that draft before implementing it.
Tasks provide durable handles for long-running operations that must survive disconnects, expose progress, or pause for client input. Both peers explicitly opt in: the client includes io.modelcontextprotocol/tasks under this request's io.modelcontextprotocol/clientCapabilities.extensions, and the server advertises the same extension from server/discover.
Current experimental contract
A server may return resultType: "task" instead of the original operation's synchronous result. The task includes a unique taskId, status, ttlMs, and pollIntervalMs; create it durably before returning the handle. Status is working, input_required, completed, failed, or cancelled, and terminal states never change.
The current operations are:
tasks/get — return current state; include result when completed or error when failed.
tasks/update — accept inputResponses for outstanding inputRequests; acknowledge with an empty result.
tasks/cancel — acknowledge a cooperative cancellation request; the task may still finish in another terminal state.
notifications/tasks — optional full-state updates delivered through subscriptions/listen; polling remains the baseline.
Clients persist opaque task IDs, respect pollIntervalMs, validate every returned state, and continue until a terminal status. Servers authorize every operation on the task handle, enforce TTL, keep terminal transitions idempotent, ignore unknown or already-satisfied input keys, and store durable state outside the stateless HTTP transport.
Tasks vs MRTR
| Need | Use |
|---|
| Input needed before retrying one original operation | Core MRTR resultType: "input_required" and a retry with a new JSON-RPC ID |
| Durable long-running operation, polling, reconnect, or mid-flight input | Experimental Tasks resultType: "task" and tasks/get / tasks/update |
| Peer using the 2025 task vocabulary | Explicit legacy adapter; do not route those shapes into modern traffic |
MRTR input is carried by retrying the original request. Task input is returned from tasks/get while the task is input_required and answered through tasks/update. Never wrap MRTR in a task notification or make task creation look like a normal MRTR retry.
Legacy interoperability boundary
Retained TypeScript schemas may still name the older ttl, pollInterval, tasks/list, tasks/result, and notifications/tasks/status vocabulary. Use references/zod-2026.ts only as the exact retained legacy wire-shape fragment, not as a declaration of current extension support.
Support matrix
| SDK | Current position |
|---|
| TypeScript v2 | Core package retains legacy Task schemas but exposes no current Tasks runtime or typed handler maps |
| C# 2.0.0 | Separate experimental ModelContextProtocol.Extensions.Tasks package; WithTasks(IMcpTaskStore) |
| Python 2.0.0 | No released Tasks helper established here; implement only after verifying an installed extension API |
Test matrix
Exercise both capability directions: never return a task unless the current client request opts in, and advertise the extension only when every handler is installed. Test durable creation before response, polling intervals, reconnect, each terminal state, cancel races, TTL expiry, ownership isolation, completed results, failed errors, input request/update correlation, duplicate responses, and optional subscriptions/listen notifications. Test a legacy adapter separately from the experimental extension.