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

# 任务

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

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

模型上下文协议（MCP）允许请求方（根据通信方向的不同，可以是客户端或服务器）使用 **任务** 增强他们的请求。任务是持久的状态机，携带有关其所包装请求的底层执行状态的信息，旨在用于请求方轮询和延迟结果检索。每个任务都可以通过接收方生成的 **任务 ID** 进行唯一标识。

任务对于表示耗时计算和批处理请求非常有用，并且可以与外部作业 API 无缝集成。

## 定义

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

* **请求方：** 发送任务增强请求的一方。这可以是客户端或服务器——任何一方都可以创建任务。
* **接收方：** 接收任务增强请求并执行任务的实体。这可以是客户端或服务器——任何一方都可以接收和执行任务。

## 用户交互模型

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

这种请求方驱动的方法确保了确定性的响应处理，并支持复杂的模式，例如分发并发请求，只有请求方才有足够的上下文来编排这些请求。

实现可以通过任何适合其需求的接口模式来暴露任务——协议本身不强制任何特定的用户交互模型。

## 能力

支持任务增强请求的服务器和客户端 **必须** 在初始化期间声明 `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` 能力，以建立哪些操作支持基于任务的执行。请求方 **应该** 仅在接收方已声明相应能力的情况下使用任务增强请求。

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

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

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

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

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

### 工具级协商

出于任务增强的目的，工具调用被给予特殊考虑。在 `tools/list` 的结果中，工具通过 `execution.taskSupport` 声明对任务的支持，如果存在，其值可以是 `"required"`、`"optional"` 或 `"forbidden"`。

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

1. 如果服务器的能力不包括 `tasks.requests.tools.call`，则客户端 **必须不** 尝试在该服务器的工具上使用任务增强，无论 `execution.taskSupport` 值如何。
2. 如果服务器的能力包括 `tasks.requests.tools.call`，则客户端考虑 `execution.taskSupport` 的值，并相应地处理它：
   1. 如果 `execution.taskSupport` 不存在或为 `"forbidden"`，客户端 **必须不** 尝试将工具作为任务调用。如果客户端尝试这样做，服务器 **应该** 返回 `-32601` (Method not found) 错误。这是默认行为。
   2. 如果 `execution.taskSupport` 为 `"optional"`，客户端 **可以** 将工具作为任务或作为普通请求调用。
   3. 如果 `execution.taskSupport` 为 `"required"`，客户端 **必须** 将工具作为任务调用。如果客户端不尝试这样做，服务器 **必须** 返回 `-32601` (Method not found) 错误。

## 协议消息

### 创建任务

任务增强请求遵循与正常请求不同的两阶段响应模式：

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

要创建任务，请求方发送一个在请求参数中包含 `task` 字段的请求。请求方 **可以** 包含一个 `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` 请求创建任务时，宿主应用程序可能希望在任务执行时将控制权返回给模型。这允许模型在等待任务完成时继续处理其他请求或执行额外的工作。

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

  此指导是非约束性的，是旨在考虑特定用例的临时逻辑。此行为可能会在未来的协议版本中作为 `CreateTaskResult` 的一部分被形式化或修改。
</Note>

### 获取任务

<Note>
  在可流式 HTTP (SSE) 传输中，客户端 **可以** 在任何时候断开与服务器响应 `tasks/get` 请求而打开的 SSE 流的连接。

  虽然此说明关于 SSE 流的具体使用不具有规定性，但所有实现 **必须** 继续遵守现有的 [可流式 HTTP 传输规范](../transports#sending-messages-to-the-server)。
</Note>

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

请求方 **应该** 继续轮询，直到任务达到终止状态（`completed`、`failed` 或 `cancelled`），或者直到遇到 [`input_required`](#input-required-status) 状态。请注意，调用 `tasks/result` 并不意味着请求方需要停止轮询——如果请求方没有主动等待 `tasks/result` 完成，他们 **应该** 继续通过 `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>
  在可流式 HTTP (SSE) 传输中，客户端 **可以** 在任何时候断开与服务器响应 `tasks/result` 请求而打开的 SSE 流的连接。

  虽然此说明关于 SSE 流的具体使用不具有规定性，但所有实现 **必须** 继续遵守现有的 [可流式 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"
      }
    }
  }
}
```

### 任务状态通知

当任务状态更改时，接收方 **可以** 发送 [`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` 请求。

请求方 **必须不** 依赖接收此通知，因为它是可选的。接收方不需要发送状态通知，并且可能选择仅针对某些状态转换发送它们。请求方 **应该** 继续通过 `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. 对于未声明某请求类型任务能力的接收方，**必须**正常处理该类型的请求，忽略任何存在的任务增强元数据。
2. 对于声明了某请求类型任务能力的接收方，**可以**针对非任务增强请求返回错误，要求请求方使用任务增强。

### 任务 ID 要求

1. 任务 ID **必须**为字符串值。
2. 任务 ID **必须**由接收方在创建任务时生成。
3. 任务 ID **必须**在接收方控制的所有任务中保持唯一。

### 任务状态生命周期

1. 任务创建时 **必须** 始于 `working` 状态。
2. 接收方 **必须** 仅通过以下有效路径转换任务状态：
   1. 从 `working`：可以移动到 `input_required`、`completed`、`failed` 或 `cancelled`
   2. 从 `input_required`：可以移动到 `working`、`completed`、`failed` 或 `cancelled`
   3. 状态为 `completed`、`failed` 或 `cancelled` 的任务处于终端状态，**不得** 转换到任何其他状态

**任务状态状态图：**

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

    working --> input_required
    working --> terminal

    input_required --> working
    input_required --> terminal

    terminal --> [*]

    note right of terminal
        终端状态：
        • completed
        • failed
        • cancelled
    end note
```

### 需要输入状态

<Note>
  使用可流式 HTTP (SSE) 传输时，服务器通常在传递响应消息后关闭 SSE 流，这可能导致用于后续任务消息的流产生歧义。

  服务器可以通过将消息入队到客户端来处理这种情况，以便在其他响应旁边通过侧通道传递任务相关消息。

  服务器在任务轮询和结果检索期间管理 SSE 流的方式具有灵活性，客户端 **应该** 预期消息会在任何 SSE 流上交付，包括 HTTP GET 流。
  一种可能的方法是在 `tasks/result` 上维护一个 SSE 流（参见关于 `input_required` 状态的注释）。
  在可能的情况下，服务器 **不应** 响应 `tasks/get` 请求而升级到 SSE 流，因为客户端已表明它希望轮询结果。

  虽然此注释并未规定 SSE 流的具体用法，但所有实现 **必须** 继续遵守现有的 [可流式 HTTP 传输规范](../transports#sending-messages-to-the-server)。
</Note>

1. 当任务接收方拥有请求方完成任务所必需的消息时，接收方 **应该** 将任务移动到 `input_required` 状态。
2. 接收方 **必须** 在请求中包含 `io.modelcontextprotocol/related-task` 元数据以将其与任务关联。
3. 当请求方遇到 `input_required` 状态时，**应该** 主动调用 `tasks/result`。
4. 当接收方收到所有必需的输入时，任务 **应该** 转换出 `input_required` 状态（通常返回 `working`）。

### TTL 与资源管理

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

### 结果检索

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

### 关联任务相关消息

1. 所有与任务相关的请求、通知和响应 **必须** 在其 `_meta` 字段中包含 `io.modelcontextprotocol/related-task` 键，其值设置为包含 `taskId` 的对象，该 `taskId` 与关联的任务 ID 匹配。
   1. 例如，任务增强工具调用所依赖的信息收集 (elicitation) **必须** 与该工具调用的任务共享相同的相关任务 ID。
2. 对于 `tasks/get`、`tasks/result` 和 `tasks/cancel` 操作，请求中的 `taskId` 参数 **必须** 用作识别目标任务的事实来源。请求方 **不应** 在这些请求中包含 `io.modelcontextprotocol/related-task` 元数据，如果存在此类元数据，接收方 **必须** 忽略它而优先使用 RPC 方法参数。
   同样，对于 `tasks/get`、`tasks/list` 和 `tasks/cancel` 操作，接收方 **不应** 在结果消息中包含 `io.modelcontextprotocol/related-task` 元数据，因为 `taskId` 已存在于响应结构中。

### 任务通知

1. 当任务状态更改时，接收方 **可以** 发送 `notifications/tasks/status` 通知。
2. 请求方 **不得** 依赖接收 `notifications/tasks/status` 通知，因为它是可选的。
3. 发送时，`notifications/tasks/status` 通知 **不应** 包含 `io.modelcontextprotocol/related-task` 元数据，因为任务 ID 已存在于通知参数中。

### 任务进度通知

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

### 任务列表

1. 接收方 **应该** 使用基于游标的分页来限制单个响应中返回的任务数量。
2. 如果有更多任务可用，接收方 **必须** 在响应中包含 `nextCursor`。
3. 请求方 **必须** 将游标视为不透明令牌，不要尝试解析或修改它们。
4. 如果请求方可通过 `tasks/get` 检索任务，则 **必须** 可通过 `tasks/list` 为该请求方检索。

### 任务取消

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

## 消息流

### 基本任务生命周期

```mermaid theme={null}
sequenceDiagram
    participant C as 客户端 (请求方)
    participant S as 服务器 (接收方)
    Note over C,S: 1. 任务创建
    C->>S: 带有任务字段 (ttl) 的请求
    activate S
    S->>C: CreateTaskResult (taskId, status: working, ttl, pollInterval)
    deactivate S
    Note over C,S: 2. 任务轮询
    C->>S: tasks/get (taskId)
    activate S
    S->>C: working
    deactivate S
    Note over S: 任务处理继续...
    C->>S: tasks/get (taskId)
    activate S
    S->>C: working
    deactivate S
    Note over S: 任务完成
    C->>S: tasks/get (taskId)
    activate S
    S->>C: completed
    deactivate S
    Note over C,S: 3. 结果检索
    C->>S: tasks/result (taskId)
    activate S
    S->>C: 结果内容
    deactivate S
    Note over C,S: 4. 清理
    Note over S: 创建后经过 ttl 周期，任务被清理
```

### 带有信息收集的任务增强工具调用

```mermaid theme={null}
sequenceDiagram
    participant U as 用户
    participant LLM
    participant C as 客户端 (请求方)
    participant S as 服务器 (接收方)

    Note over LLM,C: LLM 发起请求
    LLM->>C: 请求操作

    Note over C,S: 客户端增强任务
    C->>S: tools/call (ttl: 3600000)
    activate S
    S->>C: CreateTaskResult (task-123, status: working)
    deactivate S

    Note over LLM,C: 客户端继续处理其他请求<br/>同时任务在后台执行
    LLM->>C: 请求其他操作
    C->>LLM: 其他操作结果

    Note over C,S: 客户端轮询状态
    C->>S: tasks/get (task-123)
    activate S
    S->>C: working
    deactivate S

    Note over S: 服务器需要来自客户端的信息<br/>任务移动到 input_required

    Note over C,S: 客户端轮询并发现 input_required
    C->>S: tasks/get (task-123)
    activate S
    S->>C: input_required
    deactivate S

    Note over C,S: 客户端打开结果流
    C->>S: tasks/result (task-123)
    activate S
    S->>C: elicitation/create (related-task: task-123)
    activate C
    C->>U: 提示用户输入
    U->>C: 提供信息
    C->>S: elicitation response (related-task: task-123)
    deactivate C
    deactivate S

    Note over C,S: 客户端关闭结果流并恢复轮询

    Note over S: 任务继续处理...<br/>任务移回 working

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

    Note over S: 任务完成

    Note over C,S: 客户端轮询并发现完成
    C->>S: tasks/get (task-123)
    activate S
    S->>C: completed
    deactivate S

    Note over C,S: 客户端检索最终结果
    C->>S: tasks/result (task-123)
    activate S
    S->>C: 结果内容
    deactivate S
    C->>LLM: 处理结果

    Note over S: 结果从创建起保留 ttl 周期
```

### 任务增强采样请求

```mermaid theme={null}
sequenceDiagram
    participant U as 用户
    participant LLM
    participant C as 客户端 (接收方)
    participant S as 服务器 (请求方)

    Note over S: 服务器决定发起请求

    Note over S,C: 服务器请求客户端操作 (任务增强)
    S->>C: sampling/createMessage (ttl: 3600000)
    activate C
    C->>S: CreateTaskResult (request-789, status: working)
    deactivate C

    Note over S: 服务器继续处理<br/>同时等待结果

    Note over S,C: 服务器轮询结果
    S->>C: tasks/get (request-789)
    activate C
    C->>S: working
    deactivate C

    Note over C,U: 客户端可以向用户展示请求
    C->>U: 审查请求
    U->>C: 批准请求

    Note over C,LLM: 客户端可能涉及 LLM
    C->>LLM: 请求完成
    LLM->>C: 返回完成

    Note over C,U: 客户端可以向用户展示结果
    C->>U: 审查结果
    U->>C: 批准结果

    Note over S,C: 服务器轮询并发现完成
    S->>C: tasks/get (request-789)
    activate C
    C->>S: completed
    deactivate C

    Note over S,C: 服务器检索结果
    S->>C: tasks/result (request-789)
    activate C
    C->>S: 结果内容
    deactivate C

    Note over S: 服务器继续处理

    Note over C: 结果从创建起保留 ttl 周期
```

### 任务取消流程

```mermaid theme={null}
sequenceDiagram
    participant C as 客户端 (请求方)
    participant S as 服务器 (接收方)

    Note over C,S: 1. 任务创建
    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. 任务处理
    C->>S: tasks/get (task-123)
    activate S
    S->>C: working
    deactivate S

    Note over C,S: 3. 客户端取消
    Note over C: 用户请求取消
    C->>S: tasks/cancel (taskId: task-123)
    activate S

    Note over S: 服务器停止执行 (尽力而为)
    Note over S: 任务移动到 cancelled 状态

    S->>C: 任务 (status: cancelled)
    deactivate S

    Note over C: 客户端收到确认

    Note over S: 服务器可自行决定删除任务
```

## 数据类型

### 任务

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

* `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`（数字，可选）：请求从创建起保留任务的持续时间（毫秒）

### 相关任务元数据

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

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

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

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

## 错误处理

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

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

### 协议错误

接收方 **必须** 为以下协议错误情况返回标准 JSON-RPC 错误：

* `tasks/get`、`tasks/result` 或 `tasks/cancel` 中的 `taskId` 无效或不存在：`-32602`（无效参数）
* `tasks/list` 中的游标无效或不存在：`-32602`（无效参数）
* 尝试取消已处于终端状态的任务：`-32602`（无效参数）
* 内部错误：`-32603`（内部错误）

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

* 当接收方要求该请求类型必须进行任务增强时，收到非任务增强的请求：`-32600`（无效请求）

接收方 **应该** 提供信息丰富的错误消息以描述错误原因。

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

```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` 响应 **应该** 包含一个 `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` 端点返回的内容与底层请求原本将返回的内容完全一致：

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

## 安全考虑

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

任务 ID 是访问任务状态和结果的主要机制。如果没有适当的访问控制，任何能够猜测或获取任务 ID 的一方都可能访问敏感信息或操纵他们未创建的任务。

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

上下文绑定并不适用于所有应用程序。某些 MCP 服务器在没有授权的环境中运行，例如单用户工具，或使用不支持授权的传输方式。
在这些场景中，接收方 **应该** 清楚地记录此限制，因为任务结果可能被任何能够猜测任务 ID 的请求方访问。
如果上下文绑定不可用，接收方 **必须** 生成具有足够熵值的加密安全任务 ID 以防止猜测，并应考虑使用更短的 TTL 持续时间以减少暴露窗口。
此外，无法识别请求方的接收方 **不应** 声明 `tasks.list` 能力，因为列出任务会将任务元数据暴露给任何请求方，无论任务 ID 的熵值如何。

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

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

### 资源管理

1. 接收方 **应该**：
   1. 对每个请求方的并发任务数实施限制
   2. 实施最大 `ttl` 持续时间限制，以防止无限期保留资源
   3. 及时清理过期任务以释放资源
   4. 记录支持的最大 `ttl` 持续时间
   5. 记录每个请求方的最大并发任务数
   6. 实施资源使用的监控和警报

### 审计与日志记录

1. 接收方 **应该**：
   1. 记录任务创建、完成和检索事件以供审计
   2. 在日志中包含授权上下文（如果可用）
   3. 监控可疑模式（例如，许多失败的任务查找、过度轮询）
2. 请求方 **应该**：
   1. 记录任务生命周期事件以供调试和审计
   2. 跟踪任务 ID 及其关联的操作
