What it does
The tasks/result method is a JSON-RPC 2.0 request sent by the Requestor to the Receiver to retrieve the terminal payload of a task that has already reached a completed or failed state. Before calling it, the Requestor must confirm the task is in a terminal state — either by polling tasks/get until status is completed, failed, or cancelled, or by receiving a notifications/tasks/updated push event that carries the same transition. Calling tasks/result on a task that is still in working or input_required state will return a -32602 Invalid params error; it is not a blocking wait. Both parties must have negotiated tasks capability during initialize for this method to be available.\n\nThe request carries a single required parameter, taskId (the opaque string returned when the task was submitted). The response envelope mirrors the Task object: taskId, a terminal status field, and a result field whose shape depends on the underlying operation — for a tools/call-backed task this will be a CallToolResult, for resources/read it will be the resource content array. When a task ends in failed state, the result field may be absent or contain structured error detail; the spec leaves the exact schema to the receiver implementation, so defensive null-checks are essential.\n\nTwo timing constraints matter in practice. First, receivers enforce a TTL on stored tasks — once expired, tasks/result returns -32602 "Task has expired" just as tasks/get does, so callers should retrieve results promptly after the completion notification. Second, the method is idempotent for the task's lifetime: repeated calls to tasks/result return the same snapshot, which makes it safe to retry on transient transport errors without risk of side effects.
When to use
After tasks/get reports status:'completed'.
When NOT to use
While the task is still working.
Notes
Capability gating is mandatory
Both client and server must declare tasks support in their respective capability objects during the initialize handshake. If either side omits the tasks capability, the receiver must return a -32601 Method not found error. Check ServerCapabilities.tasks and ClientCapabilities.tasks before issuing any tasks/* call.
Only call after a terminal status is confirmed
tasks/result is not a blocking wait. Calling it while status is still working or input_required yields a -32602 Invalid params error. Always gate the call on a confirmed terminal state from tasks/get or a notifications/tasks/updated event — never race directly after submission.
Result shape is implementation-defined
The result field in the response is typed as unknown in the MCP spec. Its actual schema mirrors the underlying operation (e.g., CallToolResult for tool tasks, ReadResourceResult for resource tasks). For failed tasks the field may be null or contain a server-defined error payload — always write null-safe access and validate the shape against the operation type you submitted.
Tasks expire — retrieve results promptly
Receivers are permitted to purge task records after the TTL advertised in the tasks/get response. Once purged, tasks/result returns the same -32602 'Task has expired' error as tasks/get. Fetch and persist the result as soon as you receive a completed notification rather than relying on the server to hold it indefinitely.
Safe to retry on transport errors
tasks/result is read-only and idempotent — repeated calls for the same taskId return the same snapshot. If a network failure occurs mid-response, retry with the same taskId without concern for double-processing. The only caveat is that a retry arriving after TTL expiry will receive a -32602 expiry error instead of the result.
Request parameters
| Name | Type | Purpose |
|---|---|---|
| taskId | string | Completed task id. |
Response fields
| Name | Type | Purpose |
|---|---|---|
| taskId | string | Task identifier. |
| status | TaskStatus | Terminal status. |
| result | unknown? | Underlying payload (e.g., a CallToolResult). |
Examples
Get result
{ "method": "tasks/result", "params": { "taskId": "abc" } }
Common mistakes
❌ Calling before status is terminal
✅ Poll tasks/get first.