> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.developerdoc.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 任务

<div id="enable-section-numbers" />

<Note>
  任务在 MCP 规范 2025-11-25 版本中引入，目前被视为**实验性**功能。
  任务的设计和行为可能会在未来协议版本中演进。
</Note>

Model Context Protocol (MCP) 允许请求方使用**任务**增强其请求。根据通信方向，请求方可以是客户端，也可以是服务器。任务是持久状态机，携带其所包装请求的底层执行状态信息，用于请求方轮询和延迟结果检索。每个任务都可通过接收方生成的 **task ID** 唯一标识。

任务适合表示成本较高的计算和批处理请求，并能与外部 job API 无缝集成。

## 定义

任务将参与方表示为“请求方”或“接收方”，定义如下：

* **请求方：** 任务增强请求的发送方。它可以是客户端或服务器，二者都可以创建任务。
* **接收方：** 任务增强请求的接收方，也是执行任务的实体。它可以是客户端或服务器，二者都可以接收和执行任务。

## 用户交互模型

任务被设计为**请求方驱动**：请求方负责用任务增强请求，并轮询这些任务的结果；同时，接收方严格控制哪些请求（如果有）支持基于任务的执行，并管理这些任务的生命周期。

这种请求方驱动方式确保响应处理具有确定性，并支持分派并发请求等复杂模式，而只有请求方具备足够上下文来编排这些模式。

实现可以自由通过任何适合自身需求的接口模式公开任务；协议本身不强制任何特定用户交互模型。

## 能力

支持任务增强请求的服务器和客户端 **MUST** 在初始化期间声明 `tasks` 能力。`tasks` 能力按请求类别组织，并通过布尔属性指示哪些具体请求类型支持任务增强。

### 服务器能力

服务器声明其是否支持任务；如果支持，还要声明哪些服务器侧请求可以用任务增强。

| 能力                          | 描述                         |
| --------------------------- | -------------------------- |
| `tasks.list`                | 服务器支持 `tasks/list` 操作      |
| `tasks.cancel`              | 服务器支持 `tasks/cancel` 操作    |
| `tasks.requests.tools.call` | 服务器支持任务增强的 `tools/call` 请求 |

```json theme={null}
{
  "capabilities": {
    "tasks": {
      "list": {},
      "cancel": {},
      "requests": {
        "tools": {
          "call": {}
        }
      }
    }
  }
}
```

### 客户端能力

客户端声明其是否支持任务；如果支持，还要声明哪些客户端侧请求可以用任务增强。

| 能力                                      | 描述                                     |
| --------------------------------------- | -------------------------------------- |
| `tasks.list`                            | 客户端支持 `tasks/list` 操作                  |
| `tasks.cancel`                          | 客户端支持 `tasks/cancel` 操作                |
| `tasks.requests.sampling.createMessage` | 客户端支持任务增强的 `sampling/createMessage` 请求 |
| `tasks.requests.elicitation.create`     | 客户端支持任务增强的 `elicitation/create` 请求     |

```json theme={null}
{
  "capabilities": {
    "tasks": {
      "list": {},
      "cancel": {},
      "requests": {
        "sampling": {
          "createMessage": {}
        },
        "elicitation": {
          "create": {}
        }
      }
    }
  }
}
```

### 能力协商

在初始化阶段，双方会交换其 `tasks` 能力，以确定哪些操作支持基于任务的执行。只有在接收方声明了对应能力时，请求方 **SHOULD** 才用任务增强请求。

例如，如果服务器能力包含 `tasks.requests.tools.call: {}`，则客户端可以用任务增强 `tools/call` 请求。如果客户端能力包含 `tasks.requests.sampling.createMessage: {}`，则服务器可以用任务增强 `sampling/createMessage` 请求。

如果未定义 `capabilities.tasks`，对等方 **SHOULD NOT** 在请求期间尝试创建任务。

`capabilities.tasks.requests` 中的能力集合是穷尽的。如果某种请求类型不存在，则它不支持任务增强。

`capabilities.tasks.list` 控制该参与方是否支持 `tasks/list` 操作。

`capabilities.tasks.cancel` 控制该参与方是否支持 `tasks/cancel` 操作。

<a id="tool-level-negotiation" />

### 工具级协商

出于任务增强目的，工具调用需要特殊处理。在 `tools/list` 的结果中，工具通过 `execution.taskSupport` 声明对任务的支持；如果存在，该值可以是 `"required"`、`"optional"` 或 `"forbidden"`。

这应解释为能力之外的细粒度层，并遵循以下规则：

1. 如果服务器能力不包含 `tasks.requests.tools.call`，无论 `execution.taskSupport` 的值是什么，客户端都 **MUST NOT** 尝试对该服务器的工具使用任务增强。
2. 如果服务器能力包含 `tasks.requests.tools.call`，客户端会考虑 `execution.taskSupport` 的值，并相应处理：
   1. 如果 `execution.taskSupport` 不存在或为 `"forbidden"`，客户端 **MUST NOT** 尝试以任务方式调用工具。如果客户端尝试这样做，服务器 **SHOULD** 返回 `-32601` (Method not found) 错误。这是默认行为。
   2. 如果 `execution.taskSupport` 为 `"optional"`，客户端 **MAY** 以任务方式调用工具，也可以作为普通请求调用。
   3. 如果 `execution.taskSupport` 为 `"required"`，客户端 **MUST** 以任务方式调用工具。如果客户端没有尝试这样做，服务器 **MUST** 返回 `-32601` (Method not found) 错误。

## 协议消息

### 创建任务

任务增强请求遵循不同于普通请求的两阶段响应模式：

* **普通请求**：服务器处理请求，并直接返回实际操作结果。
* **任务增强请求**：服务器接受请求，并立即返回包含任务数据的 `CreateTaskResult`。实际操作结果会在任务完成后，稍后通过 `tasks/result` 提供。

要创建任务，请求方发送一个在请求 params 中包含 `task` 字段的请求。请求方 **MAY** 包含 `ttl` 值，表示自创建起期望的任务生命周期时长（毫秒）。

**请求：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "New York"
    },
    "task": {
      "ttl": 60000
    }
  }
}
```

**响应：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "task": {
      "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
      "status": "working",
      "statusMessage": "The operation is now in progress.",
      "createdAt": "2025-11-25T10:30:00Z",
      "lastUpdatedAt": "2025-11-25T10:40:00Z",
      "ttl": 60000,
      "pollInterval": 5000
    }
  }
}
```

当接收方接受任务增强请求时，它会返回包含任务数据的 [`CreateTaskResult`](/specification/2025-11-25/schema#createtaskresult)。响应不包含实际操作结果。实际结果（例如 `tools/call` 的工具结果）只有在任务完成后才能通过 `tasks/result` 获得。

<Note>
  当为响应 `tools/call` 请求而创建任务时，Host 应用可能希望在任务执行期间将控制权交还给模型。这允许模型在等待任务完成时继续处理其他请求或执行额外工作。

  为支持这种模式，服务器可以在 `CreateTaskResult` 的 `_meta` 字段中提供一个可选的 `io.modelcontextprotocol/model-immediate-response` 键。该键的值应为字符串，用作立即传递给模型的工具结果。
  如果服务器未提供此字段，Host 应用可以回退到自己预定义的消息。

  本指南不具约束力，是用于处理特定用例的临时逻辑。未来协议版本可能会将此行为作为 `CreateTaskResult` 的一部分正式化或修改。
</Note>

### 获取任务

<Note>
  在 Streamable HTTP (SSE) 传输中，客户端 **MAY** 随时从服务器为响应 `tasks/get` 请求而打开的 SSE 流断开连接。

  虽然本说明不对 SSE 流的具体用法作规范性规定，但所有实现 **MUST** 继续遵守现有的 [Streamable HTTP 传输规范](../transports#sending-messages-to-the-server)。
</Note>

请求方通过发送 [`tasks/get`](/specification/2025-11-25/schema#tasks%2Fget) 请求来轮询任务完成情况。
请求方在确定轮询频率时 **SHOULD** 遵守响应中提供的 `pollInterval`。

请求方 **SHOULD** 持续轮询，直到任务达到终止状态（`completed`、`failed` 或 `cancelled`），或直到遇到 [`input_required`](#input-required-status) 状态。请注意，调用 `tasks/result` 并不意味着请求方需要停止轮询；如果请求方没有主动等待 `tasks/result` 完成，**SHOULD** 继续通过 `tasks/get` 轮询任务状态。

**请求：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tasks/get",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}
```

**响应：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
    "status": "working",
    "statusMessage": "The operation is now in progress.",
    "createdAt": "2025-11-25T10:30:00Z",
    "lastUpdatedAt": "2025-11-25T10:40:00Z",
    "ttl": 30000,
    "pollInterval": 5000
  }
}
```

### 检索任务结果

<Note>
  在 Streamable HTTP (SSE) 传输中，客户端 **MAY** 随时从服务器为响应 `tasks/result` 请求而打开的 SSE 流断开连接。

  虽然本说明不对 SSE 流的具体用法作规范性规定，但所有实现 **MUST** 继续遵守现有的 [Streamable HTTP 传输规范](../transports#sending-messages-to-the-server)。
</Note>

任务完成后，可通过 [`tasks/result`](/specification/2025-11-25/schema#tasks%2Fresult) 检索操作结果。这不同于初始 `CreateTaskResult` 响应，后者只包含任务数据。结果结构与原始请求类型匹配（例如 `tools/call` 对应 `CallToolResult`）。

要检索已完成任务的结果，请求方可以发送 `tasks/result` 请求：

虽然 `tasks/result` 会阻塞，直到任务达到终止状态，但如果请求方没有主动阻塞等待结果（例如其先前的 `tasks/result` 请求失败或被取消），它们可以并行继续通过 `tasks/get` 轮询。这允许请求方在任务执行期间监控状态变化或显示进度更新，即使已经调用过 `tasks/result`。

**请求：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tasks/result",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}
```

**响应：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
      }
    ],
    "isError": false,
    "_meta": {
      "io.modelcontextprotocol/related-task": {
        "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
      }
    }
  }
}
```

### 任务状态通知

当任务状态发生变化时，接收方 **MAY** 发送 [`notifications/tasks/status`](/specification/2025-11-25/schema#notifications%2Ftasks%2Fstatus) 通知，以告知请求方该变化。此通知包含完整任务状态。

**通知：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "notifications/tasks/status",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
    "status": "completed",
    "createdAt": "2025-11-25T10:30:00Z",
    "lastUpdatedAt": "2025-11-25T10:50:00Z",
    "ttl": 60000,
    "pollInterval": 5000
  }
}
```

通知包含完整的 [`Task`](/specification/2025-11-25/schema#task) 对象，包括更新后的 `status` 和 `statusMessage`（如果存在）。这允许请求方访问完整任务状态，而无需额外发起 `tasks/get` 请求。

请求方 **MUST NOT** 依赖接收此通知，因为它是可选的。接收方不要求发送状态通知，并且可以选择只针对某些状态转换发送。请求方 **SHOULD** 继续通过 `tasks/get` 轮询，以确保收到状态更新。

### 列出任务

要检索任务列表，请求方可以发送 [`tasks/list`](/specification/2025-11-25/schema#tasks%2Flist) 请求。此操作支持分页。

**请求：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tasks/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}
```

**响应：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "tasks": [
      {
        "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
        "status": "working",
        "createdAt": "2025-11-25T10:30:00Z",
        "lastUpdatedAt": "2025-11-25T10:40:00Z",
        "ttl": 30000,
        "pollInterval": 5000
      },
      {
        "taskId": "abc123-def456-ghi789",
        "status": "completed",
        "createdAt": "2025-11-25T09:15:00Z",
        "lastUpdatedAt": "2025-11-25T10:40:00Z",
        "ttl": 60000
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}
```

### 取消任务

要显式取消任务，请求方可以发送 [`tasks/cancel`](/specification/2025-11-25/schema#tasks%2Fcancel) 请求。

**请求：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tasks/cancel",
  "params": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}
```

**响应：**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
    "status": "cancelled",
    "statusMessage": "The task was cancelled by request.",
    "createdAt": "2025-11-25T10:30:00Z",
    "lastUpdatedAt": "2025-11-25T10:40:00Z",
    "ttl": 30000,
    "pollInterval": 5000
  }
}
```

## 行为要求

这些要求适用于所有支持接收任务增强请求的参与方。

### 任务支持与处理

1. 未为某种请求类型声明任务能力的接收方 **MUST** 正常处理该类型请求，并忽略任何存在的任务增强元数据。
2. 为某种请求类型声明任务能力的接收方 **MAY** 对非任务增强请求返回错误，要求请求方使用任务增强。

### Task ID 要求

1. Task IDs **MUST** 是字符串值。
2. Task IDs **MUST** 由接收方在创建任务时生成。
3. Task IDs **MUST** 在接收方控制的所有任务中唯一。

### 任务状态生命周期

1. 任务创建时 **MUST** 从 `working` 状态开始。
2. 接收方 **MUST** 仅按以下有效路径转换任务：
   1. 从 `working`：可以转为 `input_required`、`completed`、`failed` 或 `cancelled`
   2. 从 `input_required`：可以转为 `working`、`completed`、`failed` 或 `cancelled`
   3. 状态为 `completed`、`failed` 或 `cancelled` 的任务处于终止状态，**MUST NOT** 转换为任何其他状态

**任务状态图：**

```mermaid theme={null}
stateDiagram-v2
    [*] --> working

    working --> input_required
    working --> terminal

    input_required --> working
    input_required --> terminal

    terminal --> [*]

    note right of terminal
        Terminal states:
        • completed
        • failed
        • cancelled
    end note
```

<a id="input-required-status" />

### Input Required 状态

<Note>
  使用 Streamable HTTP (SSE) 传输时，服务器通常会在投递响应消息后关闭 SSE 流，这可能导致后续任务消息应使用哪个流变得不明确。

  服务器可以通过将消息排队发送给客户端来处理这种情况，从而把任务相关消息作为旁路消息与其他响应一起传递。

  服务器可以灵活管理任务轮询和结果检索期间的 SSE 流，客户端 **SHOULD** 预期消息可能在任何 SSE 流上传递，包括 HTTP GET 流。
  一种可能方式是在 `tasks/result` 上维护 SSE 流（见关于 `input_required` 状态的说明）。
  在可行时，服务器 **SHOULD NOT** 响应 `tasks/get` 请求升级到 SSE 流，因为客户端已经表示希望轮询结果。

  虽然本说明不对 SSE 流的具体用法作规范性规定，但所有实现 **MUST** 继续遵守现有的 [Streamable HTTP 传输规范](../transports#sending-messages-to-the-server)。
</Note>

1. 当任务接收方有完成任务所必需、需要发给请求方的消息时，接收方 **SHOULD** 将任务移至 `input_required` 状态。
2. 接收方 **MUST** 在请求中包含 `io.modelcontextprotocol/related-task` 元数据，以将其与任务关联。
3. 当请求方遇到 `input_required` 状态时，它 **SHOULD** 预先调用 `tasks/result`。
4. 当接收方收到所有必需输入后，任务 **SHOULD** 转出 `input_required` 状态（通常回到 `working`）。

### TTL 和资源管理

1. 接收方 **MUST** 在所有任务响应中包含采用 [ISO 8601](https://datatracker.ietf.org/doc/html/rfc3339#section-5) 格式的 `createdAt` 时间戳，以指示任务创建时间。
2. 接收方 **MUST** 在所有任务响应中包含采用 [ISO 8601](https://datatracker.ietf.org/doc/html/rfc3339#section-5) 格式的 `lastUpdatedAt` 时间戳，以指示任务最后更新时间。
3. 接收方 **MAY** 覆盖请求的 `ttl` 时长。
4. 接收方 **MUST** 在 `tasks/get` 响应中包含实际 `ttl` 时长（或使用 `null` 表示无限制）。
5. 在任务的 `ttl` 生命周期结束后，无论任务状态如何，接收方 **MAY** 删除任务及其结果。
6. 接收方 **MAY** 在 `tasks/get` 响应中包含 `pollInterval` 值（毫秒），以建议轮询间隔。请求方在该值存在时 **SHOULD** 遵守它。

### 结果检索

1. 接受任务增强请求的接收方 **MUST** 返回 `CreateTaskResult` 作为响应。该结果 **SHOULD** 在接受任务后尽快返回。
2. 当接收方收到针对处于终止状态（`completed`、`failed` 或 `cancelled`）任务的 `tasks/result` 请求时，它 **MUST** 返回底层请求的最终结果，无论该结果是成功结果还是 JSON-RPC 错误。
3. 当接收方收到针对处于任何其他非终止状态（`working` 或 `input_required`）任务的 `tasks/result` 请求时，它 **MUST** 阻塞响应，直到任务达到终止状态。
4. 对于处于终止状态的任务，接收方 **MUST** 从 `tasks/result` 返回与底层请求本应返回的完全相同内容，无论该内容是成功结果还是 JSON-RPC 错误。

### 关联任务相关消息

1. 与任务相关的所有请求、通知和响应 **MUST** 在其 `_meta` 字段中包含 `io.modelcontextprotocol/related-task` 键，其值设置为一个对象，且其中 `taskId` 与关联任务 ID 匹配。
   1. 例如，任务增强工具调用所依赖的引出 **MUST** 与该工具调用的任务共享相同的 related task ID。
2. 对于 `tasks/get`、`tasks/result` 和 `tasks/cancel` 操作，请求中的 `taskId` 参数 **MUST** 用作标识目标任务的事实来源。请求方 **SHOULD NOT** 在这些请求中包含 `io.modelcontextprotocol/related-task` 元数据；如果存在，接收方 **MUST** 忽略此类元数据，并以 RPC 方法参数为准。
   类似地，对于 `tasks/get`、`tasks/list` 和 `tasks/cancel` 操作，接收方 **SHOULD NOT** 在结果消息中包含 `io.modelcontextprotocol/related-task` 元数据，因为 `taskId` 已经存在于响应结构中。

### 任务通知

1. 当任务状态发生变化时，接收方 **MAY** 发送 `notifications/tasks/status` 通知。
2. 请求方 **MUST NOT** 依赖接收 `notifications/tasks/status` 通知，因为它是可选的。
3. 发送时，`notifications/tasks/status` 通知 **SHOULD NOT** 包含 `io.modelcontextprotocol/related-task` 元数据，因为任务 ID 已经存在于通知参数中。

### 任务进度通知

任务增强请求支持 [progress](./progress) 规范中定义的进度通知。初始请求中提供的 `progressToken` 会在整个任务生命周期内保持有效。

### 任务列表

1. 接收方 **SHOULD** 使用基于 cursor 的分页，以限制单个响应中返回的任务数量。
2. 如果还有更多任务可用，接收方 **MUST** 在响应中包含 `nextCursor`。
3. 请求方 **MUST** 将 cursors 视为 opaque tokens，不得尝试解析或修改它们。
4. 如果某个任务可由某请求方通过 `tasks/get` 检索，则它 **MUST** 可由该请求方通过 `tasks/list` 检索。

### 任务取消

1. 对于已处于终止状态（`completed`、`failed` 或 `cancelled`）的任务，接收方 **MUST** 使用错误代码 `-32602` (Invalid params) 拒绝取消请求。
2. 收到有效取消请求后，接收方 **SHOULD** 尝试停止任务执行，并且 **MUST** 在发送响应前将任务转换为 `cancelled` 状态。
3. 任务一旦取消，即使执行继续完成或失败，也 **MUST** 保持 `cancelled` 状态。
4. `tasks/cancel` 操作未定义删除行为。不过，接收方 **MAY** 自行决定随时删除已取消任务，包括取消后立即删除或在任务 `ttl` 过期后删除。
5. 请求方 **SHOULD NOT** 依赖已取消任务保留任何特定时长，并应在取消前检索任何所需信息。

## 消息流程

### 基本任务生命周期

```mermaid theme={null}
sequenceDiagram
    participant C as Client (Requestor)
    participant S as Server (Receiver)
    Note over C,S: 1. Task Creation
    C->>S: Request with task field (ttl)
    activate S
    S->>C: CreateTaskResult (taskId, status: working, ttl, pollInterval)
    deactivate S
    Note over C,S: 2. Task Polling
    C->>S: tasks/get (taskId)
    activate S
    S->>C: working
    deactivate S
    Note over S: Task processing continues...
    C->>S: tasks/get (taskId)
    activate S
    S->>C: working
    deactivate S
    Note over S: Task completes
    C->>S: tasks/get (taskId)
    activate S
    S->>C: completed
    deactivate S
    Note over C,S: 3. Result Retrieval
    C->>S: tasks/result (taskId)
    activate S
    S->>C: Result content
    deactivate S
    Note over C,S: 4. Cleanup
    Note over S: After ttl period from creation, task is cleaned up
```

### 带引出的任务增强工具调用

```mermaid theme={null}
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
    C->>S: tools/call (ttl: 3600000)
    activate S
    S->>C: CreateTaskResult (task-123, status: working)
    deactivate S

    Note over LLM,C: Client continues processing other requests<br/>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)
    activate S
    S->>C: working
    deactivate S

    Note over S: Server needs information from client<br/>Task moves to input_required

    Note over C,S: Client polls and discovers input_required
    C->>S: tasks/get (task-123)
    activate S
    S->>C: input_required
    deactivate S

    Note over C,S: Client opens result stream
    C->>S: tasks/result (task-123)
    activate S
    S->>C: elicitation/create (related-task: task-123)
    activate C
    C->>U: Prompt user for input
    U->>C: Provide information
    C->>S: elicitation response (related-task: task-123)
    deactivate C
    deactivate S

    Note over C,S: Client closes result stream and resumes polling

    Note over S: Task continues processing...<br/>Task moves back to working

    C->>S: tasks/get (task-123)
    activate S
    S->>C: working
    deactivate S

    Note over S: Task completes

    Note over C,S: Client polls and discovers completion
    C->>S: tasks/get (task-123)
    activate S
    S->>C: completed
    deactivate S

    Note over C,S: Client retrieves final results
    C->>S: tasks/result (task-123)
    activate S
    S->>C: Result content
    deactivate S
    C->>LLM: Process result

    Note over S: Results retained for ttl period from creation
```

### 任务增强采样请求

```mermaid theme={null}
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 (ttl: 3600000)
    activate C
    C->>S: CreateTaskResult (request-789, status: working)
    deactivate C

    Note over S: Server continues processing<br/>while waiting for result

    Note over S,C: Server polls for result
    S->>C: tasks/get (request-789)
    activate C
    C->>S: working
    deactivate C

    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)
    activate C
    C->>S: completed
    deactivate C

    Note over S,C: Server retrieves result
    S->>C: tasks/result (request-789)
    activate C
    C->>S: Result content
    deactivate C

    Note over S: Server continues processing

    Note over C: Results retained for ttl period from creation
```

### 任务取消流程

```mermaid theme={null}
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, ttl: 60000)
    activate S
    S->>C: CreateTaskResult (task-123, status: working)
    deactivate S

    Note over C,S: 2. Task Processing
    C->>S: tasks/get (task-123)
    activate S
    S->>C: working
    deactivate S

    Note over C,S: 3. Client Cancellation
    Note over C: User requests cancellation
    C->>S: tasks/cancel (taskId: task-123)
    activate S

    Note over S: Server stops execution (best effort)
    Note over S: Task moves to cancelled status

    S->>C: Task (status: cancelled)
    deactivate S

    Note over C: Client receives confirmation

    Note over S: Server may delete task at its discretion
```

## 数据类型

### Task

任务表示请求的执行状态。任务状态包括：

* `taskId`：任务的唯一标识符
* `status`：任务执行的当前状态
* `statusMessage`：描述当前状态的可选人类可读消息（可出现在任何状态中，包括失败任务的错误详情）
* `createdAt`：任务创建时间的 ISO 8601 时间戳
* `ttl`：从创建开始到任务可能被删除之前的时间，单位为毫秒
* `pollInterval`：状态检查之间的建议时间，单位为毫秒
* `lastUpdatedAt`：任务状态最后更新时间的 ISO 8601 时间戳

### 任务状态

任务可以处于以下状态之一：

* `working`：请求当前正在处理。
* `input_required`：接收方需要来自请求方的输入。即使任务尚未达到终止状态，请求方也应调用 `tasks/result` 来接收输入请求。
* `completed`：请求已成功完成，结果可用。
* `failed`：关联请求未成功完成。具体到工具调用，这包括工具调用结果将 `isError` 设置为 true 的情况。
* `cancelled`：请求在完成前已取消。

### 任务参数

用任务执行增强请求时，请求参数中会包含 `task` 字段：

```json theme={null}
{
  "task": {
    "ttl": 60000
  }
}
```

字段：

* `ttl` (number, optional)：请求从创建开始保留任务的时长，单位为毫秒

### Related Task 元数据

与任务关联的所有请求、响应和通知 **MUST** 在 `_meta` 中包含 `io.modelcontextprotocol/related-task` 键：

```json theme={null}
{
  "io.modelcontextprotocol/related-task": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
  }
}
```

这会在整个请求生命周期内将消息与其来源任务关联。

对于 `tasks/get`、`tasks/list` 和 `tasks/cancel` 操作，请求方和接收方 **SHOULD NOT** 在其消息中包含此元数据，因为 `taskId` 已经存在于消息结构中。
`tasks/result` 操作 **MUST** 在其响应中包含此元数据，因为结果结构本身不包含任务 ID。

## 错误处理

任务使用两种错误报告机制：

1. **协议错误**：用于协议级问题的标准 JSON-RPC 错误
2. **任务执行错误**：底层请求执行中的错误，通过任务状态报告

### 协议错误

接收方 **MUST** 针对以下协议错误情况返回标准 JSON-RPC 错误：

* `tasks/get`、`tasks/result` 或 `tasks/cancel` 中的 `taskId` 无效或不存在：`-32602` (Invalid params)
* `tasks/list` 中的 cursor 无效或不存在：`-32602` (Invalid params)
* 尝试取消已处于终止状态的任务：`-32602` (Invalid params)
* 内部错误：`-32603` (Internal error)

此外，接收方 **MAY** 返回以下错误：

* 当接收方要求该请求类型使用任务增强时收到非任务增强请求：`-32600` (Invalid request)

接收方 **SHOULD** 提供信息充分的错误消息来描述错误原因。

**示例：需要任务增强**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "Task augmentation required for tools/call requests"
  }
}
```

**示例：任务未找到**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 70,
  "error": {
    "code": -32602,
    "message": "Failed to retrieve task: Task not found"
  }
}
```

**示例：任务已过期**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 71,
  "error": {
    "code": -32602,
    "message": "Failed to retrieve task: Task has expired"
  }
}
```

<Note>
  接收方不要求无限期保留任务。如果接收方已清除过期任务，返回说明找不到该任务的错误是符合规范的行为。
</Note>

**示例：任务取消被拒绝（已终止）**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 74,
  "error": {
    "code": -32602,
    "message": "Cannot cancel task: already in terminal status 'completed'"
  }
}
```

### 任务执行错误

当底层请求未成功完成时，任务会转为 `failed` 状态。这包括请求执行期间的 JSON-RPC 协议错误；具体到工具调用，还包括工具结果将 `isError` 设置为 true 的情况。`tasks/get` 响应 **SHOULD** 包含带有失败诊断信息的 `statusMessage` 字段。

**示例：带执行错误的任务**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "taskId": "786512e2-9e0d-44bd-8f29-789f820fe840",
    "status": "failed",
    "createdAt": "2025-11-25T10:30:00Z",
    "lastUpdatedAt": "2025-11-25T10:40:00Z",
    "ttl": 30000,
    "statusMessage": "Tool execution failed: API rate limit exceeded"
  }
}
```

对于包装工具调用请求的任务，当工具结果将 `isError` 设置为 `true` 时，任务应达到 `failed` 状态。

`tasks/result` endpoint 会返回与底层请求本应返回的完全相同内容：

* 如果底层请求产生 JSON-RPC 错误，`tasks/result` **MUST** 返回相同的 JSON-RPC 错误。
* 如果请求以 JSON-RPC 响应完成，`tasks/result` **MUST** 返回包含该结果的成功 JSON-RPC 响应。

## 安全考量

### 任务隔离和访问控制

Task IDs 是访问任务状态和结果的主要机制。如果没有适当访问控制，任何能够猜测或获得 task ID 的参与方都可能访问敏感信息，或操纵并非由其创建的任务。

当提供授权上下文时，接收方 **MUST** 将任务绑定到该上下文。

上下文绑定并不适用于所有应用。一些 MCP 服务器运行在没有授权的环境中，例如单用户工具，或使用不支持授权的传输。
在这些场景中，接收方 **SHOULD** 清楚记录此限制，因为任何能够猜测 task ID 的请求方都可能访问任务结果。
如果无法进行上下文绑定，接收方 **MUST** 生成具有足够熵的加密安全 task IDs 以防猜测，并应考虑使用更短的 TTL 时长来缩小暴露窗口。
此外，无法识别请求方的接收方 **SHOULD NOT** 声明 `tasks.list` 能力，因为列出任务会向任何请求方暴露任务元数据，无论 task ID 熵有多高。

如果上下文绑定可用，接收方 **MUST** 拒绝针对不属于请求方同一授权上下文的任务的 `tasks/get`、`tasks/result` 和 `tasks/cancel` 请求。对于 `tasks/list` 请求，接收方 **MUST** 确保返回的任务列表只包含与请求方授权上下文关联的任务。

此外，接收方 **SHOULD** 对任务操作实施速率限制，以防止拒绝服务和枚举攻击。

### 资源管理

1. 接收方 **SHOULD**：
   1. 对每个请求方的并发任务实施限制
   2. 强制执行最大 `ttl` 时长，以防资源无限期保留
   3. 及时清理过期任务以释放资源
   4. 记录支持的最大 `ttl` 时长
   5. 记录每个请求方的最大并发任务数
   6. 实现资源使用情况的监控和告警

### 审计和日志记录

1. 接收方 **SHOULD**：
   1. 出于审计目的记录任务创建、完成和检索事件
   2. 在可用时将 auth context 包含在日志中
   3. 监控可疑模式（例如大量失败的任务查找、过度轮询）
2. 请求方 **SHOULD**：
   1. 出于调试和审计目的记录任务生命周期事件
   2. 跟踪 task IDs 及其关联操作
