From 08116acb164e83a68713000462866312f2f722ba Mon Sep 17 00:00:00 2001
From: Luca Chang
but requestor uses task polling instead
+ Note over C,S: 2. Task Polling
+ C->>S: tasks/get (taskId)
+ S->>C: submitted
+ C->>S: tasks/get (taskId)
+ S->>C: working
+ Note over S: Task processing continues...
+ C->>S: tasks/get (taskId)
+ S->>C: working
+ Note over S: Task completes
+ C->>S: tasks/get (taskId)
+ S->>C: completed
+ Note over C,S: 3. Result Retrieval
+ C->>S: tasks/result (taskId)
+ S->>C: Result content
+ Note over C,S: 4. Cleanup
+ Note over S: After keepAlive period, task is cleaned up
+```
+
+### Task-Augmented Tool Call With Elicitation
+
+```mermaid
+sequenceDiagram
+ participant U as User
+ participant LLM
+ participant C as Client (Requestor)
+ participant S as Server (Receiver)
+
+ Note over LLM,C: LLM initiates request
+ LLM->>C: Request operation
+
+ Note over C,S: Client augments with task metadata
+ C->>S: tools/call (task-123, keepAlive: 3600000)
+ S--)C: notifications/tasks/created
+ Note over C,S: Original request will respond eventually,
but client uses task polling instead
+
+ Note over LLM,C: Client continues processing other requests
while task executes in background
+ LLM->>C: Request other operation
+ C->>LLM: Other operation result
+
+ Note over C,S: Client polls for status
+ C->>S: tasks/get (task-123)
+ S->>C: working
+
+ Note over S: Server requires additional information
Task moves to input_required
+
+ Note over S,C: Server sends elicitation request
+ S->>C: elicitation/create (task-123)
+
+ Note over C,S: Client polls and sees task waiting for input
+ C->>S: tasks/get (task-123)
+ S->>C: input_required
+
+ C->>U: Prompt user for input
+ U->>C: Provide information
+ C->>S: elicitation response (task-123)
+
+ Note over S: Task continues processing...
Task moves back to working
+
+ Note over C,S: Client polls again
+ C->>S: tasks/get (task-123)
+ S->>C: working
+
+ Note over S: Task completes
+
+ Note over C,S: Client polls and discovers completion
+ C->>S: tasks/get (task-123)
+ S->>C: completed
+
+ Note over C,S: Client retrieves final results
+ C->>S: tasks/result (task-123)
+ S->>C: Result content
+ C->>LLM: Process result
+
+ Note over S: Results retained for keepAlive period
+```
+
+### Task-Augmented Sampling Request
+
+```mermaid
+sequenceDiagram
+ participant U as User
+ participant LLM
+ participant C as Client (Receiver)
+ participant S as Server (Requestor)
+
+ Note over S: Server decides to initiate request
+
+ Note over S,C: Server requests client operation (task-augmented)
+ S->>C: sampling/createMessage (request-789, keepAlive: 3600000)
+ C--)S: notifications/tasks/created
+ Note over S,C: Original request will respond eventually,
but server uses task polling instead
+
+ Note over S: Server continues processing
while waiting for result
+
+ Note over S,C: Server polls for result
+ S->>C: tasks/get (request-789)
+ C->>S: working
+
+ Note over C,U: Client may present request to user
+ C->>U: Review request
+ U->>C: Approve request
+
+ Note over C,LLM: Client may involve LLM
+ C->>LLM: Request completion
+ LLM->>C: Return completion
+
+ Note over C,U: Client may present result to user
+ C->>U: Review result
+ U->>C: Approve result
+
+ Note over S,C: Server polls and discovers completion
+ S->>C: tasks/get (request-789)
+ C->>S: completed
+
+ Note over S,C: Server retrieves result
+ S->>C: tasks/result (request-789)
+ C->>S: Result content
+
+ Note over S: Server continues processing
+
+ Note over C: Results retained for keepAlive period
+```
+
+### Task Cancellation Flow
+
+```mermaid
+sequenceDiagram
+ participant C as Client (Requestor)
+ participant S as Server (Receiver)
+
+ Note over C,S: 1. Task Creation
+ C->>S: tools/call (request ID: 42, task-123)
+ S--)C: notifications/tasks/created
+
+ Note over C,S: 2. Task Processing
+ C->>S: tasks/get (task-123)
+ S->>C: working
+
+ Note over C,S: 3. Client Cancellation
+ Note over C: User requests cancellation
+ C--)S: notifications/cancelled (requestId: 42)
+
+ Note over S: Server processes cancellation
+ Note over S: Task moves to cancelled status
+
+ Note over C,S: 4. Confirmation Polling
+ C->>S: tasks/get (task-123)
+ S->>C: cancelled
+
+ Note over C: Client confirms cancellation succeeded
+
+ Note over S: After keepAlive period, task cleaned up
+```
+
+## Data Types
+
+### Task
+
+A task represents the execution state of a request. The task metadata includes:
+
+- `taskId`: Unique identifier for the task
+- `keepAlive`: Time in milliseconds that results will be kept available after completion
+- `pollFrequency`: Suggested time in milliseconds between status checks
+- `status`: Current state of the task execution
+
+### Task Status
+
+Tasks can be in one of the following states:
+
+- `submitted`: The request has been received and queued for execution
+- `working`: The request is currently being processed
+- `completed`: The request completed successfully and results are available
+- `failed`: The request encountered an error during execution
+- `cancelled`: The request was cancelled before completion
+- `unknown`: A terminal fallback state for unexpected error conditions when the receiver cannot determine the actual task state
+
+### Task Metadata
+
+When augmenting a request with task execution, the `modelcontextprotocol.io/task` key is included in `_meta`:
+
+```json
+{
+ "modelcontextprotocol.io/task": {
+ "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
+ "keepAlive": 60000
+ }
+}
+```
+
+Fields:
+
+- `taskId` (string, required): Client-generated unique identifier for the task
+- `keepAlive` (number, optional): Requested duration in milliseconds to retain results after completion
+
+### Related Task Metadata
+
+All requests, responses, and notifications associated with a task **MUST** include the `modelcontextprotocol.io/related-task` key in `_meta`:
+
+```json
+{
+ "modelcontextprotocol.io/related-task": {
+ "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
+ }
+}
+```
+
+This associates messages with their originating task across the entire request lifecycle.
+
+## Error Handling
+
+Tasks use two error reporting mechanisms:
+
+1. **Protocol Errors**: Standard JSON-RPC errors for protocol-level issues
+1. **Task Execution Errors**: Errors in the underlying request execution, reported through task status
+
+### Protocol Errors
+
+Receivers **MUST** return standard JSON-RPC errors for the following protocol error cases:
+
+- Invalid or nonexistent `taskId` in `tasks/get`, `tasks/list`, or `tasks/result`: `-32602` (Invalid params)
+- Invalid or nonexistent cursor in `tasks/list`: `-32602` (Invalid params)
+- Request with a `taskId` that was already used for a different task: `-32602` (Invalid params)
+- Attempting to retrieve result when task is not in `completed` status: `-32602` (Invalid params)
+- Internal errors: `-32603` (Internal error)
+
+Receivers **SHOULD** provide informative error messages to describe the cause of errors.
+
+**Example: Task not found**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 70,
+ "error": {
+ "code": -32602,
+ "message": "Failed to retrieve task: Task not found"
+ }
+}
+```
+
+**Example: Task expired**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 71,
+ "error": {
+ "code": -32602,
+ "message": "Failed to retrieve task: Task has expired"
+ }
+}
+```
+
+
The client's response to a sampling/create_message request from the server. The client should inform the user before returning the sampled message, to allow them to inspect the response (human in the loop) and decide whether to allow the server to see it.
See General fields: _meta for notes on _meta usage.
The name of the model that generated the message.
The reason why sampling stopped, if known.
Metadata for associating messages with a task.
+Include this in the _meta field under the key modelcontextprotocol.io/related-task.
The task identifier this message is associated with.
Metadata for augmenting a request with task execution.
+Include this in the _meta field of a request under the key modelcontextprotocol.io/task.
Requested duration in milliseconds to retain results after completion.
Client-generated unique identifier for the task.
The status of a task.
A request to retrieve the state of a task.
The task identifier to query.
The response to a tasks/get request.
See General fields: _meta for notes on _meta usage.
Error message if status is "failed".
Actual retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A request to retrieve a list of tasks.
Optionalcursor?: stringAn opaque token representing the current pagination position. +If provided, the server should return results starting after this cursor.
The response to a tasks/list request.
See General fields: _meta for notes on _meta usage.
An opaque token representing the pagination position after the last returned result. +If present, there may be more results available.
A summary of a task's state, as returned by tasks/list.
Error message if status is "failed".
Retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A request to retrieve the result of a completed task.
The task identifier to retrieve results for.
The response to a tasks/result request. +The structure matches the result type of the original request. +For example, a tools/call task would return CallToolResult structure.
See General fields: _meta for notes on _meta usage.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
If true, the tool does not modify its environment.
Default: false
If true, this tool is expected to take a long time to execute and +is a good candidate for task-augmented execution. This allows clients +to handle long-running operations asynchronously through the task system.
Default: false
A human-readable title for the tool.
(This property is mean will have no additional effect on its environment.
(This property is meaningful only when readOnlyHint == false)
Default: false
If true, this tool may interact with an "open world" of external entities. If false, the tool's domain of interaction is closed. For example, the world of a web search tool is open, whereas that -of a memory tool is not.
Default: true
If true, the tool does not modify its environment.
Default: false
If true, this tool is expected to take a long time to execute and -is a good candidate for task-augmented execution. This allows clients -to handle long-running operations asynchronously through the task system.
Default: false
A human-readable title for the tool.
Default: true
If true, the tool does not modify its environment.
Default: false
If true, this tool is expected to support task-augmented execution. +This allows clients to handle long-running operations through polling +the task system.
Default: false
A human-readable title for the tool.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionaldelete?: booleanWhether the client supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionaldelete?: booleanWhether the server supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
_meta field of a request under the key The status of a task.
A request to delete a task and its associated results.
The task identifier to delete.
The response to a tasks/delete request.
See General fields: _meta for notes on _meta usage.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionaldelete?: booleanWhether the client supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests.
Optionalrequests?: {Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionaldelete?: booleanWhether the client supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests. Nested properties indicate which specific request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionaldelete?: booleanWhether the server supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests.
Optionalrequests?: {Specifies which request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionaldelete?: booleanWhether the server supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
_meta field of a request under the key The response to a tasks/get request.
See General fields: _meta for notes on _meta usage.
Error message if status is "failed".
Actual retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
The response to a tasks/get request.
See General fields: _meta for notes on _meta usage.
Error message if status is "failed".
Actual retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A summary of a task's state, as returned by tasks/list.
Error message if status is "failed".
Retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A summary of a task's state, as returned by tasks/list.
Error message if status is "failed".
Retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A notification from the receiver to the requestor, informing them that a task has been created and is ready for polling.
Optional_meta?: {The _meta field MUST include modelcontextprotocol.io/related-task with the taskId.
An optional notification from the receiver to the requestor, informing them that a task's status has changed. Receivers are not required to send these notifications.
Parameters for a notifications/tasks/status notification.
The _meta field MUST include modelcontextprotocol.io/related-task with the taskId.
Error message if status is "failed".
The new task status.
_meta field of a request under the key The response to a tasks/delete request.
See General fields: _meta for notes on _meta usage.
The response to a tasks/delete request.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests.
Optionalrequests?: {Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalroots?: { list?: boolean }Task support for roots-related requests.
Optionallist?: booleanWhether the client supports task-augmented roots/list requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks. This applies when the client acts as a receiver of task-augmented requests from the server.
Optionaldelete?: booleanWhether the client supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the client supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the client supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the client supports task-augmented tasks/result requests.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests.
Optionalrequests?: { elicitation?: { create?: boolean }; sampling?: { createMessage?: boolean } }Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests.
Optionalrequests?: {Specifies which request types can be augmented with tasks.
Optionalprompts?: { get?: boolean; list?: boolean }Task support for prompt-related requests.
Optionalget?: booleanWhether the server supports task-augmented prompts/get requests.
Optionallist?: booleanWhether the server supports task-augmented prompts/list requests.
Optionalresources?: { list?: boolean; read?: boolean }Task support for resource-related requests.
Optionallist?: booleanWhether the server supports task-augmented resources/list requests.
Optionalread?: booleanWhether the server supports task-augmented resources/read requests.
Optionaltasks?: { delete?: boolean; get?: boolean; list?: boolean; result?: boolean }Task support for task management requests. Enables recursive task tracking where task queries themselves can be augmented with tasks.
Optionaldelete?: booleanWhether the server supports task-augmented tasks/delete requests.
Optionalget?: booleanWhether the server supports task-augmented tasks/get requests.
Optionallist?: booleanWhether the server supports task-augmented tasks/list requests.
Optionalresult?: booleanWhether the server supports task-augmented tasks/result requests.
Optionaltools?: { call?: boolean; list?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Optionallist?: booleanWhether the server supports task-augmented tools/list requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests.
Optionalrequests?: { tools?: { call?: boolean } }Specifies which request types can be augmented with tasks.
Optionaltools?: { call?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests.
Optionalrequests?: { elicitation?: { create?: boolean }; sampling?: { createMessage?: boolean } }Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: boolean }Task support for elicitation-related requests.
Optionalcreate?: booleanWhether the client supports task-augmented elicitation/create requests.
Optionalsampling?: { createMessage?: boolean }Task support for sampling-related requests.
OptionalcreateMessage?: booleanWhether the client supports task-augmented sampling/createMessage requests.
Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
Present if the client supports elicitation from the server.
Experimental, non-standard capabilities that the client supports.
Present if the client supports listing roots.
OptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
Present if the client supports sampling from an LLM.
Present if the client supports task-augmented requests.
Optionaldelete?: objectWhether this client supports tasks/delete.
Optionallist?: objectWhether this client supports tasks/list.
Optionalrequests?: { elicitation?: { create?: object }; sampling?: { createMessage?: object } }Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: object }Task support for elicitation-related requests.
Optionalcreate?: objectWhether the client supports task-augmented elicitation/create requests.
Optionalsampling?: { createMessage?: object }Task support for sampling-related requests.
OptionalcreateMessage?: objectWhether the client supports task-augmented sampling/createMessage requests.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests.
Optionalrequests?: { tools?: { call?: boolean } }Specifies which request types can be augmented with tasks.
Optionaltools?: { call?: boolean }Task support for tool-related requests.
Optionalcall?: booleanWhether the server supports task-augmented tools/call requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
Present if the server supports argument autocompletion suggestions.
Experimental, non-standard capabilities that the server supports.
Present if the server supports sending log messages to the client.
Present if the server offers any prompt templates.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
Present if the server offers any resources to read.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
Present if the server supports task-augmented requests.
Optionaldelete?: objectWhether this server supports tasks/delete.
Optionallist?: objectWhether this server supports tasks/list.
Optionalrequests?: { tools?: { call?: object } }Specifies which request types can be augmented with tasks.
Optionaltools?: { call?: object }Task support for tool-related requests.
Optionalcall?: objectWhether the server supports task-augmented tools/call requests.
Present if the server offers any tools to call.
OptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
A response to a task-augmented request.
Metadata for associating messages with a task.
Include this in the _meta field under the key modelcontextprotocol.io/related-task.
The task identifier this message is associated with.
Data associated with a task.
Error message if status is "failed".
Actual retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
Metadata for augmenting a request with task execution.
@@ -550,7 +558,7 @@ Include this in the _meta field of a request under the key
_meta?: { [key: string]: unknown };
error?: string;
keepAlive: null | number;
pollInterval?: number;
status: TaskStatus;
taskId: string;
[key: string]: unknown;
}
The response to a tasks/get request.
See General fields: _meta for notes on _meta usage.
Error message if status is "failed".
Actual retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
The response to a tasks/get request.
_meta field under the key modelconte
### `TaskMetadata`
-Metadata for augmenting a request with task execution.
-Include this in the _meta field of a request under the key modelcontextprotocol.io/task.
keepAlive?: numberRequested duration in milliseconds to retain results after completion.
taskId: stringClient-generated unique identifier for the task.
+Metadata for augmenting a request with task execution.
+Include this in the _meta field of a request under the key modelcontextprotocol.io/task.
keepAlive?: numberRequested duration in milliseconds to retain results after completion.
### `TaskStatus`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index 27c712603..05138cf0b 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -3139,15 +3139,8 @@
"keepAlive": {
"description": "Requested duration in milliseconds to retain results after completion.",
"type": "integer"
- },
- "taskId": {
- "description": "Client-generated unique identifier for the task.",
- "type": "string"
}
},
- "required": [
- "taskId"
- ],
"type": "object"
},
"TaskStatus": {
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 68d20ee62..eec8fdfc9 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -1175,11 +1175,6 @@ export type TaskStatus =
* @category tasks
*/
export interface TaskMetadata {
- /**
- * Client-generated unique identifier for the task.
- */
- taskId: string;
-
/**
* Requested duration in milliseconds to retain results after completion.
*/
From e96ce21126d85b36b33f14688dc59efd1a4db1a9 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 15:00:54 -0800
Subject: [PATCH 25/79] Add stipulation that receivers are allowed to require
tasks
---
.../draft/basic/utilities/tasks.mdx | 21 +++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 415fc1133..9952251b6 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -351,8 +351,8 @@ These requirements apply to all parties that support receiving task-augmented re
### Task Support and Handling
-1. Receivers that do not support task augmentation on a request **MUST** process the request normally, ignoring any task metadata in `_meta`.
-1. Receivers that support task augmentation **MAY** choose which request types support tasks.
+1. Receivers that do not declare the task capability for a request type **MUST** process requests of that type normally, ignoring any task-augmentation metadata if present.
+1. Receivers that do declare the task capability for a request type **MAY** return an error for non-task-augmented requests of that type, requiring requestors to use task augmentation.
### Task ID Requirements
@@ -714,8 +714,25 @@ Receivers **MUST** return standard JSON-RPC errors for the following protocol er
- Receiver rejects a `tasks/delete` request: `-32600` (Invalid request)
- Internal errors: `-32603` (Internal error)
+Additionally, receivers **MAY** return the following errors:
+
+- Non-task-augmented request when receiver requires task augmentation for that request type: `-32600` (Invalid request)
+
Receivers **SHOULD** provide informative error messages to describe the cause of errors.
+**Example: Task augmentation required**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "error": {
+ "code": -32600,
+ "message": "Task augmentation required for tools/call requests"
+ }
+}
+```
+
**Example: Task not found**
```json
From 642c3c78d3dcf317340ffa270f9656670e8a8e52 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 15:17:34 -0800
Subject: [PATCH 26/79] Update tasks/result to block until completion
---
.../draft/basic/utilities/tasks.mdx | 22 ++++---------------
1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 9952251b6..75bdc7cae 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -414,9 +414,9 @@ stateDiagram-v2
### Result Retrieval
1. Receivers that accept a task-augmented request **MUST** return a `CreateTaskResult` as the response. This result **SHOULD** be returned as soon as possible after accepting the task.
-1. Receivers **MUST** only return the actual operation results via `tasks/result` when the task status is `completed`.
-1. Receivers **MUST** return an error if `tasks/result` is called for a task in any other status.
-1. Requestors **MAY** call `tasks/result` multiple times for the same task while it remains available.
+1. When a receiver receives a `tasks/result` request, it **MUST** block the response until the task reaches a terminal status (`completed`, `failed`, `cancelled`, or `unknown`).
+1. For tasks in `completed` status, receivers **MUST** return the actual operation results as specified by the original request type.
+1. For tasks in `failed`, `cancelled`, or `unknown` status, receivers **MUST** return a successful JSON-RPC response containing error or status details in the result structure.
### Associating Task-Related Messages
@@ -710,7 +710,6 @@ Receivers **MUST** return standard JSON-RPC errors for the following protocol er
- Invalid or nonexistent `taskId` in `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/delete`: `-32602` (Invalid params)
- Invalid or nonexistent cursor in `tasks/list`: `-32602` (Invalid params)
-- Attempting to retrieve result when task is not in `completed` status: `-32602` (Invalid params)
- Receiver rejects a `tasks/delete` request: `-32600` (Invalid request)
- Internal errors: `-32603` (Internal error)
@@ -765,19 +764,6 @@ Receivers are not obligated to retain task metadata indefinitely. It is complian
-**Example: Result requested for incomplete task**
-
-```json
-{
- "jsonrpc": "2.0",
- "id": 72,
- "error": {
- "code": -32602,
- "message": "Cannot retrieve result: Task status is 'working', not 'completed'"
- }
-}
-```
-
**Example: Task deletion rejected by receiver**
```json
@@ -810,7 +796,7 @@ When the underlying request does not complete successfully, the task moves to th
}
```
-For tasks that wrap tool call requests, when the tool result has `isError` set to true, the task should reach `failed` status. The error information is conveyed both through the task's `failed` status and through the result structure when retrieved via `tasks/result`.
+For tasks that wrap tool call requests, when the tool result has `isError` set to true, the task should reach `failed` status.
## Security Considerations
From 7d008e0f4e34e0d311f7cd87441a19ee38775a3f Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 15:23:52 -0800
Subject: [PATCH 27/79] Add explicit note that tasks/result can return an error
---
docs/specification/draft/basic/utilities/tasks.mdx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 75bdc7cae..6153ee333 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -415,8 +415,7 @@ stateDiagram-v2
1. Receivers that accept a task-augmented request **MUST** return a `CreateTaskResult` as the response. This result **SHOULD** be returned as soon as possible after accepting the task.
1. When a receiver receives a `tasks/result` request, it **MUST** block the response until the task reaches a terminal status (`completed`, `failed`, `cancelled`, or `unknown`).
-1. For tasks in `completed` status, receivers **MUST** return the actual operation results as specified by the original request type.
-1. For tasks in `failed`, `cancelled`, or `unknown` status, receivers **MUST** return a successful JSON-RPC response containing error or status details in the result structure.
+1. Receivers **MUST** return from `tasks/result` exactly what the underlying request would have returned, whether that is a successful result or a JSON-RPC error.
### Associating Task-Related Messages
@@ -798,6 +797,11 @@ When the underlying request does not complete successfully, the task moves to th
For tasks that wrap tool call requests, when the tool result has `isError` set to true, the task should reach `failed` status.
+The `tasks/result` endpoint returns exactly what the underlying request would have returned:
+
+- If the underlying request resulted in a JSON-RPC error, `tasks/result` **MUST** return that same JSON-RPC error.
+- If the request completed with a JSON-RPC response, `tasks/result` **MUST** return a successful JSON-RPC response containing that result.
+
## Security Considerations
### Task Isolation and Access Control
From d05cfbbc9de90a25083f446cafb07731f0986f16 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 16:03:29 -0800
Subject: [PATCH 28/79] Alter input_required to note tasks/result relation
---
.../draft/basic/utilities/tasks.mdx | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 6153ee333..9eb81bee5 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -399,10 +399,10 @@ stateDiagram-v2
### Input Required Status
-1. When a receiver sends a request associated with a task (e.g., elicitation, sampling), the receiver **SHOULD** move the task to the `input_required` status.
+1. When the task receiver has messages for the requestor that are necessary to complete the task, the receiver **SHOULD** move the task to the `input_required` status.
1. The receiver **MUST** include the `modelcontextprotocol.io/related-task` metadata in the request to associate it with the task.
-1. When the receiver receives all required responses, the task **MAY** transition out of `input_required` status (typically back to `working`).
-1. If multiple related requests are pending, the task **SHOULD** remain in `input_required` status until all are resolved.
+1. When the requestor encounters the `input_required` status, it **SHOULD** call `tasks/result` prematurely.
+1. When the receiver receives all required input, the task **SHOULD** transition out of `input_required` status (typically back to `working`).
### Keep-Alive and Resource Management
@@ -414,8 +414,9 @@ stateDiagram-v2
### Result Retrieval
1. Receivers that accept a task-augmented request **MUST** return a `CreateTaskResult` as the response. This result **SHOULD** be returned as soon as possible after accepting the task.
-1. When a receiver receives a `tasks/result` request, it **MUST** block the response until the task reaches a terminal status (`completed`, `failed`, `cancelled`, or `unknown`).
-1. Receivers **MUST** return from `tasks/result` exactly what the underlying request would have returned, whether that is a successful result or a JSON-RPC error.
+1. When a receiver receives a `tasks/result` request for a task in a terminal status (`completed`, `failed`, `cancelled`, or `unknown`), it **MUST** return the final result of the underlying request, whether that is a successful result or a JSON-RPC error.
+1. When a receiver receives a `tasks/result` request for a task in any other non-terminal status (`submitted`, `working`, `input_required`), it **MUST** block the response until the task reaches a terminal status.
+1. For tasks in a terminal status, receivers **MUST** return from `tasks/result` exactly what the underlying request would have returned, whether that is a successful result or a JSON-RPC error.
### Associating Task-Related Messages
@@ -425,11 +426,11 @@ stateDiagram-v2
### Task Cancellation
+1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
1. When a receiver receives a `notifications/cancelled` notification for the JSON-RPC request ID of a task-augmented request, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
1. Due to the asynchronous nature of notifications, receivers **MAY** not cancel task processing instantaneously. Receivers **SHOULD** make a best-effort attempt to halt execution as quickly as possible.
1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, `cancelled`, or `unknown`), receivers **SHOULD** ignore the notification.
1. After a task reaches `cancelled` status and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its metadata.
-1. Requestors **MAY** send `notifications/cancelled` at any time during task execution, including when the task is in `input_required` status. If a task is cancelled while in `input_required` status, receivers **SHOULD** also disregard any pending responses to associated requests.
1. Because notifications do not provide confirmation of receipt, requestors **SHOULD** continue to poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status. If the task does not transition to `cancelled` within a reasonable timeframe, requestors **MAY** assume the cancellation was not processed.
### Task Listing
@@ -501,15 +502,15 @@ sequenceDiagram
C->>S: tasks/get (task-123)
S->>C: working
- Note over S: Server requires additional information
Task moves to input_required
+ Note over S: Server needs information from client
Task moves to input_required
- Note over S,C: Server sends elicitation request
- S->>C: elicitation/create (task-123)
-
- Note over C,S: Client polls and sees task waiting for input
+ Note over C,S: Client polls and discovers input_required
C->>S: tasks/get (task-123)
S->>C: input_required
+ Note over C,S: Client receives input requests
+ C->>S: tasks/result (task-123)
+ S->>C: elicitation/create (task-123)
C->>U: Prompt user for input
U->>C: Provide information
C->>S: elicitation response (task-123)
@@ -660,7 +661,7 @@ Tasks can be in one of the following states:
- `submitted`: The request has been received and queued for execution
- `working`: The request is currently being processed
-- `input_required`: The request is waiting on additional input from the requestor
+- `input_required`: The receiver needs input from the requestor. The requestor should call `tasks/result` to receive input requests, even though the task has not reached a terminal state.
- `completed`: The request completed successfully and results are available
- `failed`: The associated request did not complete successfully. For tool calls specifically, this includes cases where the tool call result has `isError` set to true.
- `cancelled`: The request was cancelled before completion
From dbc2b0a3bd15f7a4aad0d2ccab9a8493ab8b73a5 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 16:13:04 -0800
Subject: [PATCH 29/79] Remove submitted and unknown statuses
---
.../draft/basic/utilities/tasks.mdx | 37 +++++++------------
docs/specification/draft/schema.mdx | 2 +-
schema/draft/schema.json | 2 -
schema/draft/schema.ts | 4 +-
4 files changed, 15 insertions(+), 30 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 9eb81bee5..cc72ea274 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -121,7 +121,7 @@ To create a task, requestors send a request with the `modelcontextprotocol.io/ta
"id": 1,
"result": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
- "status": "submitted",
+ "status": "working",
"keepAlive": 60000,
"pollInterval": 5000,
"_meta": {
@@ -162,7 +162,7 @@ To retrieve the state of a task, requestors send a `tasks/get` request:
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
"keepAlive": 30000,
"pollInterval": 5000,
- "status": "submitted",
+ "status": "working",
"_meta": {
"modelcontextprotocol.io/related-task": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
@@ -362,23 +362,17 @@ These requirements apply to all parties that support receiving task-augmented re
### Task Status Lifecycle
-1. Tasks **MUST** begin in the `submitted` status when created.
+1. Tasks **MUST** begin in the `working` status when created.
1. Receivers **MUST** only transition tasks through the following valid paths:
- 1. From `submitted`: may move to `working`, `input_required`, `completed`, `failed`, `cancelled`, or `unknown`
- 1. From `working`: may move to `input_required`, `completed`, `failed`, `cancelled`, or `unknown`
- 1. From `input_required`: may move to `working`, `completed`, `failed`, `cancelled`, or `unknown`
- 1. Tasks in `completed`, `failed`, `cancelled`, or `unknown` status **MUST NOT** transition to any other status (terminal states)
-1. Receivers **MAY** move directly from `submitted` to `completed` if execution completes immediately.
-1. The `unknown` status is a terminal fallback state for unexpected error conditions. Receivers **SHOULD** use `failed` with an error message instead when possible.
+ 1. From `working`: may move to `input_required`, `completed`, `failed`, or `cancelled`
+ 1. From `input_required`: may move to `working`, `completed`, `failed`, or `cancelled`
+ 1. Tasks in `completed`, `failed`, or `cancelled` status **MUST NOT** transition to any other status (terminal states)
**Task Status State Diagram:**
```mermaid
stateDiagram-v2
- [*] --> submitted
-
- submitted --> working
- submitted --> terminal
+ [*] --> working
working --> input_required
working --> terminal
@@ -393,7 +387,6 @@ stateDiagram-v2
• completed
• failed
• cancelled
- • unknown
end note
```
@@ -414,8 +407,8 @@ stateDiagram-v2
### Result Retrieval
1. Receivers that accept a task-augmented request **MUST** return a `CreateTaskResult` as the response. This result **SHOULD** be returned as soon as possible after accepting the task.
-1. When a receiver receives a `tasks/result` request for a task in a terminal status (`completed`, `failed`, `cancelled`, or `unknown`), it **MUST** return the final result of the underlying request, whether that is a successful result or a JSON-RPC error.
-1. When a receiver receives a `tasks/result` request for a task in any other non-terminal status (`submitted`, `working`, `input_required`), it **MUST** block the response until the task reaches a terminal status.
+1. When a receiver receives a `tasks/result` request for a task in a terminal status (`completed`, `failed`, or `cancelled`), it **MUST** return the final result of the underlying request, whether that is a successful result or a JSON-RPC error.
+1. When a receiver receives a `tasks/result` request for a task in any other non-terminal status (`working` or `input_required`), it **MUST** block the response until the task reaches a terminal status.
1. For tasks in a terminal status, receivers **MUST** return from `tasks/result` exactly what the underlying request would have returned, whether that is a successful result or a JSON-RPC error.
### Associating Task-Related Messages
@@ -429,7 +422,7 @@ stateDiagram-v2
1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
1. When a receiver receives a `notifications/cancelled` notification for the JSON-RPC request ID of a task-augmented request, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
1. Due to the asynchronous nature of notifications, receivers **MAY** not cancel task processing instantaneously. Receivers **SHOULD** make a best-effort attempt to halt execution as quickly as possible.
-1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, `cancelled`, or `unknown`), receivers **SHOULD** ignore the notification.
+1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification.
1. After a task reaches `cancelled` status and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its metadata.
1. Because notifications do not provide confirmation of receipt, requestors **SHOULD** continue to poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status. If the task does not transition to `cancelled` within a reasonable timeframe, requestors **MAY** assume the cancellation was not processed.
@@ -457,12 +450,10 @@ sequenceDiagram
participant S as Server (Receiver)
Note over C,S: 1. Task Creation
C->>S: Request with task metadata (taskId, keepAlive)
- S->>C: CreateTaskResult (taskId, status: submitted, keepAlive, pollInterval)
+ S->>C: CreateTaskResult (taskId, status: working, keepAlive, pollInterval)
S--)C: notifications/tasks/created
Note over C,S: 2. Task Polling
C->>S: tasks/get (taskId)
- S->>C: submitted
- C->>S: tasks/get (taskId)
S->>C: working
Note over S: Task processing continues...
C->>S: tasks/get (taskId)
@@ -491,7 +482,7 @@ sequenceDiagram
Note over C,S: Client augments with task metadata
C->>S: tools/call (task-123, keepAlive: 3600000)
- S->>C: CreateTaskResult (task-123, status: submitted)
+ S->>C: CreateTaskResult (task-123, status: working)
S--)C: notifications/tasks/created
Note over LLM,C: Client continues processing other requests
while task executes in background
@@ -548,7 +539,7 @@ sequenceDiagram
Note over S,C: Server requests client operation (task-augmented)
S->>C: sampling/createMessage (request-789, keepAlive: 3600000)
- C->>S: CreateTaskResult (request-789, status: submitted)
+ C->>S: CreateTaskResult (request-789, status: working)
C--)S: notifications/tasks/created
Note over S: Server continues processing
while waiting for result
@@ -659,13 +650,11 @@ A task represents the execution state of a request. The task metadata includes:
Tasks can be in one of the following states:
-- `submitted`: The request has been received and queued for execution
- `working`: The request is currently being processed
- `input_required`: The receiver needs input from the requestor. The requestor should call `tasks/result` to receive input requests, even though the task has not reached a terminal state.
- `completed`: The request completed successfully and results are available
- `failed`: The associated request did not complete successfully. For tool calls specifically, this includes cases where the tool call result has `isError` set to true.
- `cancelled`: The request was cancelled before completion
-- `unknown`: A terminal fallback state for unexpected error conditions when the receiver cannot determine the actual task state
### Task Metadata
diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx
index 6573c0755..4e2cf040a 100644
--- a/docs/specification/draft/schema.mdx
+++ b/docs/specification/draft/schema.mdx
@@ -538,7 +538,7 @@ Include this in the _meta field of a request under the key TaskStatus:
| "submitted"
| "working"
| "input_required"
| "completed"
| "failed"
| "cancelled"
| "unknown"The status of a task.
+TaskStatus: "working" | "input_required" | "completed" | "failed" | "cancelled"The status of a task.
## `tasks/delete`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index 05138cf0b..a72fb5bff 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -3150,8 +3150,6 @@
"completed",
"failed",
"input_required",
- "submitted",
- "unknown",
"working"
],
"type": "string"
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index eec8fdfc9..18e40e6b8 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -1160,13 +1160,11 @@ export interface Tool extends BaseMetadata, Icons {
* @category tasks
*/
export type TaskStatus =
- | "submitted" // The request has been received and queued for execution
| "working" // The request is currently being processed
| "input_required" // The task is waiting for input (e.g., elicitation or sampling)
| "completed" // The request completed successfully and results are available
| "failed" // The associated request did not complete successfully. For tool calls specifically, this includes cases where the tool call result has `isError` set to true.
- | "cancelled" // The request was cancelled before completion
- | "unknown"; // A terminal fallback state for unexpected error conditions
+ | "cancelled"; // The request was cancelled before completion
/**
* Metadata for augmenting a request with task execution.
From 8169347c5e4d44555b70a2b36ae72e8ac43f53c8 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 16:32:23 -0800
Subject: [PATCH 30/79] Update cancellation to reflect CreateTaskResult
semantics
---
.../draft/basic/utilities/cancellation.mdx | 48 +++++++++++++++----
.../draft/basic/utilities/tasks.mdx | 7 ++-
docs/specification/draft/schema.mdx | 10 +++-
schema/draft/schema.json | 13 ++---
schema/draft/schema.ts | 23 +++++++--
5 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/cancellation.mdx b/docs/specification/draft/basic/utilities/cancellation.mdx
index 1669b418c..1509b0b6f 100644
--- a/docs/specification/draft/basic/utilities/cancellation.mdx
+++ b/docs/specification/draft/basic/utilities/cancellation.mdx
@@ -15,9 +15,12 @@ indicate that a previously-issued request should be terminated.
When a party wants to cancel an in-progress request, it sends a `notifications/cancelled`
notification containing:
-- The ID of the request to cancel
+- For non-task requests: The ID of the request to cancel
+- For task cancellation: The ID of the task to cancel
- An optional reason string that can be logged or displayed
+### Cancelling Non-Task Requests
+
```json
{
"jsonrpc": "2.0",
@@ -29,23 +32,49 @@ notification containing:
}
```
+### Cancelling Tasks
+
+For task-augmented requests, once the `CreateTaskResult` is returned, the original request is complete and `requestId` becomes ambiguous. Therefore, task cancellation **MUST** use `taskId`:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "method": "notifications/cancelled",
+ "params": {
+ "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
+ "reason": "User requested cancellation"
+ }
+}
+```
+
## Behavior Requirements
-1. Cancellation notifications **MUST** only reference requests that:
+### General Requirements
+
+1. Cancellation notifications **MUST** only reference requests or tasks that:
- Were previously issued in the same direction
- Are believed to still be in-progress
2. The `initialize` request **MUST NOT** be cancelled by clients
3. Receivers of cancellation notifications **SHOULD**:
- - Stop processing the cancelled request
+ - Stop processing the cancelled request or task
- Free associated resources
- - Not send a response for the cancelled request
+ - For non-task requests: Not send a response for the cancelled request
+ - For tasks: Move the task to `cancelled` status
4. Receivers **MAY** ignore cancellation notifications if:
- - The referenced request is unknown
- - Processing has already completed
- - The request cannot be cancelled
+ - The referenced request or task is unknown
+ - Processing has already completed (for non-task requests) or reached a terminal status (for tasks)
+ - The request or task cannot be cancelled
5. The sender of the cancellation notification **SHOULD** ignore any response to the
request that arrives afterward
+### Task-Specific Requirements
+
+1. For task cancellation, `taskId` **MUST** be provided (not `requestId`)
+2. `requestId` **MUST NOT** be used for task cancellation once `CreateTaskResult` has been returned
+3. When a receiver receives a `notifications/cancelled` notification with a `taskId`, it **SHOULD** immediately move the task to `cancelled` status
+4. If a cancellation notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification
+5. Requestors **SHOULD** poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status
+
## Timing Considerations
Due to network latency, cancellation notifications may arrive after request processing
@@ -77,9 +106,10 @@ sequenceDiagram
Invalid cancellation notifications **SHOULD** be ignored:
-- Unknown request IDs
-- Already completed requests
+- Unknown request IDs or task IDs
+- Already completed requests or tasks in terminal status
- Malformed notifications
+- Using `requestId` for task cancellation (should use `taskId` instead)
This maintains the "fire and forget" nature of notifications while allowing for race
conditions in asynchronous communication.
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index cc72ea274..b7e99c621 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -420,7 +420,10 @@ stateDiagram-v2
### Task Cancellation
1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
-1. When a receiver receives a `notifications/cancelled` notification for the JSON-RPC request ID of a task-augmented request, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
+1. For task cancellation, the `notifications/cancelled` notification **MUST** include a `taskId` field:
+ 1. The `taskId` **MUST** correspond to a task previously created in the same direction.
+ 1. Once a task-augmented request returns `CreateTaskResult`, the original request is complete and `requestId` becomes ambiguous. Therefore, `requestId` **MUST NOT** be used for task cancellation.
+1. When a receiver receives a `notifications/cancelled` notification with a `taskId`, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
1. Due to the asynchronous nature of notifications, receivers **MAY** not cancel task processing instantaneously. Receivers **SHOULD** make a best-effort attempt to halt execution as quickly as possible.
1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification.
1. After a task reaches `cancelled` status and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its metadata.
@@ -590,7 +593,7 @@ sequenceDiagram
Note over C,S: 3. Client Cancellation
Note over C: User requests cancellation
- C--)S: notifications/cancelled (requestId: 42)
+ C--)S: notifications/cancelled (taskId: task-123)
Note over S: Server processes cancellation
Note over S: Task moves to cancelled status
diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx
index 4e2cf040a..453c1bcae 100644
--- a/docs/specification/draft/schema.mdx
+++ b/docs/specification/draft/schema.mdx
@@ -315,11 +315,17 @@ Contains values matching the requested schema. interface CancelledNotification {
jsonrpc: "2.0";
method: "notifications/cancelled";
params: CancelledNotificationParams;
}This notification can be sent by either side to indicate that it is cancelling a previously-issued request.
The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
This notification indicates that the result will be unused, so any associated processing SHOULD cease.
A client MUST NOT attempt to cancel its initialize request.
+interface CancelledNotification {
jsonrpc: "2.0";
method: "notifications/cancelled";
params: CancelledNotificationParams;
}This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.
The request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
This notification indicates that the result will be unused, so any associated processing SHOULD cease.
A client MUST NOT attempt to cancel its initialize request.
For non-task requests, use requestId to cancel the request.
+For task cancellation, use taskId to cancel the task. Once a task-augmented request returns CreateTaskResult,
+the original request is complete and requestId becomes ambiguous - only taskId should be used for cancellation.
### `CancelledNotificationParams`
-interface CancelledNotificationParams {
_meta?: { [key: string]: unknown };
reason?: string;
requestId: RequestId;
}Parameters for a notifications/cancelled notification.
_meta?: { [key: string]: unknown }See General fields: _meta for notes on _meta usage.
reason?: stringAn optional string describing the reason for the cancellation. This MAY be logged or presented to the user.
The ID of the request to cancel.
This MUST correspond to the ID of a request previously issued in the same direction.
+interface CancelledNotificationParams {
_meta?: { [key: string]: unknown };
reason?: string;
requestId?: RequestId;
taskId?: string;
}Parameters for a notifications/cancelled notification.
For non-task requests: requestId MUST be provided.
+For task cancellation: taskId MUST be provided (using requestId is not supported once the task has been created).
_meta?: { [key: string]: unknown }See General fields: _meta for notes on _meta usage.
reason?: stringAn optional string describing the reason for the cancellation. This MAY be logged or presented to the user.
The ID of the request to cancel.
This MUST correspond to the ID of a request previously issued in the same direction.
+This MUST be provided for cancelling non-task requests.
+This MUST NOT be used for cancelling tasks (use taskId instead).
taskId?: stringThe ID of the task to cancel.
This MUST correspond to the ID of a task previously created in the same direction.
+This MUST be provided for cancelling tasks.
## `notifications/initialized`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index a72fb5bff..2c85f38d5 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -209,7 +209,7 @@
"type": "object"
},
"CancelledNotification": {
- "description": "This notification can be sent by either side to indicate that it is cancelling a previously-issued request.\n\nThe request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.\n\nThis notification indicates that the result will be unused, so any associated processing SHOULD cease.\n\nA client MUST NOT attempt to cancel its `initialize` request.",
+ "description": "This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.\n\nThe request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.\n\nThis notification indicates that the result will be unused, so any associated processing SHOULD cease.\n\nA client MUST NOT attempt to cancel its `initialize` request.\n\nFor non-task requests, use `requestId` to cancel the request.\nFor task cancellation, use `taskId` to cancel the task. Once a task-augmented request returns `CreateTaskResult`,\nthe original request is complete and `requestId` becomes ambiguous - only `taskId` should be used for cancellation.",
"properties": {
"jsonrpc": {
"const": "2.0",
@@ -231,7 +231,7 @@
"type": "object"
},
"CancelledNotificationParams": {
- "description": "Parameters for a `notifications/cancelled` notification.",
+ "description": "Parameters for a `notifications/cancelled` notification.\n\nFor non-task requests: `requestId` MUST be provided.\nFor task cancellation: `taskId` MUST be provided (using `requestId` is not supported once the task has been created).",
"properties": {
"_meta": {
"additionalProperties": {},
@@ -244,12 +244,13 @@
},
"requestId": {
"$ref": "#/definitions/RequestId",
- "description": "The ID of the request to cancel.\n\nThis MUST correspond to the ID of a request previously issued in the same direction."
+ "description": "The ID of the request to cancel.\n\nThis MUST correspond to the ID of a request previously issued in the same direction.\nThis MUST be provided for cancelling non-task requests.\nThis MUST NOT be used for cancelling tasks (use `taskId` instead)."
+ },
+ "taskId": {
+ "description": "The ID of the task to cancel.\n\nThis MUST correspond to the ID of a task previously created in the same direction.\nThis MUST be provided for cancelling tasks.",
+ "type": "string"
}
},
- "required": [
- "requestId"
- ],
"type": "object"
},
"ClientCapabilities": {
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 18e40e6b8..1084ef2ec 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -149,6 +149,9 @@ export type EmptyResult = Result;
/**
* Parameters for a `notifications/cancelled` notification.
*
+ * For non-task requests: `requestId` MUST be provided.
+ * For task cancellation: `taskId` MUST be provided (using `requestId` is not supported once the task has been created).
+ *
* @category notifications/cancelled
*/
export interface CancelledNotificationParams extends NotificationParams {
@@ -156,8 +159,18 @@ export interface CancelledNotificationParams extends NotificationParams {
* The ID of the request to cancel.
*
* This MUST correspond to the ID of a request previously issued in the same direction.
+ * This MUST be provided for cancelling non-task requests.
+ * This MUST NOT be used for cancelling tasks (use `taskId` instead).
+ */
+ requestId?: RequestId;
+
+ /**
+ * The ID of the task to cancel.
+ *
+ * This MUST correspond to the ID of a task previously created in the same direction.
+ * This MUST be provided for cancelling tasks.
*/
- requestId: RequestId;
+ taskId?: string;
/**
* An optional string describing the reason for the cancellation. This MAY be logged or presented to the user.
@@ -166,14 +179,18 @@ export interface CancelledNotificationParams extends NotificationParams {
}
/**
- * This notification can be sent by either side to indicate that it is cancelling a previously-issued request.
+ * This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.
*
- * The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
+ * The request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
*
* This notification indicates that the result will be unused, so any associated processing SHOULD cease.
*
* A client MUST NOT attempt to cancel its `initialize` request.
*
+ * For non-task requests, use `requestId` to cancel the request.
+ * For task cancellation, use `taskId` to cancel the task. Once a task-augmented request returns `CreateTaskResult`,
+ * the original request is complete and `requestId` becomes ambiguous - only `taskId` should be used for cancellation.
+ *
* @category notifications/cancelled
*/
export interface CancelledNotification extends JSONRPCNotification {
From 8a675ea6fcc7500302f45e8349e3541645baf9da Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 7 Nov 2025 16:50:04 -0800
Subject: [PATCH 31/79] Update progress spec to reflect task semantics
---
docs/specification/draft/basic/utilities/progress.mdx | 4 ++++
docs/specification/draft/basic/utilities/tasks.mdx | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/docs/specification/draft/basic/utilities/progress.mdx b/docs/specification/draft/basic/utilities/progress.mdx
index df51ef958..95a4c561d 100644
--- a/docs/specification/draft/basic/utilities/progress.mdx
+++ b/docs/specification/draft/basic/utilities/progress.mdx
@@ -68,6 +68,10 @@ The receiver **MAY** then send progress notifications containing:
- Send notifications at whatever frequency they deem appropriate
- Omit the total value if unknown
+3. For task-augmented requests, the `progressToken` provided in the original request **MUST** continue to be used for progress notifications throughout the task's lifetime, even after the `CreateTaskResult` has been returned. The progress token remains valid and associated with the task until the task reaches a terminal status.
+ - Progress notifications for tasks **MUST** use the same `progressToken` that was provided in the initial task-augmented request
+ - Progress notifications for tasks **MUST** stop after the task reaches a terminal status (`completed`, `failed`, or `cancelled`)
+
```mermaid
sequenceDiagram
participant Sender
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index b7e99c621..8b7894f07 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -417,6 +417,10 @@ stateDiagram-v2
1. For example, an elicitation that a task-augmented tool call depends on **MUST** share the same related task ID with that tool call's task.
1. For the `tasks/get`, `tasks/list`, `tasks/result`, and `tasks/delete` operations, the `taskId` parameter in the request **MUST** be used as the source of truth for identifying the target task. Requestors **SHOULD NOT** include `modelcontextprotocol.io/related-task` metadata in these requests, and receivers **MUST** ignore such metadata if present in favor of the RPC method parameter.
+### Task Progress Notifications
+
+Task-augmented requests support progress notifications as defined in the progress notification specification. The `progressToken` provided in the initial request remains valid throughout the task's lifetime.
+
### Task Cancellation
1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
From 13c683538dec3e157ca8c771061d32f29a443926 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Mon, 10 Nov 2025 10:58:28 -0800
Subject: [PATCH 32/79] Add optional statusMessage field
---
docs/specification/draft/basic/utilities/tasks.mdx | 2 ++
docs/specification/draft/schema.mdx | 2 +-
schema/draft/schema.json | 4 ++++
schema/draft/schema.ts | 5 +++++
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 8b7894f07..4b41cf7a0 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -122,6 +122,7 @@ To create a task, requestors send a request with the `modelcontextprotocol.io/ta
"result": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
"status": "working",
+ "statusMessage": "The operation is now in progress.",
"keepAlive": 60000,
"pollInterval": 5000,
"_meta": {
@@ -163,6 +164,7 @@ To retrieve the state of a task, requestors send a `tasks/get` request:
"keepAlive": 30000,
"pollInterval": 5000,
"status": "working",
+ "statusMessage": "The operation is now in progress.",
"_meta": {
"modelcontextprotocol.io/related-task": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx
index 453c1bcae..4b2a831fa 100644
--- a/docs/specification/draft/schema.mdx
+++ b/docs/specification/draft/schema.mdx
@@ -535,7 +535,7 @@ Include this in the _meta field under the key modelconte
### `Task`
-interface Task {
error?: string;
keepAlive: null | number;
pollInterval?: number;
status: TaskStatus;
taskId: string;
}Data associated with a task.
error?: stringError message if status is "failed".
keepAlive: null | numberActual retention duration in milliseconds, null for unlimited.
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
taskId: stringThe task identifier.
+interface Task {
error?: string;
keepAlive: null | number;
pollInterval?: number;
status: TaskStatus;
statusMessage?: string;
taskId: string;
}Data associated with a task.
error?: stringError message if status is "failed".
keepAlive: null | numberActual retention duration in milliseconds, null for unlimited.
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
statusMessage?: stringCurrent task state message, optional.
taskId: stringThe task identifier.
### `TaskMetadata`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index 2c85f38d5..01e15aaf3 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -3058,6 +3058,10 @@
"$ref": "#/definitions/TaskStatus",
"description": "Current task state."
},
+ "statusMessage": {
+ "description": "Current task state message, optional.",
+ "type": "string"
+ },
"taskId": {
"description": "The task identifier.",
"type": "string"
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 1084ef2ec..491117e0e 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -1225,6 +1225,11 @@ export interface Task {
*/
status: TaskStatus;
+ /**
+ * Current task state message, optional.
+ */
+ statusMessage?: string;
+
/**
* Actual retention duration in milliseconds, null for unlimited.
*/
From b9a9ac4be42d0c0793ba1dac3ce51d3454f875ea Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Mon, 10 Nov 2025 12:08:17 -0800
Subject: [PATCH 33/79] Remove cancellation changes and convert deletion into
cancel RPC method
---
.../draft/basic/utilities/cancellation.mdx | 48 ++-----
.../draft/basic/utilities/tasks.mdx | 114 +++++++++------
docs/specification/draft/schema.mdx | 27 ++--
schema/draft/schema.json | 130 +++++++++++-------
schema/draft/schema.ts | 70 ++++++----
5 files changed, 215 insertions(+), 174 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/cancellation.mdx b/docs/specification/draft/basic/utilities/cancellation.mdx
index 1509b0b6f..1669b418c 100644
--- a/docs/specification/draft/basic/utilities/cancellation.mdx
+++ b/docs/specification/draft/basic/utilities/cancellation.mdx
@@ -15,12 +15,9 @@ indicate that a previously-issued request should be terminated.
When a party wants to cancel an in-progress request, it sends a `notifications/cancelled`
notification containing:
-- For non-task requests: The ID of the request to cancel
-- For task cancellation: The ID of the task to cancel
+- The ID of the request to cancel
- An optional reason string that can be logged or displayed
-### Cancelling Non-Task Requests
-
```json
{
"jsonrpc": "2.0",
@@ -32,49 +29,23 @@ notification containing:
}
```
-### Cancelling Tasks
-
-For task-augmented requests, once the `CreateTaskResult` is returned, the original request is complete and `requestId` becomes ambiguous. Therefore, task cancellation **MUST** use `taskId`:
-
-```json
-{
- "jsonrpc": "2.0",
- "method": "notifications/cancelled",
- "params": {
- "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
- "reason": "User requested cancellation"
- }
-}
-```
-
## Behavior Requirements
-### General Requirements
-
-1. Cancellation notifications **MUST** only reference requests or tasks that:
+1. Cancellation notifications **MUST** only reference requests that:
- Were previously issued in the same direction
- Are believed to still be in-progress
2. The `initialize` request **MUST NOT** be cancelled by clients
3. Receivers of cancellation notifications **SHOULD**:
- - Stop processing the cancelled request or task
+ - Stop processing the cancelled request
- Free associated resources
- - For non-task requests: Not send a response for the cancelled request
- - For tasks: Move the task to `cancelled` status
+ - Not send a response for the cancelled request
4. Receivers **MAY** ignore cancellation notifications if:
- - The referenced request or task is unknown
- - Processing has already completed (for non-task requests) or reached a terminal status (for tasks)
- - The request or task cannot be cancelled
+ - The referenced request is unknown
+ - Processing has already completed
+ - The request cannot be cancelled
5. The sender of the cancellation notification **SHOULD** ignore any response to the
request that arrives afterward
-### Task-Specific Requirements
-
-1. For task cancellation, `taskId` **MUST** be provided (not `requestId`)
-2. `requestId` **MUST NOT** be used for task cancellation once `CreateTaskResult` has been returned
-3. When a receiver receives a `notifications/cancelled` notification with a `taskId`, it **SHOULD** immediately move the task to `cancelled` status
-4. If a cancellation notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification
-5. Requestors **SHOULD** poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status
-
## Timing Considerations
Due to network latency, cancellation notifications may arrive after request processing
@@ -106,10 +77,9 @@ sequenceDiagram
Invalid cancellation notifications **SHOULD** be ignored:
-- Unknown request IDs or task IDs
-- Already completed requests or tasks in terminal status
+- Unknown request IDs
+- Already completed requests
- Malformed notifications
-- Using `requestId` for task cancellation (should use `taskId` instead)
This maintains the "fire and forget" nature of notifications while allowing for race
conditions in asynchronous communication.
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 4b41cf7a0..698265095 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -27,7 +27,7 @@ Servers declare if they support tasks, and if so, which server-side requests can
"capabilities": {
"tasks": {
"list": {},
- "delete": {},
+ "cancel": {},
"requests": {
"tools": {
"call": {}
@@ -47,7 +47,7 @@ Clients declare if they support tasks, and if so, which client-side requests can
"capabilities": {
"tasks": {
"list": {},
- "delete": {},
+ "cancel": {},
"requests": {
"sampling": {
"createMessage": {}
@@ -73,7 +73,7 @@ The set of capabilities in `capabilities.tasks.requests` is exhaustive. If a req
`capabilities.tasks.list` controls if the `tasks/list` operation is supported by the party.
-`capabilities.tasks.delete` controls if the `tasks/delete` operation is supported by the party.
+`capabilities.tasks.cancel` controls if the `tasks/cancel` operation is supported by the party.
### Tool-Level Negotiation
@@ -314,17 +314,17 @@ To retrieve a list of tasks, requestors send a `tasks/list` request. This operat
}
```
-### Deleting Tasks
+### Cancelling Tasks
-To explicitly delete a task and its associated results, requestors send a `tasks/delete` request.
+To explicitly cancel a task, requestors send a `tasks/cancel` request. The request can optionally include a `delete` parameter to immediately delete the task and its results after cancellation.
-**Request:**
+**Request (basic cancellation):**
```json
{
"jsonrpc": "2.0",
"id": 6,
- "method": "tasks/delete",
+ "method": "tasks/cancel",
"params": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
}
@@ -338,6 +338,41 @@ To explicitly delete a task and its associated results, requestors send a `tasks
"jsonrpc": "2.0",
"id": 6,
"result": {
+ "status": "cancelled",
+ "executionStopped": true,
+ "_meta": {
+ "modelcontextprotocol.io/related-task": {
+ "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
+ }
+ }
+ }
+}
+```
+
+**Request (cancellation with deletion):**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 7,
+ "method": "tasks/cancel",
+ "params": {
+ "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
+ "delete": true
+ }
+}
+```
+
+**Response:**
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 7,
+ "result": {
+ "status": "cancelled",
+ "executionStopped": true,
+ "deleted": true,
"_meta": {
"modelcontextprotocol.io/related-task": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
@@ -417,24 +452,12 @@ stateDiagram-v2
1. All requests, notifications, and responses related to a task **MUST** include the `modelcontextprotocol.io/related-task` key in their `_meta`, with the value set to an object with a `taskId` matching the associated task ID.
1. For example, an elicitation that a task-augmented tool call depends on **MUST** share the same related task ID with that tool call's task.
-1. For the `tasks/get`, `tasks/list`, `tasks/result`, and `tasks/delete` operations, the `taskId` parameter in the request **MUST** be used as the source of truth for identifying the target task. Requestors **SHOULD NOT** include `modelcontextprotocol.io/related-task` metadata in these requests, and receivers **MUST** ignore such metadata if present in favor of the RPC method parameter.
+1. For the `tasks/get`, `tasks/list`, `tasks/result`, and `tasks/cancel` operations, the `taskId` parameter in the request **MUST** be used as the source of truth for identifying the target task. Requestors **SHOULD NOT** include `modelcontextprotocol.io/related-task` metadata in these requests, and receivers **MUST** ignore such metadata if present in favor of the RPC method parameter.
### Task Progress Notifications
Task-augmented requests support progress notifications as defined in the progress notification specification. The `progressToken` provided in the initial request remains valid throughout the task's lifetime.
-### Task Cancellation
-
-1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
-1. For task cancellation, the `notifications/cancelled` notification **MUST** include a `taskId` field:
- 1. The `taskId` **MUST** correspond to a task previously created in the same direction.
- 1. Once a task-augmented request returns `CreateTaskResult`, the original request is complete and `requestId` becomes ambiguous. Therefore, `requestId` **MUST NOT** be used for task cancellation.
-1. When a receiver receives a `notifications/cancelled` notification with a `taskId`, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
-1. Due to the asynchronous nature of notifications, receivers **MAY** not cancel task processing instantaneously. Receivers **SHOULD** make a best-effort attempt to halt execution as quickly as possible.
-1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification.
-1. After a task reaches `cancelled` status and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its metadata.
-1. Because notifications do not provide confirmation of receipt, requestors **SHOULD** continue to poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status. If the task does not transition to `cancelled` within a reasonable timeframe, requestors **MAY** assume the cancellation was not processed.
-
### Task Listing
1. Receivers **SHOULD** use cursor-based pagination to limit the number of tasks returned in a single response.
@@ -442,12 +465,14 @@ Task-augmented requests support progress notifications as defined in the progres
1. Requestors **MUST** treat cursors as opaque tokens and not attempt to parse or modify them.
1. If a task is retrievable via `tasks/get` for a requestor, it **MUST** be retrievable via `tasks/list` for that requestor.
-### Task Deletion
+### Task Cancellation
-1. Receivers **MAY** accept or reject delete requests for any task at their discretion.
-1. If a receiver accepts a delete request, it **SHOULD** delete the task and all associated results and metadata.
-1. Receivers **MAY** choose not to support deletion at all, or only support deletion for tasks in certain statuses (e.g., only terminal statuses).
-1. Requestors **SHOULD** delete tasks containing sensitive data promptly rather than relying solely on `keepAlive` expiration for cleanup.
+1. Receivers **MUST** reject cancellation requests for tasks already in a terminal status (`completed`, `failed`, or `cancelled`) with error code `-32602` (Invalid params).
+1. Upon receiving a valid cancellation request, receivers **SHOULD** attempt to stop the task's execution (best effort) and **MUST** transition the task to `cancelled` status before sending the response.
+1. Once a task is cancelled, it **MUST** remain in `cancelled` status even if execution continues to completion or fails.
+1. If the `delete` parameter is `true`, receivers **SHOULD** delete the task and all associated results and metadata after transitioning to `cancelled` status. Receivers **MAY** choose not to support deletion and ignore this parameter.
+1. If the `delete` parameter is `false` or omitted, receivers **MUST** retain the task in `cancelled` status subject to the `keepAlive` duration.
+1. Requestors **SHOULD** use the `delete` parameter to clean up tasks containing sensitive data promptly rather than relying solely on `keepAlive` expiration.
## Message Flow
@@ -591,6 +616,7 @@ sequenceDiagram
Note over C,S: 1. Task Creation
C->>S: tools/call (request ID: 42, task-123)
+ S->>C: CreateTaskResult (task-123, status: working)
S--)C: notifications/tasks/created
Note over C,S: 2. Task Processing
@@ -599,21 +625,19 @@ sequenceDiagram
Note over C,S: 3. Client Cancellation
Note over C: User requests cancellation
- C--)S: notifications/cancelled (taskId: task-123)
+ C->>S: tasks/cancel (taskId: task-123)
- Note over S: Server processes cancellation
+ Note over S: Server stops execution (best effort)
Note over S: Task moves to cancelled status
- Note over C,S: 4. Confirmation Polling
- C->>S: tasks/get (task-123)
- S->>C: cancelled
+ S->>C: Result (status: cancelled, executionStopped: true)
- Note over C: Client confirms cancellation succeeded
+ Note over C: Client receives confirmation
Note over S: After keepAlive period, task cleaned up
```
-### Task Deletion Flow
+### Task Cancellation with Deletion Flow
```mermaid
sequenceDiagram
@@ -622,7 +646,7 @@ sequenceDiagram
Note over C,S: 1. Task Creation and Completion
C->>S: tools/call (task-123)
- S->>C: CreateTaskResult (task-123, status: submitted)
+ S->>C: CreateTaskResult (task-123, status: working)
S--)C: notifications/tasks/created
Note over S: Task processing...
C->>S: tasks/get (task-123)
@@ -632,13 +656,15 @@ sequenceDiagram
C->>S: tasks/result (task-123)
S->>C: Result content
- Note over C,S: 3. Explicit Deletion
+ Note over C,S: 3. Cancellation with Deletion
Note over C: Client decides to clean up task
- C->>S: tasks/delete (task-123)
- S->>C: Success (empty result)
+ C->>S: tasks/cancel (task-123, delete: true)
+ Note over S: Task moves to cancelled status
Note over S: Task and results immediately deleted
+ S->>C: Result (status: cancelled, deleted: true)
+
Note over C,S: 4. Verification (optional)
C->>S: tasks/get (task-123)
S->>C: Error: Task not found
@@ -706,9 +732,9 @@ Tasks use two error reporting mechanisms:
Receivers **MUST** return standard JSON-RPC errors for the following protocol error cases:
-- Invalid or nonexistent `taskId` in `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/delete`: `-32602` (Invalid params)
+- Invalid or nonexistent `taskId` in `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/cancel`: `-32602` (Invalid params)
- Invalid or nonexistent cursor in `tasks/list`: `-32602` (Invalid params)
-- Receiver rejects a `tasks/delete` request: `-32600` (Invalid request)
+- Attempt to cancel a task already in a terminal status: `-32602` (Invalid params)
- Internal errors: `-32603` (Internal error)
Additionally, receivers **MAY** return the following errors:
@@ -762,15 +788,15 @@ Receivers are not obligated to retain task metadata indefinitely. It is complian
-**Example: Task deletion rejected by receiver**
+**Example: Task cancellation rejected (already terminal)**
```json
{
"jsonrpc": "2.0",
"id": 74,
"error": {
- "code": -32600,
- "message": "Task deletion not supported for tasks in 'working' status"
+ "code": -32602,
+ "message": "Cannot cancel task: already in terminal status 'completed'"
}
}
```
@@ -808,20 +834,20 @@ The `tasks/result` endpoint returns exactly what the underlying request would ha
1. Receivers **SHOULD** scope task IDs to prevent unauthorized access:
1. Bind tasks to the session that created them (if sessions are supported)
1. Bind tasks to the authentication context (if authentication is used)
- 1. Reject `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/delete` requests for tasks from different sessions or auth contexts
+ 1. Reject `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/cancel` requests for tasks from different sessions or auth contexts
1. Receivers that do not implement session or authentication binding **SHOULD** document this limitation clearly, as task results may be accessible to any requestor that can guess the task ID.
1. Receivers **SHOULD** implement rate limiting on:
1. Task creation to prevent resource exhaustion
1. Task status polling to prevent denial of service
1. Task result retrieval attempts
1. Task listing requests to prevent denial of service
- 1. Task deletion requests to prevent abuse
+ 1. Task cancellation requests to prevent abuse
### Resource Management
-Task results may persist longer than the original request execution time. For sensitive operations, requestors should carefully consider the security implications of extended result retention and may want to retrieve results promptly and request shorter `keepAlive` durations. Requestors are encouraged to use `tasks/delete` to explicitly clean up tasks containing sensitive data rather than relying solely on `keepAlive` expiration.
+Task results may persist longer than the original request execution time. For sensitive operations, requestors should carefully consider the security implications of extended result retention and may want to retrieve results promptly and request shorter `keepAlive` durations. Requestors are encouraged to use `tasks/cancel` with the `delete` parameter set to `true` to explicitly clean up tasks containing sensitive data rather than relying solely on `keepAlive` expiration.
diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx
index 4b2a831fa..a6099b9ca 100644
--- a/docs/specification/draft/schema.mdx
+++ b/docs/specification/draft/schema.mdx
@@ -27,7 +27,7 @@ the data is entirely optional. interface ClientCapabilities {
elicitation?: object;
experimental?: { [key: string]: object };
roots?: { listChanged?: boolean };
sampling?: object;
tasks?: {
delete?: object;
list?: object;
requests?: {
elicitation?: { create?: object };
sampling?: { createMessage?: object };
};
};
}Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
elicitation?: objectPresent if the client supports elicitation from the server.
experimental?: { [key: string]: object }Experimental, non-standard capabilities that the client supports.
roots?: { listChanged?: boolean }Present if the client supports listing roots.
Type declarationOptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
sampling?: objectPresent if the client supports sampling from an LLM.
tasks?: {
delete?: object;
list?: object;
requests?: {
elicitation?: { create?: object };
sampling?: { createMessage?: object };
};
}Present if the client supports task-augmented requests.
Type declarationOptionaldelete?: objectWhether this client supports tasks/delete.
Optionallist?: objectWhether this client supports tasks/list.
Optionalrequests?: { elicitation?: { create?: object }; sampling?: { createMessage?: object } }Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: object }Task support for elicitation-related requests.
Optionalcreate?: objectWhether the client supports task-augmented elicitation/create requests.
Optionalsampling?: { createMessage?: object }Task support for sampling-related requests.
OptionalcreateMessage?: objectWhether the client supports task-augmented sampling/createMessage requests.
+interface ClientCapabilities {
elicitation?: object;
experimental?: { [key: string]: object };
roots?: { listChanged?: boolean };
sampling?: object;
tasks?: {
cancel?: object;
list?: object;
requests?: {
elicitation?: { create?: object };
sampling?: { createMessage?: object };
};
};
}Capabilities a client may support. Known capabilities are defined here, in this schema, but this is not a closed set: any client can define its own, additional capabilities.
elicitation?: objectPresent if the client supports elicitation from the server.
experimental?: { [key: string]: object }Experimental, non-standard capabilities that the client supports.
roots?: { listChanged?: boolean }Present if the client supports listing roots.
Type declarationOptionallistChanged?: booleanWhether the client supports notifications for changes to the roots list.
sampling?: objectPresent if the client supports sampling from an LLM.
tasks?: {
cancel?: object;
list?: object;
requests?: {
elicitation?: { create?: object };
sampling?: { createMessage?: object };
};
}Present if the client supports task-augmented requests.
Type declarationOptionalcancel?: objectWhether this client supports tasks/cancel.
Optionallist?: objectWhether this client supports tasks/list.
Optionalrequests?: { elicitation?: { create?: object }; sampling?: { createMessage?: object } }Specifies which request types can be augmented with tasks.
Optionalelicitation?: { create?: object }Task support for elicitation-related requests.
Optionalcreate?: objectWhether the client supports task-augmented elicitation/create requests.
Optionalsampling?: { createMessage?: object }Task support for sampling-related requests.
OptionalcreateMessage?: objectWhether the client supports task-augmented sampling/createMessage requests.
### `ContentBlock`
@@ -221,7 +221,7 @@ other URI schemes. interface ServerCapabilities {
completions?: object;
experimental?: { [key: string]: object };
logging?: object;
prompts?: { listChanged?: boolean };
resources?: { listChanged?: boolean; subscribe?: boolean };
tasks?: {
delete?: object;
list?: object;
requests?: { tools?: { call?: object } };
};
tools?: { listChanged?: boolean };
}Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
completions?: objectPresent if the server supports argument autocompletion suggestions.
experimental?: { [key: string]: object }Experimental, non-standard capabilities that the server supports.
logging?: objectPresent if the server supports sending log messages to the client.
prompts?: { listChanged?: boolean }Present if the server offers any prompt templates.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
resources?: { listChanged?: boolean; subscribe?: boolean }Present if the server offers any resources to read.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
tasks?: {
delete?: object;
list?: object;
requests?: { tools?: { call?: object } };
}Present if the server supports task-augmented requests.
Type declarationOptionaldelete?: objectWhether this server supports tasks/delete.
Optionallist?: objectWhether this server supports tasks/list.
Optionalrequests?: { tools?: { call?: object } }Specifies which request types can be augmented with tasks.
Optionaltools?: { call?: object }Task support for tool-related requests.
Optionalcall?: objectWhether the server supports task-augmented tools/call requests.
tools?: { listChanged?: boolean }Present if the server offers any tools to call.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
+interface ServerCapabilities {
completions?: object;
experimental?: { [key: string]: object };
logging?: object;
prompts?: { listChanged?: boolean };
resources?: { listChanged?: boolean; subscribe?: boolean };
tasks?: {
cancel?: object;
list?: object;
requests?: { tools?: { call?: object } };
};
tools?: { listChanged?: boolean };
}Capabilities that a server may support. Known capabilities are defined here, in this schema, but this is not a closed set: any server can define its own, additional capabilities.
completions?: objectPresent if the server supports argument autocompletion suggestions.
experimental?: { [key: string]: object }Experimental, non-standard capabilities that the server supports.
logging?: objectPresent if the server supports sending log messages to the client.
prompts?: { listChanged?: boolean }Present if the server offers any prompt templates.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the prompt list.
resources?: { listChanged?: boolean; subscribe?: boolean }Present if the server offers any resources to read.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the resource list.
Optionalsubscribe?: booleanWhether this server supports subscribing to resource updates.
tasks?: {
cancel?: object;
list?: object;
requests?: { tools?: { call?: object } };
}Present if the server supports task-augmented requests.
Type declarationOptionalcancel?: objectWhether this server supports tasks/cancel.
Optionallist?: objectWhether this server supports tasks/list.
Optionalrequests?: { tools?: { call?: object } }Specifies which request types can be augmented with tasks.
Optionaltools?: { call?: object }Task support for tool-related requests.
Optionalcall?: objectWhether the server supports task-augmented tools/call requests.
tools?: { listChanged?: boolean }Present if the server offers any tools to call.
Type declarationOptionallistChanged?: booleanWhether this server supports notifications for changes to the tool list.
### `StringSchema`
@@ -315,17 +315,13 @@ Contains values matching the requested schema. interface CancelledNotification {
jsonrpc: "2.0";
method: "notifications/cancelled";
params: CancelledNotificationParams;
}This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.
The request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
This notification indicates that the result will be unused, so any associated processing SHOULD cease.
A client MUST NOT attempt to cancel its initialize request.
For non-task requests, use requestId to cancel the request.
-For task cancellation, use taskId to cancel the task. Once a task-augmented request returns CreateTaskResult,
-the original request is complete and requestId becomes ambiguous - only taskId should be used for cancellation.
+interface CancelledNotification {
jsonrpc: "2.0";
method: "notifications/cancelled";
params: CancelledNotificationParams;
}This notification can be sent by either side to indicate that it is cancelling a previously-issued request.
The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
This notification indicates that the result will be unused, so any associated processing SHOULD cease.
A client MUST NOT attempt to cancel its initialize request.
For task cancellation, use the tasks/cancel request instead of this notification.
### `CancelledNotificationParams`
-interface CancelledNotificationParams {
_meta?: { [key: string]: unknown };
reason?: string;
requestId?: RequestId;
taskId?: string;
}Parameters for a notifications/cancelled notification.
For non-task requests: requestId MUST be provided.
-For task cancellation: taskId MUST be provided (using requestId is not supported once the task has been created).
_meta?: { [key: string]: unknown }See General fields: _meta for notes on _meta usage.
reason?: stringAn optional string describing the reason for the cancellation. This MAY be logged or presented to the user.
The ID of the request to cancel.
This MUST correspond to the ID of a request previously issued in the same direction.
+
interface CancelledNotificationParams {
_meta?: { [key: string]: unknown };
reason?: string;
requestId?: RequestId;
taskId?: string;
}Parameters for a notifications/cancelled notification.
_meta?: { [key: string]: unknown }See General fields: _meta for notes on _meta usage.
reason?: stringAn optional string describing the reason for the cancellation. This MAY be logged or presented to the user.
The ID of the request to cancel.
This MUST correspond to the ID of a request previously issued in the same direction.
This MUST be provided for cancelling non-task requests.
-This MUST NOT be used for cancelling tasks (use taskId instead).
taskId?: stringThe ID of the task to cancel.
This MUST correspond to the ID of a task previously created in the same direction.
-This MUST be provided for cancelling tasks.
+This MUST NOT be used for cancelling tasks (use the tasks/cancel request instead). taskId?: stringDeprecated: Use the tasks/cancel request instead of this notification for task cancellation.
## `notifications/initialized`
@@ -546,15 +542,18 @@ Include this in the _meta field of a request under the key TaskStatus: "working" | "input_required" | "completed" | "failed" | "cancelled"The status of a task.
-## `tasks/delete`
+## `tasks/cancel`
-### `DeleteTaskRequest`
+### `CancelTaskRequest`
-interface DeleteTaskRequest {
id: RequestId;
jsonrpc: "2.0";
method: "tasks/delete";
params: { taskId: string };
}A request to delete a task and its associated results.
params: { taskId: string }Type declaration- taskId: string
The task identifier to delete.
+interface CancelTaskRequest {
id: RequestId;
jsonrpc: "2.0";
method: "tasks/cancel";
params: { delete?: boolean; taskId: string };
}A request to cancel a task and optionally delete its associated results.
params: { delete?: boolean; taskId: string }Type declarationOptionaldelete?: booleanWhether to delete the task and its results after cancellation.
+If true, the task and all associated results and metadata will be deleted.
+If false or omitted, the task will be retained according to its keepAlive duration.
- taskId: string
The task identifier to cancel.
-### `DeleteTaskResult`
+### `CancelTaskResult`
-The response to a tasks/delete request.
+interface CancelTaskResult {
_meta?: { [key: string]: unknown };
deleted?: boolean;
executionStopped?: boolean;
status: "cancelled";
[key: string]: unknown;
}The response to a tasks/cancel request.
_meta?: { [key: string]: unknown }See General fields: _meta for notes on _meta usage.
deleted?: booleanWhether the task and its results were deleted.
executionStopped?: booleanWhether execution was successfully stopped.
+If not provided, it is unknown whether execution was stopped.
status: "cancelled"The status of the task after cancellation (always "cancelled").
## `tasks/get`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index 01e15aaf3..f77360564 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -208,8 +208,74 @@
],
"type": "object"
},
+ "CancelTaskRequest": {
+ "description": "A request to cancel a task and optionally delete its associated results.",
+ "properties": {
+ "id": {
+ "$ref": "#/definitions/RequestId"
+ },
+ "jsonrpc": {
+ "const": "2.0",
+ "type": "string"
+ },
+ "method": {
+ "const": "tasks/cancel",
+ "type": "string"
+ },
+ "params": {
+ "properties": {
+ "delete": {
+ "description": "Whether to delete the task and its results after cancellation.\nIf true, the task and all associated results and metadata will be deleted.\nIf false or omitted, the task will be retained according to its keepAlive duration.",
+ "type": "boolean"
+ },
+ "taskId": {
+ "description": "The task identifier to cancel.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "taskId"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "id",
+ "jsonrpc",
+ "method",
+ "params"
+ ],
+ "type": "object"
+ },
+ "CancelTaskResult": {
+ "description": "The response to a tasks/cancel request.",
+ "properties": {
+ "_meta": {
+ "additionalProperties": {},
+ "description": "See [General fields: `_meta`](/specification/draft/basic/index#meta) for notes on `_meta` usage.",
+ "type": "object"
+ },
+ "deleted": {
+ "description": "Whether the task and its results were deleted.",
+ "type": "boolean"
+ },
+ "executionStopped": {
+ "description": "Whether execution was successfully stopped.\nIf not provided, it is unknown whether execution was stopped.",
+ "type": "boolean"
+ },
+ "status": {
+ "const": "cancelled",
+ "description": "The status of the task after cancellation (always \"cancelled\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "status"
+ ],
+ "type": "object"
+ },
"CancelledNotification": {
- "description": "This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.\n\nThe request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.\n\nThis notification indicates that the result will be unused, so any associated processing SHOULD cease.\n\nA client MUST NOT attempt to cancel its `initialize` request.\n\nFor non-task requests, use `requestId` to cancel the request.\nFor task cancellation, use `taskId` to cancel the task. Once a task-augmented request returns `CreateTaskResult`,\nthe original request is complete and `requestId` becomes ambiguous - only `taskId` should be used for cancellation.",
+ "description": "This notification can be sent by either side to indicate that it is cancelling a previously-issued request.\n\nThe request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.\n\nThis notification indicates that the result will be unused, so any associated processing SHOULD cease.\n\nA client MUST NOT attempt to cancel its `initialize` request.\n\nFor task cancellation, use the `tasks/cancel` request instead of this notification.",
"properties": {
"jsonrpc": {
"const": "2.0",
@@ -231,7 +297,7 @@
"type": "object"
},
"CancelledNotificationParams": {
- "description": "Parameters for a `notifications/cancelled` notification.\n\nFor non-task requests: `requestId` MUST be provided.\nFor task cancellation: `taskId` MUST be provided (using `requestId` is not supported once the task has been created).",
+ "description": "Parameters for a `notifications/cancelled` notification.",
"properties": {
"_meta": {
"additionalProperties": {},
@@ -244,10 +310,10 @@
},
"requestId": {
"$ref": "#/definitions/RequestId",
- "description": "The ID of the request to cancel.\n\nThis MUST correspond to the ID of a request previously issued in the same direction.\nThis MUST be provided for cancelling non-task requests.\nThis MUST NOT be used for cancelling tasks (use `taskId` instead)."
+ "description": "The ID of the request to cancel.\n\nThis MUST correspond to the ID of a request previously issued in the same direction.\nThis MUST be provided for cancelling non-task requests.\nThis MUST NOT be used for cancelling tasks (use the `tasks/cancel` request instead)."
},
"taskId": {
- "description": "The ID of the task to cancel.\n\nThis MUST correspond to the ID of a task previously created in the same direction.\nThis MUST be provided for cancelling tasks.",
+ "description": "Deprecated: Use the `tasks/cancel` request instead of this notification for task cancellation.",
"type": "string"
}
},
@@ -290,9 +356,9 @@
"tasks": {
"description": "Present if the client supports task-augmented requests.",
"properties": {
- "delete": {
+ "cancel": {
"additionalProperties": true,
- "description": "Whether this client supports tasks/delete.",
+ "description": "Whether this client supports tasks/cancel.",
"properties": {},
"type": "object"
},
@@ -402,7 +468,7 @@
"$ref": "#/definitions/GetTaskPayloadRequest"
},
{
- "$ref": "#/definitions/DeleteTaskRequest"
+ "$ref": "#/definitions/CancelTaskRequest"
},
{
"$ref": "#/definitions/ListTasksRequest"
@@ -427,6 +493,9 @@
{
"$ref": "#/definitions/GetTaskPayloadResult"
},
+ {
+ "$ref": "#/definitions/CancelTaskResult"
+ },
{
"$ref": "#/definitions/ListTasksResult"
},
@@ -729,44 +798,6 @@
"description": "An opaque token used to represent a cursor for pagination.",
"type": "string"
},
- "DeleteTaskRequest": {
- "description": "A request to delete a task and its associated results.",
- "properties": {
- "id": {
- "$ref": "#/definitions/RequestId"
- },
- "jsonrpc": {
- "const": "2.0",
- "type": "string"
- },
- "method": {
- "const": "tasks/delete",
- "type": "string"
- },
- "params": {
- "properties": {
- "taskId": {
- "description": "The task identifier to delete.",
- "type": "string"
- }
- },
- "required": [
- "taskId"
- ],
- "type": "object"
- }
- },
- "required": [
- "id",
- "jsonrpc",
- "method",
- "params"
- ],
- "type": "object"
- },
- "DeleteTaskResult": {
- "$ref": "#/definitions/Result"
- },
"ElicitRequest": {
"description": "A request from the server to elicit additional information from the user via the client.",
"properties": {
@@ -2753,9 +2784,9 @@
"tasks": {
"description": "Present if the server supports task-augmented requests.",
"properties": {
- "delete": {
+ "cancel": {
"additionalProperties": true,
- "description": "Whether this server supports tasks/delete.",
+ "description": "Whether this server supports tasks/cancel.",
"properties": {},
"type": "object"
},
@@ -2842,7 +2873,7 @@
"$ref": "#/definitions/GetTaskPayloadRequest"
},
{
- "$ref": "#/definitions/DeleteTaskRequest"
+ "$ref": "#/definitions/CancelTaskRequest"
},
{
"$ref": "#/definitions/ListTasksRequest"
@@ -2894,6 +2925,9 @@
{
"$ref": "#/definitions/GetTaskPayloadResult"
},
+ {
+ "$ref": "#/definitions/CancelTaskResult"
+ },
{
"$ref": "#/definitions/ListTasksResult"
},
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 491117e0e..8ac2b4a0d 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -149,9 +149,6 @@ export type EmptyResult = Result;
/**
* Parameters for a `notifications/cancelled` notification.
*
- * For non-task requests: `requestId` MUST be provided.
- * For task cancellation: `taskId` MUST be provided (using `requestId` is not supported once the task has been created).
- *
* @category notifications/cancelled
*/
export interface CancelledNotificationParams extends NotificationParams {
@@ -160,15 +157,12 @@ export interface CancelledNotificationParams extends NotificationParams {
*
* This MUST correspond to the ID of a request previously issued in the same direction.
* This MUST be provided for cancelling non-task requests.
- * This MUST NOT be used for cancelling tasks (use `taskId` instead).
+ * This MUST NOT be used for cancelling tasks (use the `tasks/cancel` request instead).
*/
requestId?: RequestId;
/**
- * The ID of the task to cancel.
- *
- * This MUST correspond to the ID of a task previously created in the same direction.
- * This MUST be provided for cancelling tasks.
+ * Deprecated: Use the `tasks/cancel` request instead of this notification for task cancellation.
*/
taskId?: string;
@@ -179,17 +173,15 @@ export interface CancelledNotificationParams extends NotificationParams {
}
/**
- * This notification can be sent by either side to indicate that it is cancelling a previously-issued request or task.
+ * This notification can be sent by either side to indicate that it is cancelling a previously-issued request.
*
- * The request or task SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
+ * The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished.
*
* This notification indicates that the result will be unused, so any associated processing SHOULD cease.
*
* A client MUST NOT attempt to cancel its `initialize` request.
*
- * For non-task requests, use `requestId` to cancel the request.
- * For task cancellation, use `taskId` to cancel the task. Once a task-augmented request returns `CreateTaskResult`,
- * the original request is complete and `requestId` becomes ambiguous - only `taskId` should be used for cancellation.
+ * For task cancellation, use the `tasks/cancel` request instead of this notification.
*
* @category notifications/cancelled
*/
@@ -288,9 +280,9 @@ export interface ClientCapabilities {
*/
list?: object;
/**
- * Whether this client supports tasks/delete.
+ * Whether this client supports tasks/cancel.
*/
- delete?: object;
+ cancel?: object;
/**
* Specifies which request types can be augmented with tasks.
*/
@@ -373,9 +365,9 @@ export interface ServerCapabilities {
*/
list?: object;
/**
- * Whether this server supports tasks/delete.
+ * Whether this server supports tasks/cancel.
*/
- delete?: object;
+ cancel?: object;
/**
* Specifies which request types can be augmented with tasks.
*/
@@ -1302,26 +1294,46 @@ export interface GetTaskPayloadResult extends Result {
}
/**
- * A request to delete a task and its associated results.
+ * A request to cancel a task and optionally delete its associated results.
*
- * @category tasks/delete
+ * @category tasks/cancel
*/
-export interface DeleteTaskRequest extends JSONRPCRequest {
- method: "tasks/delete";
+export interface CancelTaskRequest extends JSONRPCRequest {
+ method: "tasks/cancel";
params: {
/**
- * The task identifier to delete.
+ * The task identifier to cancel.
*/
taskId: string;
+ /**
+ * Whether to delete the task and its results after cancellation.
+ * If true, the task and all associated results and metadata will be deleted.
+ * If false or omitted, the task will be retained according to its keepAlive duration.
+ */
+ delete?: boolean;
};
}
/**
- * The response to a tasks/delete request.
+ * The response to a tasks/cancel request.
*
- * @category tasks/delete
+ * @category tasks/cancel
*/
-export type DeleteTaskResult = Result;
+export interface CancelTaskResult extends Result {
+ /**
+ * The status of the task after cancellation (always "cancelled").
+ */
+ status: "cancelled";
+ /**
+ * Whether execution was successfully stopped.
+ * If not provided, it is unknown whether execution was stopped.
+ */
+ executionStopped?: boolean;
+ /**
+ * Whether the task and its results were deleted.
+ */
+ deleted?: boolean;
+}
/**
* A request to retrieve a list of tasks.
@@ -2037,7 +2049,7 @@ export type ClientRequest =
| GetTaskRequest
| GetTaskPayloadRequest
| ListTasksRequest
- | DeleteTaskRequest;
+ | CancelTaskRequest;
/** @internal */
export type ClientNotification =
@@ -2057,7 +2069,7 @@ export type ClientResult =
| GetTaskResult
| GetTaskPayloadResult
| ListTasksResult
- | DeleteTaskResult;
+ | CancelTaskResult;
/* Server messages */
/** @internal */
@@ -2069,7 +2081,7 @@ export type ServerRequest =
| GetTaskRequest
| GetTaskPayloadRequest
| ListTasksRequest
- | DeleteTaskRequest;
+ | CancelTaskRequest;
/** @internal */
export type ServerNotification =
@@ -2098,4 +2110,4 @@ export type ServerResult =
| GetTaskResult
| GetTaskPayloadResult
| ListTasksResult
- | DeleteTaskResult;
+ | CancelTaskResult;
From aa0629af0faa0d8d1ad7add47c9b8ff1b2dce60f Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Tue, 11 Nov 2025 13:24:39 -0800
Subject: [PATCH 34/79] Replace keepalive with TTL; add createdAt
---
.../draft/basic/utilities/tasks.mdx | 67 ++++++++++---------
docs/specification/draft/schema.mdx | 10 +--
schema/draft/schema.json | 40 ++++++-----
schema/draft/schema.ts | 24 +++++--
4 files changed, 84 insertions(+), 57 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 698265095..61bcb3093 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -90,7 +90,7 @@ Task-augmented requests follow a two-phase response pattern that differs from no
- **Normal requests**: The server processes the request and returns the actual operation result directly.
- **Task-augmented requests**: The server accepts the request and immediately returns a `CreateTaskResult` containing task metadata. The actual operation result becomes available later through `tasks/result` after the task completes.
-To create a task, requestors send a request with the `modelcontextprotocol.io/task` key included in `_meta`. Requestors **MAY** include a `keepAlive` value representing how long after completion the requestor would like the task results to be kept for.
+To create a task, requestors send a request with the `modelcontextprotocol.io/task` key included in `_meta`. Requestors **MAY** include a `ttl` value representing how long from task creation the requestor would like the task to be retained for.
**Request:**
@@ -106,7 +106,7 @@ To create a task, requestors send a request with the `modelcontextprotocol.io/ta
},
"_meta": {
"modelcontextprotocol.io/task": {
- "keepAlive": 60000
+ "ttl": 60000
}
}
}
@@ -123,7 +123,8 @@ To create a task, requestors send a request with the `modelcontextprotocol.io/ta
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
"status": "working",
"statusMessage": "The operation is now in progress.",
- "keepAlive": 60000,
+ "createdAt": "2025-11-25T10:30:00Z",
+ "ttl": 60000,
"pollInterval": 5000,
"_meta": {
"modelcontextprotocol.io/related-task": {
@@ -161,10 +162,11 @@ To retrieve the state of a task, requestors send a `tasks/get` request:
"id": 3,
"result": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
- "keepAlive": 30000,
- "pollInterval": 5000,
"status": "working",
"statusMessage": "The operation is now in progress.",
+ "createdAt": "2025-11-25T10:30:00Z",
+ "ttl": 30000,
+ "pollInterval": 5000,
"_meta": {
"modelcontextprotocol.io/related-task": {
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
@@ -300,13 +302,15 @@ To retrieve a list of tasks, requestors send a `tasks/list` request. This operat
{
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
"status": "working",
- "keepAlive": 30000,
+ "createdAt": "2025-11-25T10:30:00Z",
+ "ttl": 30000,
"pollInterval": 5000
},
{
"taskId": "abc123-def456-ghi789",
"status": "completed",
- "keepAlive": 60000
+ "createdAt": "2025-11-25T09:15:00Z",
+ "ttl": 60000
}
],
"nextCursor": "next-page-cursor"
@@ -434,11 +438,12 @@ stateDiagram-v2
1. When the requestor encounters the `input_required` status, it **SHOULD** call `tasks/result` prematurely.
1. When the receiver receives all required input, the task **SHOULD** transition out of `input_required` status (typically back to `working`).
-### Keep-Alive and Resource Management
+### TTL and Resource Management
-1. Receivers **MAY** override the requested `keepAlive` duration.
-1. Receivers **MUST** include the actual `keepAlive` duration (or `null` for unlimited) in `tasks/get` responses.
-1. After a task reaches a terminal status (`completed`, `failed`, or `cancelled`) and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its results.
+1. Receivers **MUST** include a `createdAt` timestamp (ISO 8601 format) in all task responses to indicate when the task was created.
+1. Receivers **MAY** override the requested `ttl` duration.
+1. Receivers **MUST** include the actual `ttl` duration (or `null` for unlimited) in `tasks/get` responses.
+1. After a task's `ttl` duration has elapsed from creation, receivers **MAY** delete the task and its results, regardless of the task's status.
1. Receivers **MAY** include a `pollInterval` value (in milliseconds) in `tasks/get` responses to suggest polling intervals. Requestors **SHOULD** respect this value when provided.
### Result Retrieval
@@ -471,8 +476,8 @@ Task-augmented requests support progress notifications as defined in the progres
1. Upon receiving a valid cancellation request, receivers **SHOULD** attempt to stop the task's execution (best effort) and **MUST** transition the task to `cancelled` status before sending the response.
1. Once a task is cancelled, it **MUST** remain in `cancelled` status even if execution continues to completion or fails.
1. If the `delete` parameter is `true`, receivers **SHOULD** delete the task and all associated results and metadata after transitioning to `cancelled` status. Receivers **MAY** choose not to support deletion and ignore this parameter.
-1. If the `delete` parameter is `false` or omitted, receivers **MUST** retain the task in `cancelled` status subject to the `keepAlive` duration.
-1. Requestors **SHOULD** use the `delete` parameter to clean up tasks containing sensitive data promptly rather than relying solely on `keepAlive` expiration.
+1. If the `delete` parameter is `false` or omitted, receivers **MUST** retain the task in `cancelled` status subject to the `ttl` duration.
+1. Requestors **SHOULD** use the `delete` parameter to clean up tasks containing sensitive data promptly rather than relying solely on `ttl` expiration.
## Message Flow
@@ -483,8 +488,8 @@ sequenceDiagram
participant C as Client (Requestor)
participant S as Server (Receiver)
Note over C,S: 1. Task Creation
- C->>S: Request with task metadata (taskId, keepAlive)
- S->>C: CreateTaskResult (taskId, status: working, keepAlive, pollInterval)
+ C->>S: Request with task metadata (taskId, ttl)
+ S->>C: CreateTaskResult (taskId, status: working, ttl, pollInterval)
S--)C: notifications/tasks/created
Note over C,S: 2. Task Polling
C->>S: tasks/get (taskId)
@@ -499,7 +504,7 @@ sequenceDiagram
C->>S: tasks/result (taskId)
S->>C: Result content
Note over C,S: 4. Cleanup
- Note over S: After keepAlive period, task is cleaned up
+ Note over S: After ttl period from creation, task is cleaned up
```
### Task-Augmented Tool Call With Elicitation
@@ -515,7 +520,7 @@ sequenceDiagram
LLM->>C: Request operation
Note over C,S: Client augments with task metadata
- C->>S: tools/call (task-123, keepAlive: 3600000)
+ C->>S: tools/call (task-123, ttl: 3600000)
S->>C: CreateTaskResult (task-123, status: working)
S--)C: notifications/tasks/created
@@ -557,7 +562,7 @@ sequenceDiagram
S->>C: Result content
C->>LLM: Process result
- Note over S: Results retained for keepAlive period
+ Note over S: Results retained for ttl period from creation
```
### Task-Augmented Sampling Request
@@ -572,7 +577,7 @@ sequenceDiagram
Note over S: Server decides to initiate request
Note over S,C: Server requests client operation (task-augmented)
- S->>C: sampling/createMessage (request-789, keepAlive: 3600000)
+ S->>C: sampling/createMessage (request-789, ttl: 3600000)
C->>S: CreateTaskResult (request-789, status: working)
C--)S: notifications/tasks/created
@@ -604,7 +609,7 @@ sequenceDiagram
Note over S: Server continues processing
- Note over C: Results retained for keepAlive period
+ Note over C: Results retained for ttl period from creation
```
### Task Cancellation Flow
@@ -634,7 +639,7 @@ sequenceDiagram
Note over C: Client receives confirmation
- Note over S: After keepAlive period, task cleaned up
+ Note over S: After ttl period from creation, task cleaned up
```
### Task Cancellation with Deletion Flow
@@ -677,9 +682,10 @@ sequenceDiagram
A task represents the execution state of a request. The task metadata includes:
- `taskId`: Unique identifier for the task
-- `keepAlive`: Time in milliseconds that results will be kept available after completion
-- `pollInterval`: Suggested time in milliseconds between status checks
- `status`: Current state of the task execution
+- `createdAt`: ISO 8601 timestamp when the task was created
+- `ttl`: Time in milliseconds from creation before task may be deleted
+- `pollInterval`: Suggested time in milliseconds between status checks
### Task Status
@@ -698,14 +704,14 @@ When augmenting a request with task execution, the `modelcontextprotocol.io/task
```json
{
"modelcontextprotocol.io/task": {
- "keepAlive": 60000
+ "ttl": 60000
}
}
```
Fields:
-- `keepAlive` (number, optional): Requested duration in milliseconds to retain results after completion
+- `ttl` (number, optional): Requested duration in milliseconds to retain task from creation
### Related Task Metadata
@@ -812,9 +818,10 @@ When the underlying request does not complete successfully, the task moves to th
"jsonrpc": "2.0",
"id": 4,
"result": {
- "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
+ "taskId": "786512e2-9e0d-44bd-8f29-789f820fe840",
"status": "failed",
- "keepAlive": 30000,
+ "createdAt": "2025-11-25T10:30:00Z",
+ "ttl": 30000,
"error": "Tool execution failed: API rate limit exceeded"
}
}
@@ -847,16 +854,16 @@ The `tasks/result` endpoint returns exactly what the underlying request would ha
-Task results may persist longer than the original request execution time. For sensitive operations, requestors should carefully consider the security implications of extended result retention and may want to retrieve results promptly and request shorter `keepAlive` durations. Requestors are encouraged to use `tasks/cancel` with the `delete` parameter set to `true` to explicitly clean up tasks containing sensitive data rather than relying solely on `keepAlive` expiration.
+Task results may persist for the duration specified by the TTL. For sensitive operations, requestors should carefully consider the security implications of extended task retention and may want to retrieve results promptly and request shorter `ttl` durations. Requestors are encouraged to use `tasks/cancel` with the `delete` parameter set to `true` to explicitly clean up tasks containing sensitive data rather than relying solely on `ttl` expiration.
1. Receivers **SHOULD**:
1. Enforce limits on concurrent tasks per requestor
- 1. Enforce maximum `keepAlive` durations to prevent indefinite resource retention
+ 1. Enforce maximum `ttl` durations to prevent indefinite resource retention
1. Clean up expired tasks promptly to free resources
1. Receivers **SHOULD**:
- 1. Document maximum supported `keepAlive` duration
+ 1. Document maximum supported `ttl` duration
1. Document maximum concurrent tasks per requestor
1. Implement monitoring and alerting for resource usage
diff --git a/docs/specification/draft/schema.mdx b/docs/specification/draft/schema.mdx
index a6099b9ca..232f1e3ce 100644
--- a/docs/specification/draft/schema.mdx
+++ b/docs/specification/draft/schema.mdx
@@ -531,12 +531,12 @@ Include this in the _meta field under the key modelconte
### `Task`
-interface Task {
error?: string;
keepAlive: null | number;
pollInterval?: number;
status: TaskStatus;
statusMessage?: string;
taskId: string;
}Data associated with a task.
error?: stringError message if status is "failed".
keepAlive: null | numberActual retention duration in milliseconds, null for unlimited.
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
statusMessage?: stringCurrent task state message, optional.
taskId: stringThe task identifier.
+interface Task {
createdAt: string;
error?: string;
pollInterval?: number;
status: TaskStatus;
statusMessage?: string;
taskId: string;
ttl: null | number;
}Data associated with a task.
createdAt: stringISO 8601 timestamp when the task was created.
error?: stringError message if status is "failed".
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
statusMessage?: stringCurrent task state message, optional.
taskId: stringThe task identifier.
ttl: null | numberActual retention duration from creation in milliseconds, null for unlimited.
### `TaskMetadata`
-Metadata for augmenting a request with task execution.
-Include this in the _meta field of a request under the key modelcontextprotocol.io/task.
keepAlive?: numberRequested duration in milliseconds to retain results after completion.
+Metadata for augmenting a request with task execution.
+Include this in the _meta field of a request under the key modelcontextprotocol.io/task.
ttl?: numberRequested duration in milliseconds to retain task from creation.
### `TaskStatus`
@@ -548,7 +548,7 @@ Include this in the _meta field of a request under the key interface CancelTaskRequest {
id: RequestId;
jsonrpc: "2.0";
method: "tasks/cancel";
params: { delete?: boolean; taskId: string };
}A request to cancel a task and optionally delete its associated results.
params: { delete?: boolean; taskId: string }Type declarationOptionaldelete?: booleanWhether to delete the task and its results after cancellation.
If true, the task and all associated results and metadata will be deleted.
-If false or omitted, the task will be retained according to its keepAlive duration.
- taskId: string
The task identifier to cancel.
+If false or omitted, the task will be retained according to its ttl duration. taskId: stringThe task identifier to cancel.
A summary of a task's state, as returned by tasks/list.
Error message if status is "failed".
Retention duration in milliseconds, null for unlimited.
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
A summary of a task's state, as returned by tasks/list.
ISO 8601 timestamp when the task was created.
Error message if status is "failed".
Suggested polling interval in milliseconds.
Current task state.
The task identifier.
Retention duration from creation in milliseconds, null for unlimited.
_meta field of a request under the key A request to cancel a task and optionally delete its associated results.
Optionaldelete?: booleanWhether to delete the task and its results after cancellation. -If true, the task and all associated results and metadata will be deleted. -If false or omitted, the task will be retained according to its ttl duration.
The task identifier to cancel.
A request to cancel a task.
The task identifier to cancel.
The response to a tasks/cancel request.
See General fields: _meta for notes on _meta usage.
Whether the task and its results were deleted.
Whether execution was successfully stopped. -If not provided, it is unknown whether execution was stopped.
The status of the task after cancellation (always "cancelled").
The response to a tasks/cancel request.
A notification from the receiver to the requestor, informing them that a task has been created and is ready for polling.
Optional_meta?: {The _meta field MUST include modelcontextprotocol.io/related-task with the taskId.
A notification from the receiver to the requestor, informing them that a task has been created and is ready for polling.
Parameters for a notifications/tasks/created notification.
An optional notification from the receiver to the requestor, informing them that a task's status has changed. Receivers are not required to send these notifications.
An optional notification from the receiver to the requestor, informing them that a task's status has changed. Receivers are not required to send these notifications.
Parameters for a notifications/tasks/status notification.
The _meta field MUST include modelcontextprotocol.io/related-task with the taskId.
Error message if status is "failed".
The new task status.
Parameters for a notifications/tasks/status notification.
Parameters for a tools/call request.
See General fields: _meta for notes on _meta usage.
If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
Inherited from RequestParams._meta
Arguments to use for the tool call.
The name of the tool.
Parameters for a tools/call request.
See General fields: _meta for notes on _meta usage.
If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications.
Inherited from RequestParams._meta
Arguments to use for the tool call.
The name of the tool.
If specified, the caller is requesting task-augmented execution for this request. +The request will return a CreateTaskResult immediately, and the actual result can be +retrieved later via tasks/result.
Task augmentation is subject to capability negotiation - receivers MUST declare support +for task augmentation of specific request types in their capabilities.
Inherited from RequestParams.task
A response to a task-augmented request.
A response to a task-augmented request.
See General fields: _meta for notes on _meta usage.
Inherited from BaseMetadata ### `ToolAnnotations` -
Additional properties describing a Tool to clients.
NOTE: all properties in ToolAnnotations are hints. +
Additional properties describing a Tool to clients.
NOTE: all properties in ToolAnnotations are hints.
They are not guaranteed to provide a faithful description of
tool behavior (including descriptive properties like title).
Clients should never make tool use decisions based on ToolAnnotations received from untrusted servers.
If true, the tool may perform destructive updates to its environment. @@ -740,7 +740,7 @@ If false, the tool performs only additive updates.
(This property is mean will have no additional effect on its environment.
(This property is meaningful only when readOnlyHint == false)
Default: false
If true, this tool may interact with an "open world" of external entities. If false, the tool's domain of interaction is closed. For example, the world of a web search tool is open, whereas that -of a memory tool is not.
Default: true
If true, the tool does not modify its environment.
Default: false
If true, this tool is expected to support task-augmented execution. +of a memory tool is not.
Default: true
If true, the tool does not modify its environment.
Default: false
Indicates whether this tool supports task-augmented execution. This allows clients to handle long-running operations through polling -the task system.
Default: false
A human-readable title for the tool.
Default: "never"
A human-readable title for the tool.
_meta field under the key io.modelco
### `Task`
-interface Task {
createdAt: string;
error?: string;
pollInterval?: number;
status: TaskStatus;
statusMessage?: string;
taskId: string;
ttl: number | null;
}Data associated with a task.
createdAt: stringISO 8601 timestamp when the task was created.
error?: stringError details when status is "failed".
-This field provides diagnostic information about what went wrong and should only
-be present when the task has failed. Use statusMessage for general state descriptions.
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
statusMessage?: stringOptional human-readable message describing the current task state.
-This can provide context for any status (e.g., reasons for "cancelled",
-summaries for "completed", etc.).
taskId: stringThe task identifier.
ttl: number | nullActual retention duration from creation in milliseconds, null for unlimited.
+interface Task {
createdAt: string;
pollInterval?: number;
status: TaskStatus;
statusMessage?: string;
taskId: string;
ttl: number | null;
}Data associated with a task.
createdAt: stringISO 8601 timestamp when the task was created.
pollInterval?: numberSuggested polling interval in milliseconds.
Current task state.
statusMessage?: stringOptional human-readable message describing the current task state.
+This can provide context for any status, including:
- Reasons for "cancelled" status
- Summaries for "completed" status
- Diagnostic information for "failed" status (e.g., error details, what went wrong)
taskId: stringThe task identifier.
ttl: number | nullActual retention duration from creation in milliseconds, null for unlimited.
### `TaskMetadata`
diff --git a/schema/draft/schema.json b/schema/draft/schema.json
index fdd31f01d..cd05fdcff 100644
--- a/schema/draft/schema.json
+++ b/schema/draft/schema.json
@@ -3350,10 +3350,6 @@
"description": "ISO 8601 timestamp when the task was created.",
"type": "string"
},
- "error": {
- "description": "Error details when status is \"failed\".\nThis field provides diagnostic information about what went wrong and should only\nbe present when the task has failed. Use statusMessage for general state descriptions.",
- "type": "string"
- },
"pollInterval": {
"description": "Suggested polling interval in milliseconds.",
"type": "integer"
@@ -3363,7 +3359,7 @@
"description": "Current task state."
},
"statusMessage": {
- "description": "Optional human-readable message describing the current task state.\nThis can provide context for any status (e.g., reasons for \"cancelled\",\nsummaries for \"completed\", etc.).",
+ "description": "Optional human-readable message describing the current task state.\nThis can provide context for any status, including:\n- Reasons for \"cancelled\" status\n- Summaries for \"completed\" status\n- Diagnostic information for \"failed\" status (e.g., error details, what went wrong)",
"type": "string"
},
"taskId": {
diff --git a/schema/draft/schema.ts b/schema/draft/schema.ts
index 8eeff06c9..a10f91ed5 100644
--- a/schema/draft/schema.ts
+++ b/schema/draft/schema.ts
@@ -1321,8 +1321,10 @@ export interface Task {
/**
* Optional human-readable message describing the current task state.
- * This can provide context for any status (e.g., reasons for "cancelled",
- * summaries for "completed", etc.).
+ * This can provide context for any status, including:
+ * - Reasons for "cancelled" status
+ * - Summaries for "completed" status
+ * - Diagnostic information for "failed" status (e.g., error details, what went wrong)
*/
statusMessage?: string;
@@ -1340,13 +1342,6 @@ export interface Task {
* Suggested polling interval in milliseconds.
*/
pollInterval?: number;
-
- /**
- * Error details when status is "failed".
- * This field provides diagnostic information about what went wrong and should only
- * be present when the task has failed. Use statusMessage for general state descriptions.
- */
- error?: string;
}
/**
From e397f5dd7c7e369e7fdc24387f505d0097853e89 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:23:42 -0800
Subject: [PATCH 73/79] Clarify task polling under "Getting Tasks"
---
docs/specification/draft/basic/utilities/tasks.mdx | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 9c475ff0c..5a77d837f 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -178,7 +178,10 @@ This guidance is non-binding and is provisional logic intended to account for th
### Getting Tasks
-To retrieve the state of a task, requestors can send a `tasks/get` request:
+Requestors poll for task completion by sending `tasks/get` requests.
+Requestors **SHOULD** respect the `pollInterval` provided in responses when determining polling frequency.
+
+Requestors **SHOULD** continue polling until the task reaches a terminal status (`completed`, `failed`, or `cancelled`), or until encountering the [`input_required`](#input-required-status) status.
**Request:**
@@ -641,11 +644,11 @@ A task represents the execution state of a request. The task metadata includes:
Tasks can be in one of the following states:
-- `working`: The request is currently being processed
+- `working`: The request is currently being processed.
- `input_required`: The receiver needs input from the requestor. The requestor should call `tasks/result` to receive input requests, even though the task has not reached a terminal state.
-- `completed`: The request completed successfully and results are available
+- `completed`: The request completed successfully and results are available.
- `failed`: The associated request did not complete successfully. For tool calls specifically, this includes cases where the tool call result has `isError` set to true.
-- `cancelled`: The request was cancelled before completion
+- `cancelled`: The request was cancelled before completion.
### Task Parameters
From 7604c8281a135022c332d1d09e424261fe64f1f0 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:34:48 -0800
Subject: [PATCH 74/79] Add a line explaining requestor-driven tasks
---
docs/specification/draft/basic/utilities/tasks.mdx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 5a77d837f..62e946a2a 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -24,7 +24,9 @@ Tasks represent parties as either "requestors" or "receivers," defined as follow
## User Interaction Model
-Tasks are designed to be **requestor-driven** - requestors are responsible for augmenting requests with tasks and for polling for the results of those tasks; meanwhile, receivers tightly control which requests (if any) support task-based execution and manage the lifecycles of those tasks.
+Tasks are designed to be **requestor-driven** - requestors are responsible for augmenting requests with tasks and for polling for the results of those tasks; meanwhile, receivers tightly control which requests (if any) support task-based execution and manages the lifecycles of those tasks.
+
+This requestor-driven approach ensures deterministic response handling and enables sophisticated patterns such as concurrent request dispatching, which only the requestor has sufficient context to orchestrate.
Implementations are free to expose tasks through any interface pattern that suits their needs — the protocol itself does not mandate any specific user interaction model.
From 87e8d4285a2a30cd8cced0f755548e3eb66da24c Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:40:57 -0800
Subject: [PATCH 75/79] Add line on task use cases to spec
---
docs/docs/learn/architecture.mdx | 2 +-
docs/specification/draft/basic/utilities/tasks.mdx | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/docs/learn/architecture.mdx b/docs/docs/learn/architecture.mdx
index 60b5e7de1..f18feb4c1 100644
--- a/docs/docs/learn/architecture.mdx
+++ b/docs/docs/learn/architecture.mdx
@@ -134,7 +134,7 @@ For more details about client primitives see [client concepts](./client-concepts
Besides server and client primitives, the protocol offers cross-cutting utility primitives that augment how requests are executed:
-- **Tasks (Experimental)**: Asynchronous execution wrappers that enable deferred result retrieval and status tracking for any MCP request (e.g., expensive computations, workflow automation, batch processing, multi-step operations)
+- **Tasks (Experimental)**: Durable execution wrappers that enable deferred result retrieval and status tracking for MCP requests (e.g., expensive computations, workflow automation, batch processing, multi-step operations)
#### Notifications
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 62e946a2a..bcf3ef7dd 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -15,6 +15,8 @@ The design and behavior of tasks may evolve in future protocol versions.
The Model Context Protocol (MCP) allows requestors — which can be either clients or servers, depending on the direction of communication — to augment their requests with **tasks**. Tasks are durable state machines that carry information about the underlying execution state of the request they wrap, and are intended for requestor polling and deferred result retrieval. Each task is uniquely identifiable by a receiver-generated **task ID**.
+Tasks are useful for representing expensive computations and batch processing requests, and integrate seamlessly with external job APIs.
+
## Definitions
Tasks represent parties as either "requestors" or "receivers," defined as follows:
@@ -26,7 +28,7 @@ Tasks represent parties as either "requestors" or "receivers," defined as follow
Tasks are designed to be **requestor-driven** - requestors are responsible for augmenting requests with tasks and for polling for the results of those tasks; meanwhile, receivers tightly control which requests (if any) support task-based execution and manages the lifecycles of those tasks.
-This requestor-driven approach ensures deterministic response handling and enables sophisticated patterns such as concurrent request dispatching, which only the requestor has sufficient context to orchestrate.
+This requestor-driven approach ensures deterministic response handling and enables sophisticated patterns such as dispatching concurrent requests, which only the requestor has sufficient context to orchestrate.
Implementations are free to expose tasks through any interface pattern that suits their needs — the protocol itself does not mandate any specific user interaction model.
From f41e5e38be269c8fd440a003fac441aa31a599fe Mon Sep 17 00:00:00 2001
From: Luca Chang <131398524+LucaButBoring@users.noreply.github.com>
Date: Fri, 14 Nov 2025 12:46:53 -0800
Subject: [PATCH 76/79] Apply suggestions from code review
Co-authored-by: Jonathan Hefner
---
docs/specification/draft/basic/utilities/tasks.mdx | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index bcf3ef7dd..0e4748b13 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -8,7 +8,7 @@ title: Tasks
-Tasks are newly-introduced in this version of the MCP specification and are currently considered **experimental**.
+Tasks were introduced in version 2025-11-25 of the MCP specification and are currently considered **experimental**.
The design and behavior of tasks may evolve in future protocol versions.
@@ -167,7 +167,7 @@ To create a task, requestors send a request with the `task` field included in th
}
```
-When a receiver accepts a task-augmented request, it returns a `CreateTaskResult` containing task metadata. The response does not include the actual operation result. The actual result (e.g., tool result for `tools/call`) becomes available only through `tasks/result` after the task completes.
+When a receiver accepts a task-augmented request, it returns a [`CreateTaskResult`](/specification/draft/schema#createtaskresult) containing task metadata. The response does not include the actual operation result. The actual result (e.g., tool result for `tools/call`) becomes available only through `tasks/result` after the task completes.
@@ -219,7 +219,7 @@ Requestors **SHOULD** continue polling until the task reaches a terminal status
### Retrieving Task Results
-After a task completes the operation result is retrieved via `tasks/result`. This is distinct from the initial `CreateTaskResult` response, which contains only task metadata. The result structure matches the original request type (e.g., `CallToolResult` for `tools/call`).
+After a task completes the operation result is retrieved via [`tasks/result`](/specification/draft/schema#tasks%2Fresult). This is distinct from the initial `CreateTaskResult` response, which contains only task metadata. The result structure matches the original request type (e.g., `CallToolResult` for `tools/call`).
To retrieve the result of a completed task, requestors can send a `tasks/result` request:
@@ -261,7 +261,7 @@ To retrieve the result of a completed task, requestors can send a `tasks/result`
### Task Status Notification
-When a task status changes, receivers **MAY** send a `notifications/tasks/status` notification to inform the requestor of the change. This notification includes the full task state.
+When a task status changes, receivers **MAY** send a [`notifications/tasks/status`](/specification/draft/schema#notifications%2Ftasks%2Fstatus) notification to inform the requestor of the change. This notification includes the full task state.
**Notification:**
@@ -285,7 +285,7 @@ Requestors **MUST NOT** rely on receiving this notifications, as it is optional.
### Listing Tasks
-To retrieve a list of tasks, requestors can send a `tasks/list` request. This operation supports pagination.
+To retrieve a list of tasks, requestors can send a [`tasks/list`](/specification/draft/schema#tasks%2Flist) request. This operation supports pagination.
**Request:**
@@ -329,7 +329,7 @@ To retrieve a list of tasks, requestors can send a `tasks/list` request. This op
### Cancelling Tasks
-To explicitly cancel a task, requestors can send a `tasks/cancel` request.
+To explicitly cancel a task, requestors can send a [`tasks/cancel`](/specification/draft/schema#tasks%2Fcancel) request.
**Request:**
From 43113ab0cc2f5acb09c9b5715b352070bd57721f Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:49:42 -0800
Subject: [PATCH 77/79] Add missing link
---
docs/specification/draft/basic/utilities/tasks.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 0e4748b13..93b8cb08a 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -279,7 +279,7 @@ When a task status changes, receivers **MAY** send a [`notifications/tasks/statu
}
```
-The notification includes the full `Task` object with all task metadata fields, including the updated `status` and `statusMessage` (if present). This allows requestors to access the complete task state without making an additional `tasks/get` request.
+The notification includes the full [`Task`](/specification/draft/schema#task) object with all task metadata fields, including the updated `status` and `statusMessage` (if present). This allows requestors to access the complete task state without making an additional `tasks/get` request.
Requestors **MUST NOT** rely on receiving this notifications, as it is optional. Receivers are not required to send status notifications and may choose to only send them for certain status transitions. Requestors **SHOULD** continue to poll via `tasks/get` to ensure they receive status updates.
From ba39ed7aa3b60687539fee581f6b3f0b0d835c3e Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:50:14 -0800
Subject: [PATCH 78/79] Add missing link
---
docs/specification/draft/basic/utilities/tasks.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 93b8cb08a..7c9c8c788 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -182,7 +182,7 @@ This guidance is non-binding and is provisional logic intended to account for th
### Getting Tasks
-Requestors poll for task completion by sending `tasks/get` requests.
+Requestors poll for task completion by sending [`tasks/get`](/specification/draft/schema#tasks%2Fget) requests.
Requestors **SHOULD** respect the `pollInterval` provided in responses when determining polling frequency.
Requestors **SHOULD** continue polling until the task reaches a terminal status (`completed`, `failed`, or `cancelled`), or until encountering the [`input_required`](#input-required-status) status.
From cbf3dca16f8d95d2499767797bccb9bdc53d9f57 Mon Sep 17 00:00:00 2001
From: Luca Chang
Date: Fri, 14 Nov 2025 12:59:32 -0800
Subject: [PATCH 79/79] Relax task augmentation with capabilities to "SHOULD",
fix "task metadata" language
---
.../draft/basic/utilities/tasks.mdx | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/docs/specification/draft/basic/utilities/tasks.mdx b/docs/specification/draft/basic/utilities/tasks.mdx
index 7c9c8c788..d86e270fb 100644
--- a/docs/specification/draft/basic/utilities/tasks.mdx
+++ b/docs/specification/draft/basic/utilities/tasks.mdx
@@ -94,11 +94,11 @@ Clients declare if they support tasks, and if so, which client-side requests can
### Capability Negotiation
-During the initialization phase, both parties exchange their `tasks` capabilities to establish which operations support task-based execution. Requestors **MUST** only augment requests with task metadata if the corresponding capability has been declared by the receiver.
+During the initialization phase, both parties exchange their `tasks` capabilities to establish which operations support task-based execution. Requestors **SHOULD** only augment requests with a task if the corresponding capability has been declared by the receiver.
-For example, if a server's capabilities include `tasks.requests.tools.call: {}`, then clients may augment `tools/call` requests with task metadata. If a client's capabilities include `tasks.requests.sampling.createMessage: {}`, then servers may augment `sampling/createMessage` requests with task metadata.
+For example, if a server's capabilities include `tasks.requests.tools.call: {}`, then clients may augment `tools/call` requests with a task. If a client's capabilities include `tasks.requests.sampling.createMessage: {}`, then servers may augment `sampling/createMessage` requests with a task.
-If `capabilities.tasks` is not defined, the peer **MUST NOT** attempt to create tasks during requests.
+If `capabilities.tasks` is not defined, the peer **SHOULD NOT** attempt to create tasks during requests.
The set of capabilities in `capabilities.tasks.requests` is exhaustive. If a request type is not present, it does not support task-augmentation.
@@ -125,7 +125,7 @@ This is to be interpreted as a fine-grained layer in addition to capabilities, f
Task-augmented requests follow a two-phase response pattern that differs from normal requests:
- **Normal requests**: The server processes the request and returns the actual operation result directly.
-- **Task-augmented requests**: The server accepts the request and immediately returns a `CreateTaskResult` containing task metadata. The actual operation result becomes available later through `tasks/result` after the task completes.
+- **Task-augmented requests**: The server accepts the request and immediately returns a `CreateTaskResult` containing task data. The actual operation result becomes available later through `tasks/result` after the task completes.
To create a task, requestors send a request with the `task` field included in the request params. Requestors **MAY** include a `ttl` value indicating the desired task lifetime duration (in milliseconds) since its creation.
@@ -167,7 +167,7 @@ To create a task, requestors send a request with the `task` field included in th
}
```
-When a receiver accepts a task-augmented request, it returns a [`CreateTaskResult`](/specification/draft/schema#createtaskresult) containing task metadata. The response does not include the actual operation result. The actual result (e.g., tool result for `tools/call`) becomes available only through `tasks/result` after the task completes.
+When a receiver accepts a task-augmented request, it returns a [`CreateTaskResult`](/specification/draft/schema#createtaskresult) containing task data. The response does not include the actual operation result. The actual result (e.g., tool result for `tools/call`) becomes available only through `tasks/result` after the task completes.
@@ -219,7 +219,7 @@ Requestors **SHOULD** continue polling until the task reaches a terminal status
### Retrieving Task Results
-After a task completes the operation result is retrieved via [`tasks/result`](/specification/draft/schema#tasks%2Fresult). This is distinct from the initial `CreateTaskResult` response, which contains only task metadata. The result structure matches the original request type (e.g., `CallToolResult` for `tools/call`).
+After a task completes the operation result is retrieved via [`tasks/result`](/specification/draft/schema#tasks%2Fresult). This is distinct from the initial `CreateTaskResult` response, which contains only task data. The result structure matches the original request type (e.g., `CallToolResult` for `tools/call`).
To retrieve the result of a completed task, requestors can send a `tasks/result` request:
@@ -279,7 +279,7 @@ When a task status changes, receivers **MAY** send a [`notifications/tasks/statu
}
```
-The notification includes the full [`Task`](/specification/draft/schema#task) object with all task metadata fields, including the updated `status` and `statusMessage` (if present). This allows requestors to access the complete task state without making an additional `tasks/get` request.
+The notification includes the full [`Task`](/specification/draft/schema#task) object, including the updated `status` and `statusMessage` (if present). This allows requestors to access the complete task state without making an additional `tasks/get` request.
Requestors **MUST NOT** rely on receiving this notifications, as it is optional. Receivers are not required to send status notifications and may choose to only send them for certain status transitions. Requestors **SHOULD** continue to poll via `tasks/get` to ensure they receive status updates.
@@ -481,7 +481,7 @@ sequenceDiagram
participant C as Client (Requestor)
participant S as Server (Receiver)
Note over C,S: 1. Task Creation
- C->>S: Request with task metadata (ttl)
+ C->>S: Request with task field (ttl)
S->>C: CreateTaskResult (taskId, status: working, ttl, pollInterval)
Note over C,S: 2. Task Polling
C->>S: tasks/get (taskId)
@@ -511,7 +511,7 @@ sequenceDiagram
Note over LLM,C: LLM initiates request
LLM->>C: Request operation
- Note over C,S: Client augments with task metadata
+ Note over C,S: Client augments with task
C->>S: tools/call (ttl: 3600000)
S->>C: CreateTaskResult (task-123, status: working)
@@ -635,7 +635,7 @@ sequenceDiagram
### Task
-A task represents the execution state of a request. The task metadata includes:
+A task represents the execution state of a request. The task state includes:
- `taskId`: Unique identifier for the task
- `status`: Current state of the task execution
@@ -750,7 +750,7 @@ Receivers **SHOULD** provide informative error messages to describe the cause of
-Receivers are not required to retain task metadata indefinitely. It is compliant behavior for a receiver to return an error stating the task cannot be found if it has purged an expired task.
+Receivers are not required to retain tasks indefinitely. It is compliant behavior for a receiver to return an error stating the task cannot be found if it has purged an expired task.
OptionalparamsOptional_meta?: { [key: string]: unknown }See General fields:
_metafor notes on_metausage.jsonrpc: "2.0";
method: "notifications/tasks/created";
params?: {
_meta?: {
"modelcontextprotocol.io/related-task"?: RelatedTaskMetadata;
[key: string]: unknown;
};
};
}
A notification from the receiver to the requestor, informing them that a task has been created and is ready for polling.
Optionalparams_meta?: {
"modelcontextprotocol.io/related-task"?: RelatedTaskMetadata;
[key: string]: unknown;
};
}
Optional_meta?: {"modelcontextprotocol.io/related-task"?: RelatedTaskMetadata;
[key: string]: unknown;
}
The _meta field MUST include modelcontextprotocol.io/related-task with the taskId.