Two-second tool call? Return the result. But try that with a report that takes ten minutes to build. A dropped connection leaves the client wondering whether the job finished, failed, or is still running somewhere.
MCP Tasks give that work a durable handle. The server can accept a tool call, return a task ID, and let the client come back for the result. Tasks are an optional extension to the Model Context Protocol, not the default behavior of every MCP server.
The core idea
An MCP task is a job ticket for a tool call. The server returns a taskId and a status instead of making the client wait for the result in the first response. Save the ID. Check on the job later.
That works for a codebase index or an export whose duration is hard to predict. It does not turn the tool into a scheduler. The client has to poll, respond if the job asks for input, and decide what to do with the result.
How MCP Tasks work
In the 2026-07-28 protocol, Tasks live in the io.modelcontextprotocol/tasks extension. Both sides advertise support. The client includes that capability with the request; the server decides whether a particular tools/call returns a regular result or a task handle. Currently, tool calls are the supported request type for task-augmented execution. A server must not return a task handle to a client that did not declare support on that request.
A task response is marked resultType: "task". It carries a server-generated taskId, a status such as working, timestamps, a time-to-live value, and possibly a recommended pollIntervalMs. The server must make the task retrievable before returning its handle, so an immediate tasks/get does not race task creation.
The client then calls tasks/get with that ID. If the task is still working, it waits before polling again, respecting the server’s suggested interval. If the task is completed, the response includes the result the original tool call would have returned. A failed task instead carries a JSON-RPC error. An operation-level tool error with isError: true can still appear inside a completed task: the transport completed, even though the tool reported a problem.
A task can also reach input_required. In that case tasks/get exposes outstanding inputRequests, and the client returns answers using tasks/update. This is different from retrying the original tool call. For cancellation, the client sends tasks/cancel; the acknowledgement does not promise that the underlying work has stopped. Cancellation is cooperative, and work may finish before the server acts on the request.
Why it matters for AI agents
The practical win is recovery after a disconnect. Persist the task ID and a restarted client can ask what happened instead of submitting the same job twice. A server can put the work on a queue or move it between workers, as long as tasks/get can still find the state. Remote servers in particular have to contend with proxy timeouts.
The statuses help the UI tell the truth, too. working: wait. input_required: someone needs to answer. completed: read the result. A spinner cannot tell a developer which of those is happening.
The handle is durable only as long as the server keeps the task. Pick a realistic retention period and expect IDs to expire after their TTL. Check authorization on every lookup and update; an ID alone must not let one user read another user’s job. Clients need to protect the IDs they save.
MCP Tasks in practice
Say a server exposes generate_monthly_report. A small account gets the report in the first response. A larger one gets a task handle, which the client saves before polling tasks/get at the suggested interval. Same tool, different return path.
Suppose the report then needs a billing region. The task moves to input_required; the client asks the user and sends the answer with tasks/update. After completed, it reads the report from the task result. If the user cancels instead, a tasks/cancel acknowledgement is not proof the export stopped. Check the task state.
This is separate from MCP progress notifications. A notification can describe progress during an active exchange; a task handle gives the client a retrievable job with its own lifecycle. It is also different from multi round-trip requests, which can request input before a task is created.
FAQ
Does every MCP tool call create a task?
No. A server that supports Tasks can still return a normal result. Task creation is the server’s decision for each supported request, and the client must handle either shape.
Can a client request a task for any MCP method?
Not in the current extension. Task-augmented execution currently supports tools/call. Other methods may be added in future revisions.
Is a task ID enough to authorize access to a result?
No. Servers need to check authentication and authorization on each task-related request. An opaque ID is a lookup key, not a substitute for access control.
Are Tasks in the core MCP specification?
No. Tasks were experimental in the older 2025-11-25 protocol and moved into an optional extension for 2026-07-28. The earlier task flow is not wire-compatible with the extension. Check which protocol version your client and server support before implementing it.
Source: MCP Tasks extension specification.