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…