# MCP Tasks Extension: Long-Running Jobs Without Blocking Your Agent (2026)

> The MCP Tasks extension lets agents kick off a 20-minute job, get a task ID back, and poll for the result later. Here is how the call-now, fetch-later pattern works.

**Source:** https://mcpplaygroundonline.com/blog/mcp-tasks-extension-long-running-operations  
**Author:** Nikhil Tiwari  
**Published:** 2026-07-22  
**Category:** Development  
**Reading time:** 9 min read

---

📖 TL;DR

-   The **MCP Tasks extension** gives long-running work first-class support — no more tool calls that hang for 20 minutes.
-   It uses a **call-now, fetch-later** pattern: submit a job, get a task ID, then poll `tasks/get` while the conversation keeps moving.
-   Tasks moved **out of the core protocol** into an official extension in the 2026 redesign, rebuilt around the new stateless core.
-   Test how your server handles long jobs in [MCP Playground](/mcp-test-server) — free, in the browser.

Some tools finish in 50 milliseconds. Others kick off a data pipeline that runs for 20 minutes.

Until 2026, MCP treated both the same way — one blocking request, one response. That falls apart the moment work outlives the request.

The **MCP Tasks extension** fixes this. It lets an agent start a long job, get a handle back, and check on it later — without freezing the chat.

If you build agents that run ETL jobs, multi-repo evals, or overnight batch work, this is the piece of the 2026 spec you actually need. Here is how it works.

## What is the MCP Tasks extension?

The _Tasks extension_ is an official MCP extension for long-running operations. It lets a server accept a request, return a task handle immediately, and do the real work in the background.

The client then polls or subscribes for the result. The model is free to answer other questions in the meantime.

Each task is a **durable state machine**. It carries the execution state of a request — running, done, failed — behind a single ID the receiver generates.

The reference lives at [modelcontextprotocol/ext-tasks](https://github.com/modelcontextprotocol/ext-tasks) on GitHub, versioned independently from the core spec.

## Why blocking tool calls break real agents

**The problem:** a plain tool call is synchronous. The client sends a request and waits for one response.

That is fine for a database read. It is a disaster for a job that takes minutes.

**It gets worse.** A long request holds a connection open. On the new stateless infrastructure, that means timeouts, dropped load-balancer connections, and gateways that give up mid-job.

Your agent looks frozen. The user assumes it crashed. The pipeline is still running, but nobody can see it.

**The fix** is to stop waiting. Return a receipt now, deliver the result later. That is exactly what Tasks does.

## The call-now, fetch-later pattern

The Tasks flow has three moves. Think of it like ordering food with a buzzer.

1.  **Call now.** The client invokes a task-capable tool. The server returns a task ID instead of a final result.
2.  **Do other work.** The agent keeps talking to the user. The conversation is never blocked.
3.  **Fetch later.** The client polls `tasks/get` with the ID until the task reaches a terminal state, then reads the result.

This decouples the length of the work from the length of the request. A 20-minute job and a 200-millisecond job use the same clean handshake.

## The task lifecycle: five states

Every task moves through a small set of states. That gives the agent and the user real visibility instead of a spinner.

State

What it means

`working`

The job is running. Keep polling.

`input_required`

The task paused and needs more data from the client.

`completed`

Done. The result is ready to fetch.

`failed`

The job errored out. Read the error payload.

`cancelled`

The client called `tasks/cancel` and the work stopped.

`working` and `input_required` are non-terminal. The other three are terminal — once you hit them, stop polling.

## The three methods: get, update, cancel

The 2026 redesign trimmed the API down to what agents actually use.

-   **`tasks/get`** — poll a task by ID to read its current state and, once terminal, its result.
-   **`tasks/update`** — send data back into a task that is sitting in `input_required`.
-   **`tasks/cancel`** — stop a task you no longer need so the server can free resources.

Notice what is missing: the old blocking `tasks/result` call. It is gone.

Instead of one method that hangs until the job finishes, you poll `tasks/get`. That plays nicely with stateless servers and plain HTTP load balancers.

**Tip:** back off your polling interval. Start at a second or two, then widen the gap for jobs you know run for minutes. Hammering `tasks/get` every 100ms just burns tokens and rate limits.

## What changed from the 2025-11-25 version

Tasks is not brand new. It first shipped as an **experimental core feature** in the 2025-11-25 spec.

Production use exposed two problems. The blocking result call did not fit long jobs, and baking tasks into the core made the protocol heavier for servers that never needed them.

So the 2026 redesign made two calls:

-   **Moved out of core** into an official, independently versioned extension. Servers opt in.
-   **Rebuilt around statelessness** — polling via `tasks/get` replaced the blocking `tasks/result` method.

If you built against the experimental API, you must migrate. The lifecycle-based extension is the supported path going forward.

## When should you reach for Tasks?

Not every tool needs this. Use Tasks when the work can plausibly outlive a single request.

-   Kicking off a **20-minute data pipeline** or ETL job
-   Running a **multi-repo evaluation** across a large codebase
-   An **overnight document classification** batch
-   Large **file conversions** or media processing
-   Multi-step **infrastructure provisioning**

For a fast lookup or a single API read, skip it. A plain tool call is simpler and cheaper.

## How MCP Playground can help

Before you ship a task-capable server, you want to see the whole lifecycle actually work — states, polling, and the final payload.

[MCP Agent Studio](/mcp-agent-studio) connects a real AI model to your server and shows every call live. You watch the task fire, transition through `working`, and land on `completed` — no local setup.

Testing a long-running MCP server?

Connect it, fire a task, and watch every state change in your browser.

[Test any MCP server free →](/mcp-test-server)

## Frequently Asked Questions

**What is the MCP Tasks extension?** It is an official MCP extension that adds first-class support for long-running operations, letting a server return a task ID immediately and deliver the result later while the conversation keeps moving.

**How do MCP tasks work?** A client calls a task-capable tool, gets a receiver-generated task ID, and polls `tasks/get` until the task reaches a terminal state — completed, failed, or cancelled.

**Is Tasks part of the MCP core protocol?** No. It started as an experimental core feature in 2025-11-25 but was moved into an official, independently versioned extension in the 2026 redesign.

## Conclusion

**The Tasks extension is how MCP finally handles work that takes minutes, not milliseconds.** Call now, fetch later, poll `tasks/get`, and never freeze the chat again.

The best way to trust it is to watch it run. [Test any MCP server free](/mcp-test-server) and see the full task lifecycle end to end.

## Frequently asked questions

### What is the MCP Tasks extension?

The MCP Tasks extension is an official Model Context Protocol extension that adds first-class support for long-running operations. Instead of a blocking tool call, a task-capable server returns a task ID immediately and does the real work in the background, so the agent can deliver the result later without freezing the conversation.

### How does the call-now, fetch-later pattern work?

The client invokes a task-capable tool and gets back a receiver-generated task ID instead of a final result. The agent keeps doing other work while the client polls tasks/get with that ID until the task reaches a terminal state (completed, failed, or cancelled), then reads the result.

### What are the MCP task lifecycle states?

A task moves through five states: working (running), input_required (paused, needs more data), completed (done, result ready), failed (errored), and cancelled (stopped by the client). Working and input_required are non-terminal; the other three are terminal.

### What methods does the Tasks extension use?

Three: tasks/get to poll a task by ID, tasks/update to send data back into a task waiting in input_required, and tasks/cancel to stop a task you no longer need. The old blocking tasks/result method was removed in favor of polling.

### Do I need to migrate from the experimental Tasks API?

Yes. Tasks first shipped as an experimental core feature in the 2025-11-25 spec, but the 2026 redesign moved it into an official extension and replaced the blocking tasks/result call with polling via tasks/get. Code built against the experimental API must be updated to the extension-based lifecycle.


---

_Canonical page: https://mcpplaygroundonline.com/blog/mcp-tasks-extension-long-running-operations — MCP Playground (mcpplaygroundonline.com), the free browser-based tool for testing MCP servers and building AI agents._
