What is Task?
The Task interface is a durable state machine that wraps a long-running MCP operation, giving clients a stable identity (taskId) to poll against rather than holding an open connection. Introduced as an experimental feature on 2025-11-25, it decouples request initiation from result retrieval: a server returns a Task immediately when it accepts a request that may take seconds to minutes, and the client repeatedly calls the polling endpoint until status reaches a terminal state (completed, failed, or cancelled).
Within the MCP message flow, a Task sits between the initial tool-call response and the final result payload. The server owns the lifecycle — it transitions status from working through any intermediate input_required pauses (where the client must supply additional data before processing resumes) to a terminal state. The pollInterval field (in milliseconds) is a server-supplied hint telling clients how frequently to check; respecting it prevents both thundering-herd polling and stale UX. The ttl field signals how long the server will retain the task record after completion, letting clients garbage-collect their local references.
Because the feature is still experimental, the exact wire encoding and status enum values should be treated as unstable across minor MCP spec revisions. The statusMessage string is optional and carries human-readable progress detail — useful for streaming textual progress to a UI — but must not be parsed programmatically, as its format is server-defined and unversioned.
When to use
For expensive tool calls, batch jobs, or long-running workflows.
When NOT to use
For quick synchronous operations — the overhead isn't worth it.
Notes
Poll interval is a hint, not a contract
Servers set pollInterval based on expected workload cadence, but clients must handle the case where a task finishes faster than one interval. Always check status on the first poll response before scheduling the next tick. Aggressive over-polling (ignoring pollInterval entirely) risks rate-limiting from MCP server implementations that enforce per-task request quotas.
TTL clock starts at completion
The ttl field counts milliseconds from the task's terminal-state transition, not from creation. A client that misses the completion window will receive a 404-equivalent on the next poll — treat that as a permanent failure. For long-pipeline tasks, save the final result payload on first successful read rather than relying on re-fetching within the TTL window.
input_required pauses block status progression
When status is input_required, the task will not advance to completed or failed until the client submits the requested data via the task-continuation endpoint. Failing to respond before the TTL expires causes the task to transition to cancelled. Always surface this status visibly in client UIs so users are not left watching an indefinitely-stalled spinner.
taskId uniqueness scope is server-local
The spec does not mandate globally unique taskIds across MCP servers or across sessions on the same server. Clients operating against multiple servers should namespace stored task references by server origin to avoid ID collisions. UUIDs are the recommended format but are not enforced by the schema.
Experimental status means schema instability
Because Task was introduced as experimental, the TaskStatus enum and optional fields like statusMessage may gain or lose members in future MCP spec drafts without a major version bump. Pin to a specific MCP spec revision in production and validate inbound task objects defensively — treat any unrecognised status value as working rather than failing fast.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| taskId | string | yes | Unique identifier (often UUID). |
| status | TaskStatus | yes | 'working' | 'input_required' | 'completed' | 'failed' | 'cancelled'. |
| statusMessage | string? | no | Human-readable status detail. |
| createdAt | string | yes | ISO 8601 creation timestamp. |
| lastUpdatedAt | string | yes | ISO 8601 last update. |
| ttl | number | yes | Milliseconds the task will be retained after completion. |
| pollInterval | number | yes | Recommended client poll interval in milliseconds. |
Examples
Working task
{
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
"status": "working",
"createdAt": "2025-11-25T10:30:00Z",
"lastUpdatedAt": "2025-11-25T10:30:05Z",
"ttl": 30000,
"pollInterval": 5000
}
Common mistakes
❌ Polling more aggressively than pollInterval
✅ Respect pollInterval — servers may rate-limit you.