hubagenticai

Compare & Decide Advanced · 7/12

Long-running agent tasks: MCP Tasks vs. A2A tasks vs. durable execution

When agent work takes minutes, hours, or a human approval, three different things called "tasks" compete for the job. What each one guarantees, what it does not, and how they fit together.

updated 2026-10-08

Most agent tutorials assume every step finishes in seconds. Real work doesn’t: a CI pipeline runs for twenty minutes, a data export for an hour, a refund waits two days for a manager’s approval. At that point you need something that remembers the work exists while nothing is actively running it.

Three things now offer that, and all three call themselves “tasks”:

  1. MCP Tasks, an extension to the Model Context Protocol, for a tool call that takes too long to answer in one request.
  2. A2A tasks, the core unit of the Agent2Agent protocol, for work you delegate to another agent.
  3. Durable execution, a class of runtimes (Temporal, Restate, DBOS, Inngest, and the persistence layer in frameworks such as LangGraph) that make your own code survive crashes and restarts.

They solve different problems, and the most common mistake is assuming the first two give you the third. They don’t. A protocol tells a caller how to track work across a boundary; it does not keep the worker on the other side alive.

MCP Tasks: a tool call that returns a ticket

In the 2026-07-28 MCP spec revision, Tasks moved out of the core protocol into an official extension, io.modelcontextprotocol/tasks. Both sides opt in: the client lists the extension in the capabilities it sends with each request, and the server advertises it from server/discover.

How it works:

  • The client calls a tool as usual. If the server decides the call will be long-running, it returns a task handle instead of the result (resultType: "task", with a taskId, a status, a time-to-live ttlMs, and a suggested pollIntervalMs). The server decides per request; the client just has to handle either shape.
  • The client polls with tasks/get until the status is terminal. Statuses: working, input_required, completed, failed, cancelled. Servers can also push updates through the new subscriptions/listen mechanism.
  • If the task needs something from the user (a confirmation, a missing value), it moves to input_required with the requests attached, and the client answers with tasks/update.
  • tasks/cancel asks the server to stop. Cancellation is cooperative: the server may still finish.

What it guarantees: a handle the client can keep and come back to after a disconnect. The spec tells servers to create the task durably before replying, and tells clients to store task IDs durably. What it does not guarantee: that the work behind the handle survives a server crash. That is the server author’s job.

Adoption caveat (October 2026): the extension is new. The official Python SDK had not implemented it yet, and the MCP project’s client support matrix listed no client with Tasks support. Check your client before designing around it.

A2A tasks: delegation with a lifecycle

In A2A, the task is the protocol. When one agent sends another a message, the receiving agent can answer directly or create a task, and from then on both sides talk about that task. The v1.0 spec (released March 2026) defines these states: submitted, working, input-required, auth-required, completed, failed, canceled, and rejected. Results come back as artifacts attached to the task.

The operations, by their v1.0 names: SendMessage and SendStreamingMessage to start or continue work, GetTask to check on it, CancelTask, SubscribeToTask to stream updates, and a set of …TaskPushNotificationConfig operations so the remote agent can call a webhook when something changes, instead of you polling for hours.

The differences from MCP Tasks come from the peer on the other side. An A2A peer is an agent: it can reject the task, ask clarifying questions over several turns, or need its own authorization (auth-required). It’s usually run by another team or another company. A2A says nothing about how that agent keeps its work alive either; it only tells you what state the agent reports.

Durable execution: making the worker itself survive

Durable-execution engines record each step of your code as it runs. If the process dies, a new one replays the record, skips the steps that already completed, and continues from where it stopped. Waiting is cheap: a workflow can sleep for three days, holding no process, and resume when a timer fires or a signal (such as “approved”) arrives.

The main shapes:

  • Workflow engines with a server, such as Temporal and Restate. You write workflows in ordinary code; the engine records the history and drives retries, timers and signals. Temporal requires workflow code to be deterministic, with side effects (including LLM and tool calls) placed in separately retried activities.
  • Libraries on your own database, such as DBOS, which checkpoints workflow steps in Postgres, so there is no separate orchestrator to run.
  • Persistence inside an agent framework, such as LangGraph: compile the graph with a checkpointer and pass a thread_id, and the graph’s state is saved as it runs, so it can resume after a failure or a human-in-the-loop interrupt. LangGraph lets you trade speed for safety with its durability modes (exit, async, sync).

The rule they all share: a step that is resumed may run again, so anything with a side effect (sending an email, issuing a refund, writing a record) needs an idempotency key or a check for an existing result. LLM calls are side effects for this purpose too: their output isn’t reproducible, so record it rather than regenerate it on replay.

How they fit together

These are layers, not alternatives. A typical long-running agent action uses a protocol at the boundary and an engine behind it:

diagram
One refund, three layers: MCP task handle → durable workflow → human approval
%% caption: One refund, three layers: MCP task handle → durable workflow → human approval
sequenceDiagram
    autonumber
    participant Agent as Agent<br/>(MCP client)
    participant Server as MCP server
    participant Engine as Workflow<br/>engine
    participant Human as Approver

    Agent->>Server: tools/call issue_refund<br/>(tasks extension)
    Server->>Engine: start workflow<br/>key = request ID
    Server-->>Agent: task handle<br/>status: working
    loop every pollIntervalMs
        Agent->>Server: tasks/get
        Server->>Engine: query state
        Server-->>Agent: status: working
    end
    Engine->>Human: approval request
    Note over Engine: sleeps, holding<br/>no process
    Human-->>Engine: approved (signal)
    Engine->>Engine: issue refund<br/>(recorded, retried)
    Agent->>Server: tasks/get
    Server-->>Agent: completed + result

The MCP task handle lets the agent stop waiting on an open connection and come back later. The durable workflow lets the refund survive a deploy, a crash, or a two-day approval wait. Swap the MCP server for a remote A2A agent and the picture is the same: A2A at the boundary, whatever durable runtime that team chose behind it.

Decision table

Your situationUseWhy
A tool call takes longer than a client will wait on one requestMCP Tasks (if your client supports it)Returns a handle instead of blocking; the client polls or subscribes
A tool call needs a user’s input partway throughMCP Tasks input_requiredMid-flight input without a second connection
You hand long work to an agent owned by another team or vendorA2A tasksLifecycle, multi-turn clarification, push notifications, rejection and auth states
Your own agent’s multi-step work must survive restarts and deploysDurable executionRecords completed steps and resumes; protocols don’t do this
A step waits hours or days for a human or an external eventDurable execution (timers and signals)Sleeps without holding a process, resumes on the signal
You’re already on LangGraph and need resume-after-failureLangGraph checkpointerDurability without adding an engine; graduate to a dedicated engine if workflows get complex
The work finishes in secondsNone of theseA plain tool call with a timeout and retry is simpler

The verdict

Pick by boundary, then by durability. If the long work sits behind an MCP tool, expose it as an MCP task; if it sits behind another agent, it’s an A2A task. Either way, if losing the work to a crash would cost money or trust, run it on a durable-execution engine and make every side effect idempotent. Starting with the engine and adding the protocol later is easier than the reverse.

Where to go next

For the three protocols side by side, read the agent protocol stack. For deciding which parts of a process should be agent steps at all, see workflow vs. agent. If you maintain an MCP server, migrating to the 2026 spec covers the extension mechanism that Tasks plugs into.

newsletter

One practical agentic-AI guide in your inbox. No news, no hype.

Tutorials and decision frameworks as they ship. Unsubscribe anytime.

Quick Jump: