Gloss Key Takeaways
  1. MCP’s release-candidate Tasks extension lets a tools/call return a task handle (a ticket) instead of an immediate result, with clients polling via tasks/get, steering via tasks/update, or stopping via tasks/cancel.
  2. The change exists because long-running agent/tool work doesn’t fit reliably in a single request-response cycle and routinely breaks on timeouts, forcing brittle, non-portable async hacks.
  3. Task creation is server-directed: clients only advertise support, and the server decides per call whether to return a normal result or a task handle based on expected runtime.
  4. tasks/list was removed because MCP’s stateless design can’t safely scope task enumeration without sessions, making the task handle the only way to re-identify work.
  5. This is a real migration from the 2025-11-25 experimental Tasks API: ownership, discovery, and cleanup semantics changed, so existing servers/clients must be updated accordingly.

The tool call returns a ticket

The MCP release candidate makes Tasks a first-class extension: a tool call can hand back a handle instead of an answer, and the client drives it with tasks/get, tasks/update, and tasks/cancel until the work is done.

This exists because agent work stopped fitting inside one request. Long-running tools were already faking async with timeouts, keep-alive streams, and homegrown polling. Now the protocol does the job so you stop reinventing it badly.

If you build MCP servers, this is real work, not a footnote. You decide which calls become tasks, you live without tasks/list because it was removed, and you write clients that survive a call returning nothing useful for ten minutes.

The request that was always going to break

The Model Context Protocol was born request-response. Client calls a tool, server does the thing, server returns the result. That shape is fine when the tool reads a file or hits a database. It falls apart the moment the tool is "run the test suite," "render the video," "kick off the deployment and watch it," or "let the sub-agent think about this for a while."

Those calls do not finish in a few hundred milliseconds. They finish in minutes, sometimes longer. And a synchronous call that takes eight minutes is a call that dies on every load balancer, gateway, and idle timeout between the client and the server. Everyone who shipped a serious MCP server hit this wall. The workarounds were all variations on the same hack: hold the connection open and dribble out keep-alive messages, or return immediately with some job ID baked into the tool's own arguments and make the model poll a second tool you invented for the purpose.

Both work. Neither is portable. Your polling convention is not my polling convention, and the model has to learn each one.

What the extension actually says

The redesigned Tasks extension, which moved from an experimental core feature in the 2025-11-25 spec to a standalone extension in the release candidate dated 2026-07-28, formalizes the pattern. A server can answer a tools/call with a task handle instead of a result. The client then drives the work with three operations: tasks/get to check status, tasks/update to nudge it, tasks/cancel to kill it.

Two design decisions are worth reading closely.

First, task creation is server-directed. The client advertises that it supports the extension, and the server decides when a given call should run as a task. You do not annotate a tool as "always async" and hope. The server, which is the only party that knows how long the work will take, makes the call at call time. A tool can return a normal result today and a task handle tomorrow for a larger input, and the client handles both.

Second, tasks/list is gone. The old experimental API let you enumerate outstanding tasks. That primitive got cut because, in the words of the spec, it "can't be scoped safely without sessions." This is the stateless redesign showing its teeth. When there is no session tying a stream of calls to one client, there is no safe way to answer "show me my tasks" without leaking one client's work to another. So the operation was removed rather than shipped with a security hole. The task handle you get back is now the only thing that lets you find your task again. Lose it, and the work is orphaned.

Why stateless forced this

I wrote a few weeks back that MCP went stateless and that your state did not vanish, it moved. Tasks is the clearest evidence of what that migration costs and buys. In a session world, a long-running task could lean on the session for identity, scoping, and cleanup. Strip the session out and every one of those has to be rebuilt around the handle itself.

That is why the lifecycle changed substantially enough that anyone using the 2025-11-25 experimental Tasks API has to migrate. This is not a rename. The model of who owns the task, how you find it, and how it gets cleaned up all shifted. If you built on the experimental version, budget time for the rewrite before you assume the upgrade is free.

The upside is that a task handle is portable in a way a session never was. Because the whole thing is stateless, the client polling your task does not have to be the same process that started it, does not have to hold a connection open, and does not care which server instance behind the load balancer answers the poll. That is the entire point. Long work stops being tied to a fragile connection and becomes a thing you can hand off, retry, and resume.

The other half: MCP Apps

The same release candidate promotes MCP Apps to a first-class extension. Servers can ship interactive HTML interfaces that the host renders in a sandboxed iframe. Tools pre-declare their UI templates so the host can prefetch them and review them for security before anything runs. The rendered UI talks back to the host over the same JSON-RPC base protocol, which means every click a user makes inside that embedded interface flows through the same audit and consent path as a normal tool call.

Pair this with Tasks and the shape of a real agent workflow appears. A tool kicks off a ten-minute job and returns a task handle. An MCP App renders a live view of that job inside the host. The user watches, and if they intervene, the intervention is a JSON-RPC call that gets logged and consented to like everything else. The protocol is quietly growing the pieces you need to run work that a human supervises rather than work that returns in one breath.

What to do about it

If you maintain an MCP server, three concrete moves.

Audit your tools for the ones that already take too long. Anything that runs a build, a test suite, a deployment, a render, or a sub-agent is a Tasks candidate. Those are the calls worth converting first, because those are the calls currently dying on timeouts.

Design your clients to lose the handle gracefully. With tasks/list gone, a dropped handle is a lost task. That means the handle has to be persisted somewhere the moment you receive it, not held in memory and forgotten on the next crash. Treat it like a receipt you cannot reprint.

Hold off on production commitments until the final spec lands. This is a release candidate. The final specification carries the 2026-07-28 date, which means the details can still move between now and then. Prototype against it, file the rough edges upstream, but do not ship a customer-facing integration on a candidate and then act surprised when a field name changes.

The tool call that returns a ticket instead of an answer feels like a small change. It is not. It is the protocol admitting that the interesting agent work does not fit in a single round trip anymore, and building the plumbing to match. The teams who internalize that early will have agents that run for ten minutes without falling over. The teams who do not will keep writing the same polling hack, badly, one server at a time.

Gloss What This Means For You

If you build or integrate with MCP servers, update your clients to handle tools/call responses that may return only a task handle and then keep working through tasks/get until completion, even if it takes many minutes. On the server side, decide which operations should become tasks at runtime and design for the fact that users can’t “list my tasks,” so losing a handle means losing access. If you previously relied on the experimental Tasks API, plan a migration because the stateless lifecycle and security constraints change how you track, scope, and clean up long-running work.