Verdict: MCP Tasks — the Model Context Protocol's mechanism for long-running, durable agent tool calls — shipped in November 2025 as an experimental primitive, and not a single major agent framework implemented it. The reason was rational: the V1 wire protocol was stateful, required long-lived connections for human-in-the-loop input, and demanded complex client-side orchestration machinery that no team wanted to build. The July 2026 V2 redesign (MCP spec revision 2026-07-28) goes stateless, deletes the problematic endpoints, and turns Tasks into an independently versioned extension — making it substantially easier to implement. If you build AI agents or MCP servers, this redesign removes the main excuse for staying synchronous-only.
Last verified: 2026-08-03 TL;DR:
- MCP Tasks add a "call-now, fetch-later" pattern so agents can invoke tools that take minutes or hours without blocking.
- V1 (Nov 2025, experimental, SEP-1686) was stateful, required long-lived sessions, and had an unfiltered
tasks/listendpoint that broke at scale — zero agent frameworks adopted it.- V2 (July 2026, SEP-2663) moves to a stateless core, makes Tasks an extension, removes
tasks/list, replaces session-based input with client-initiated signals, and keeps the task lifecycle unchanged.- Still unsolved: at million-task scale, polling overhead remains; the spec's notifications protocol may fix this but isn't fully implemented.
- Pricing/spec status: Tasks remain experimental but are now in an extension that versions independently of the core protocol. A FastMCP reference implementation is expected within 1–2 months (~Sep–Oct 2026).
- Volatile facts: Protocol details may shift. Pin to
2025-11-25for now; read migration notes before building against the2026-07-28release candidate.
What Are MCP Tasks?
MCP Tasks are a protocol-level primitive that lets an MCP client (an AI agent) invoke a tool and get back a durable task handle instead of waiting for a synchronous response. The agent can then poll for status, retrieve results later, send signals into the running task (like human approval), and recover from disconnections without losing the work.
Before Tasks, MCP was effectively a request-response protocol: a client calls tools/call, waits, and receives the result. That model breaks when the work takes longer than the transport timeout — think a 30-minute ETL job, a multi-step invoice approval, or anything involving a human-in-the-loop step where the human might go on vacation for a week.
The MCP Tasks spec (2025-11-25) describes tasks as "durable state machines that carry information about the underlying execution state of the request they wrap." Each task has a unique, server-generated task ID that the client holds onto. The task's lifecycle flows through defined states:
| State | Meaning |
|---|---|
working |
The task is actively executing |
input_required |
The task is paused, waiting for external input (human approval, data) |
completed |
The task finished successfully |
failed |
The task encountered an error |
canceled |
The task was explicitly cancelled |
This lifecycle is the same in both V1 and V2 — it's one of the few things that didn't change.
Why Did No Agent Framework Implement V1?
The experimental status was part of it — teams rationally wait on experimental specs. But the deeper reason was architectural: V1 was a stateful protocol that was extremely expensive to implement correctly on the client side.
Problem 1: The Stateful tasks/list Endpoint
V1 included a tasks/list RPC endpoint that let a client ask the server, "What tasks do you have?" This was the recovery mechanism — if your client disconnected, the human took too long, or the network dropped, you could reconnect and rediscover your in-flight tasks.
That works with two tasks. It even works with ten. But there was no filter on the endpoint — no way to say "only show me tasks for my user" or "only tasks created in the last hour." At a server with a million concurrent tasks, you'd have to page through the entire unfiltered list to find the one you wanted. In large-scale distributed systems, this is a non-starter.
Problem 2: Long-Lived Connections for Human-in-the-Loop
When a task entered the input_required state, the V1 protocol handled this through the tasks/result endpoint, which kept a long-running connection open and had the server elicit a response from the client through that session. This is effectively a server-initiated callback over a living connection.
This creates a cascade of engineering problems:
- Connection death: If the connection drops mid-session, how do you pick up where you left off?
- Client complexity: The client needs a protocol handler that manages long-lived connections, handles elicitation, tracks state, and recovers from failures — essentially building a workflow engine just to participate in the protocol.
- FIFO bottleneck: The reference implementation serialized
input_requiredtasks in FIFO order on the client side. If you had five tasks waiting for approval, you could only respond to the first one. The rest were stuck until you cleared the queue.
Problem 3: Durability Burden on the Client
The MCP Tasks spec mandates durability — once a task is launched, it "can't disappear." It must survive server restarts, client crashes, network blips, and human delays. In V1, the server held the task list and ran the elicitation session, so the server bore most of the durability burden — but the client still had to build significant machinery to manage the long-running connections, handle reconnection, and orchestrate elicitation responses.
The net result: implementing V1 Tasks on the client side meant building a durable workflow engine that handles session management, long-lived connections, elicitation protocols, FIFO queuing, and failure recovery. Every agent framework team looked at this and said: not yet.
How MCP Tasks V2 Fixes the Problems
In May 2026, Angie Jones — VP of Developer Experience at the Agentic AI Foundation, the Linux Foundation-backed organization that now houses MCP — published the announcement that the protocol was going stateless. This triggered the V2 redesign, which shipped as part of the 2026-07-28 spec release candidate.
Change 1: The Protocol Goes Stateless
V2 removes the initialize/initialized handshake, removes the Mcp-Session-Id header, and makes every request self-contained. Client information travels in _meta fields on each request, so any server instance can handle any request — no sticky sessions required.
For Tasks, this means the stateful session machinery that made V1 so hard to implement is gone. The protocol is now closer to simple HTTP request-response than to a stateful RPC with sessions.
Change 2: tasks/list Is Removed
The unfiltered, unscalable tasks/list endpoint is deleted entirely. Instead, the spec now says clients should persist task IDs themselves — the client is the only place a task ID survives after disconnection.
This is the trade-off hidden in the stateless redesign: statelessness shifts the durability burden from the server to the client. A server that no longer tracks its tasks can only be recovered by clients that remember their own. The spec uses "should" language, but notes that "if you don't persist task IDs, there is no way to get it back" — a gap that many have flagged as needing a "MUST" rather than a "SHOULD."
Change 3: Session-Based Input Replaced With Client-Initiated Signals
The long-lived session for input_required is replaced with a client-initiated update endpoint. When a task is waiting for input, the client sends an update (an approval, additional data, a cancellation) as a simple request — no long-lived connection needed.
This is functionally equivalent to a "signal" in durable workflow engines like Temporal: a way to push data into a running process without holding a connection open. The client no longer needs to maintain a session handler; it just sends a request when it has something to contribute.
Change 4: Tasks Becomes an Extension
Tasks moves out of the monolithic core spec and into an independently versioned extension (io.modelcontextprotocol/tasks). This is part of a broader restructuring where MCP splits into a stateless core plus extensions — the same pattern used for MCP Apps, the interactive UI extension.
The practical benefit: Tasks can now evolve without waiting for a full core spec revision. If the task lifecycle semantics need adjustment, the extension versions independently — no coupling to the core protocol's release schedule.
V1 vs V2 Comparison
| Dimension | V1 (November 2025) | V2 (July 2026) |
|---|---|---|
| Overall shape | Monolithic spec, experimental core | Stateless core; Tasks is an extension |
| Recovery mechanism | tasks/list — ask server "what tasks exist?" (unfiltered, unscalable) |
tasks/list removed; clients persist task IDs |
| Human-in-the-loop input | Server opens long-lived tasks/result session, elicits from client |
Client sends a signal/update via a new endpoint (no session held) |
tasks/result |
Session-based, carries elicitation | Simplified, no session |
| Connection model | Stateful (requires sticky sessions) | Stateless (any server instance handles any request) |
| Task lifecycle | working → input_required → working → completed/canceled/failed | Unchanged |
| Scalability at 1M tasks | Server must hold all tasks; client must manage sessions | Each client polls its own tasks; no server-side enumeration |
What Still Needs to Be Solved in V2
V2 is better, but not finished. Two notable gaps remain:
The Polling Scalability Problem
With tasks/list gone, a client with a million in-flight tasks must poll each one individually — a million tasks/get requests. That does not scale. The MCP Tasks spec includes a notifications protocol that offers a path forward: a single endpoint where a client asks "has anything changed?" and the server responds with which task changed. Only then does the client pull that specific task. This replaces the million-poll pattern with change detection.
As of August 2026, the notifications protocol is not fully implemented but is described as promising. Until it ships, clients with high task volumes face a polling cost that grows linearly with concurrency.
The "Should" vs "Must" Problem
The V2 spec says clients should persist task IDs — but the spec itself acknowledges that "if you don't persist task IDs, there is no way to get it back." In practice, this means a client that doesn't persist task IDs has no recovery path if it disconnects. The weak "should" language leaves a silent-failure mode that robust implementations must handle defensively, even if the server doesn't enforce it.
How to Build an MCP Tasks Client Today
If you want to implement Tasks now, here is the practical state of the ecosystem:
1. Pin to the right spec version
- For production today: pin to 2025-11-25 (V1). It's the latest stable revision.
- For forward-looking work: read the 2026-07-28 release candidate and the extension overview. Build with the knowledge that the API will change.
- The deprecated V1 subsystems (including the session-based
tasks/resultflow) have a one-year grace period from July 28, 2026 — so V1 code won't break immediately, but it will need migration.
2. Use FastMCP for server-side Task support
FastMCP already supports server-side Tasks and some client-side functionality. It is the most actively maintained Python MCP framework and is the target for the upcoming V2 reference implementation — Cornelia Davis and collaborators have stated they intend to ship a V2 Tasks implementation directly in FastMCP within approximately 1–2 months (target: September–October 2026).
3. Persist task IDs on the client
Regardless of which spec version you build against, persist every task ID you receive. Store it in a database, not just in memory. This is your only recovery path if the client process restarts or the network drops. Without the task ID, the task is unreachable.
4. Handle the input_required state explicitly
When a task enters input_required:
- V1: You need a protocol handler that manages the long-lived session and responds to server-initiated elicitation. This is the hard part.
- V2: You poll the task status, see
input_required, and send a client-initiated update with the human's input. Much simpler — no session management.
5. Map the task lifecycle to your domain state machine
The MCP task lifecycle (working → input_required → working → completed/failed/canceled) is generic. Your actual business logic has its own state machine (e.g., an invoice going through "validated" → "approved" → "paid" → "reconciled"). You map between the two — the task state is the protocol-level view; your domain state is the application-level view.
What This Means For You
If you build MCP servers: Start declaring Tasks capability in your server initialization. Even if no client uses it yet, the capability advertisement is cheap and forward-compatible. Audit which of your tools take longer than a few seconds — those are your Task candidates. Use FastMCP, which already handles the server-side durability.
If you build AI agent clients: Wait for the FastMCP V2 reference implementation (target Sep–Oct 2026) before investing in client-side Task support unless you have an immediate need. If you must build now, pin to 2025-11-25 and implement the full V1 protocol handler — but budget for migration. Persist every task ID in durable storage from day one.
If you run a small business using AI agents: This matters because it determines what your agents can actually do. A synchronous-only agent can't process an invoice that takes 20 minutes and requires human approval. Tasks make that kind of multi-step, durable workflow possible — but only once agent frameworks adopt the protocol. Watch for FastMCP support landing; that's the signal that real-world async agent workflows are becoming practical.
For a deeper look at how interactive UIs work alongside Tasks in the MCP ecosystem (the other major V2 extension), see our MCP Apps interactive UI protocol guide. For the broader picture of how agents coordinate multiple tools and memory, see our guide on building an AI agent operating system.
FAQ
Q: What is an MCP Task? A: An MCP Task is a protocol-level primitive that lets an AI agent call a tool and get back a durable task handle instead of waiting for a synchronous result. The agent polls for status, retrieves results later, and can send signals (like human approval) into the running task. Tasks are designed for operations that take longer than a single request-response cycle.
Q: Why didn't any agent frameworks implement MCP Tasks V1?
A: Because the V1 protocol was stateful, required long-lived connections for human-in-the-loop input, and had an unfiltered tasks/list endpoint that didn't scale. Implementing it correctly on the client side meant building a durable workflow engine with session management, elicitation handling, and failure recovery — a cost no framework team was willing to pay for an experimental spec.
Q: What is the difference between MCP Tasks V1 and V2?
A: V2 (2026-07-28) removes the stateful session layer, deletes the tasks/list endpoint, replaces the long-lived input session with a client-initiated signal, and moves Tasks into an independently versioned extension. The task lifecycle (working → input_required → completed/failed/canceled) is unchanged. V2 is substantially easier to implement on the client side.
Q: Is MCP Tasks V2 ready for production? A: As of August 2026, the 2026-07-28 spec is a release candidate, not a final stable release. The TypeScript SDK went stable at 2.0.0 on July 27, 2026, with Python, Go, and C# following. However, Tasks remain labeled experimental within the extension. A FastMCP reference implementation is expected by September–October 2026. For production today, pin to the 2025-11-25 stable spec.
Q: Do I need a workflow engine like Temporal to use MCP Tasks? A: No — MCP Tasks is a protocol specification, not a runtime. You can implement Tasks in any language with any persistence layer. However, durable workflow engines like Temporal solve the same underlying problem (long-running, fault-tolerant processes with signals), so they are a natural fit for implementing both the server-side task executor and the client-side task tracker. The reference implementation from Temporal's team uses Temporal workflows for exactly this reason.
Q: What happens if my client crashes while a task is running?
A: The task survives on the server — durability is a spec requirement. But you need your task ID to reattach. In V2, with tasks/list removed, there is no way to rediscover a task without the ID. Persisting task IDs in durable storage is essential; without it, the task becomes an orphan that completes on the server but is never retrieved by the client.
Q: How does MCP Tasks relate to MCP Apps?
A: Both are V2 extensions that shipped with the 2026-07-28 release. MCP Apps lets servers render interactive UIs inside agent hosts. MCP Tasks lets servers run long-running operations. They are complementary — a task that enters input_required could surface an MCP App UI for the human to review and approve. See our MCP Apps guide for how the UI extension works.

Discussion
0 comments