Skip to main content

Tasks

Asynchronous task execution for long-running MCP operations.

Adapted from Tasks. Spec and docs: experimental-ext-tasks / related Tasks extension SEPs.

Long-running work needs durable handles

Tasks keep hosts responsive when tools cannot finish within a single request timeout.

Why not just block?​

  • Connection and intermediary timeouts
  • Crash resilience via durable IDs
  • Progress visibility (working, input_required, …)
  • Mid-flight elicitation without a second ad-hoc channel
  • Server decides per request whether to create a task

Lifecycle statuses​

StatusMeaning
workingIn progress
input_requiredNeeds client/user input (inputRequests)
completedTerminal success (result)
failedTerminal error (error)
cancelledCancel acknowledged (cooperative)

Client checklist​

  1. Advertise io.modelcontextprotocol/tasks in per-request capabilities.
  2. Accept either a normal result or CreateTaskResult (resultType: "task").
  3. Poll with tasks/get using pollIntervalMs.
  4. Handle input_required via tasks/update.
  5. Persist taskId across restarts.
  6. Optionally subscribe to notifications/tasks.

Server checklist​

  1. Advertise the extension in server/discover.
  2. Never return a task to clients that did not opt in.
  3. Create the task durably before responding.
  4. Honour cancellation when possible (cooperative).

Good fit​

CI pipelines, batch jobs, human approvals, wrappers around external job APIs, unreliable networks.

Negative cases​

  • Returning tasks without client capability → protocol violation.
  • Non-durable task store → lost work on server restart.
  • Ignoring input_required on the client → stuck forever.

Discussion

Comments​

Share feedback or questions about this page. No account required.

Loading comments…