Back to Blog
Technical GuideDecember 16, 202517 min read

MCP Tasks (2025): Durable Tool Calls, Polling, and Deferred Results

The November 2025 MCP spec introduces experimental Tasks, a durable execution layer that lets clients track long-running work, poll status, and retrieve results later. This deep dive explains the exact message flow and the best practices you need for production.

Share:

Why Tasks exist

MCP started as a clean abstraction for calling tools and reading resources, but real workloads do not always finish within a single request. Code migration, deep research, big data processing, and enterprise automation frequently take minutes or hours.

Tasks provide a standardized way to make an MCP request durable: instead of blocking until completion, the receiver returns a task handle that the requestor can poll. When the work is complete, the requestor retrieves the final result via a separate method.

The core idea

Phase 1: `tools/call` returns `CreateTaskResult` (no tool output yet).
Phase 2: `tasks/result` returns the same structure as the original request (for tool calls, that is `CallToolResult`).
Sponsored
InVideo AI - Create videos with AI

The message flow (with real JSON-RPC)

1) Create a task via `tools/call`

The requestor includes a `task` object in the request params. A `ttl` can be requested (milliseconds), but the receiver can override it.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "generate_report",
    "arguments": {
      "range": "last_90_days"
    },
    "task": {
      "ttl": 600000
    }
  }
}

The receiver returns a `CreateTaskResult` with the task state (including `pollInterval`).

2) Poll status via `tasks/get`

The requestor polls until the task reaches a terminal state (`completed`, `failed`, `cancelled`) or enters `input_required`.

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tasks/get",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}

3) Retrieve the final output via `tasks/result`

`tasks/result` blocks until the task reaches a terminal status, then returns the underlying request result.

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tasks/result",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}

Automate Your Emails with AI

GetResponse combines email marketing and AI for ultra-high-performing campaigns. Perfect for MCP workflows.

Try GetResponse Free

Status lifecycle, cancellation, and operational safety

The allowed status transitions

Tasks start in `working`. From there, they may move to `input_required` or a terminal state. Once terminal, they must not transition again.

`input_required` is a first-class concept

If the receiver needs more data to proceed, it should move the task into `input_required`. The protocol requires task-related messages to include related-task metadata in `_meta`.

Cancellation is explicit

Requestors can cancel with `tasks/cancel`. Receivers should attempt to stop execution and must transition the task to `cancelled`.

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tasks/cancel",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}
Sponsored
InVideo AI - Create videos with AI

Production checklist (clients and servers)

Client-side checklist

  • 1. Respect `pollInterval` and avoid aggressive polling.
  • 2. Treat `taskId` as opaque and never derive meaning from it.
  • 3. Handle `input_required` by preemptively calling `tasks/result` when appropriate.
  • 4. Plan for expiry: results may disappear after TTL.

Server-side checklist

  • 1. Return `CreateTaskResult` as soon as possible after accepting work.
  • 2. Provide realistic `pollInterval` values.
  • 3. Use strong isolation boundaries so tasks cannot leak across sessions.
  • 4. Validate inputs and return tool execution errors to enable model self-correction.

If you are building automation workflows around MCP and you want a practical way to trigger campaigns and follow-ups after a task completes, consider connecting your pipeline to GetResponse for email marketing automation.

Conclusion

Tasks are the missing piece for real-world MCP adoption: long-running jobs become first-class, clients stay responsive, and results remain retrievable after completion.

Treat Tasks as an execution contract: define clear lifecycles, communicate progress, and harden boundaries. Do that, and you can safely move agentic systems from demos to production.

#MCP#Tasks#Polling#LongRunning#StreamableHTTP#SSE#Automation#JSONRPC#OAuth#Enterprise