Skip to content
MCP 文档版本 2026-07-28 更新于 2026-10-14

Tasks

面向长时间运行的 MCP 操作的异步任务执行

ext-tasks 仓库包含 MCP Tasks 的完整规范与文档。

modelcontextprotocol/ext-tasks

MCP Tasks 的完整规范与文档。

并非每次工具调用都会立即返回。有些操作——CI 流水线、批处理、人工审批——需要数秒、数分钟甚至更长时间。MCP Tasks 让服务端返回一个持久化句柄,而不是阻塞等待,这样客户端就可以轮询进度、在需要时提供输入,并在重新连接后获取最终结果。

为什么不直接阻塞?

你当然可以一直保持连接打开,直到工作完成。但 Tasks 解决了阻塞无法解决的问题:

  • 无需长连接。 阻塞会在操作期间一直占用连接。许多客户端和传输中间层都设有超时,使得阻塞超过几秒就变得不切实际。
  • 崩溃恢复能力。 任务 ID 是一个持久化句柄。如果客户端断开连接或重启,它可以用同一个 ID 恢复轮询。
  • 进度可见性。 Tasks 携带状态元数据(working、input_required、completed、failed、cancelled)以及可选的状态消息,让客户端能够看到进度。
  • 执行中途交互。 当任务需要输入时(例如通过征询请求用户确认),它会转为 input_required 并暴露该请求。客户端通过 tasks/update 进行响应——无需第二条连接,也无需服务端主动向客户端发送消息。
  • 服务端主导。 由服务端逐请求决定是否创建任务。客户端只需通过扩展能力一次性选择加入,然后处理到达的任意结果形态。无需按工具预热,也无需按请求设置标志。

Tasks 如何工作

Tasks 扩展了标准请求流程。当服务端判定某个请求将长时间运行时,它会返回一个任务句柄,而不是最终结果。客户端随后轮询完成情况。

  1. 能力协商。 客户端在其逐请求能力中包含 io.modelcontextprotocol/tasks。服务端在其自身的 server/discover 能力中声明同一扩展。

  2. 任务创建。 针对受支持的请求,服务端返回一个 CreateTaskResult(由 resultType: "task" 标识),其中包含 taskId、 初始状态、TTL 和建议的轮询间隔。任务在响应发送之前就已持久化创建。

  3. 轮询。 客户端使用 taskId 调用 tasks/get。响应携带当前状态,对于终态还会携带最终结果或错误。

  4. 执行中途输入。 如果任务转为 input_required,tasks/get 响应会包含一个 inputRequests 映射,其中带有征询或其他服务端请求。客户端通过 tasks/update 完成这些请求。

  5. 完成。 当状态达到 completed 时,result 字段 包含原请求在同步情况下本应返回的内容。如果状态为 failed,error 字段包含 JSON-RPC 错误。

  6. 取消。 客户端可以随时发送 tasks/cancel。 取消是协作式的——服务端确认该意图,但没有义务停止工作。

sequenceDiagram
    participant Client
    participant Server

    Client->>Server: tools/call (with tasks capability)
    Server-->>Client: CreateTaskResult (taskId, status: working)

    loop Poll until terminal
        Client->>Server: tasks/get (taskId)
        Server-->>Client: Task (status: working)
    end

    Note over Client,Server: Server needs user input
    Client->>Server: tasks/get (taskId)
    Server-->>Client: Task (status: input_required, inputRequests)
    Client->>Server: tasks/update (taskId, inputResponses)
    Server-->>Client: ack

    loop Poll until terminal
        Client->>Server: tasks/get (taskId)
        Server-->>Client: Task (status: working)
    end

    Client->>Server: tasks/get (taskId)
    Server-->>Client: Task (status: completed, result)

何时使用 Tasks

当你的用例涉及以下情况时,Tasks 是一个很好的选择:

长时间运行的操作。 需要数分钟或数小时的 CI 流水线、批数据处理或模型训练作业。

人在回路的工作流。 审批关卡、审核步骤,或任何需要暂停等待用户确认的操作。任务会转为 input_required,客户端则呈现该请求。

外部作业系统。 如果你的服务端封装了一个已经使用作业 ID 的 API(云部署、异步 API、排队工作),那么在你创建作业时返回一个任务,并在作业完成时将其解决。

不可靠的连接。 移动客户端、间歇性网络,或连接会中断的环境。任务 ID 能在断开连接后继续存在。

批处理。 处理大量条目的操作(批量导入、批量更新),其中部分进度是有意义的。状态消息会报告进度。

任务生命周期

状态含义
working操作正在进行中。
input_required服务端在继续之前需要客户端输入。参见 inputRequests。
completed操作已完成。result 字段包含最终输出。
failed执行期间发生了 JSON-RPC 错误。error 字段包含详细信息。
cancelled操作已被取消(不一定会被真正执行)。

completed、failed 和 cancelled 是终态——一旦到达,任务状态不再改变。

通知

服务端可以通过 notifications/tasks 推送状态更新。客户端通过 subscriptions/listen 机制选择接收这些通知。每条通知都携带完整的任务状态,从而无需额外进行一次 tasks/get 往返。

轮询是默认方式。如果服务端支持通知,客户端可以依赖通知而非轮询。

实现指南

面向 MCP 客户端

要消费任务增强型响应,你的客户端必须:

声明支持

在其逐请求能力中包含该扩展:

```jsonc
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "...",
  "params": {
    // Other fields...
    "_meta": {
      // Other fields...
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {
          "io.modelcontextprotocol/tasks": {},
        },
      },
    },
  },
}
```

处理多态结果

在发出受支持的请求(例如 `tools/call`)时,要准备好接收标准结果或带有 `resultType: "task"` 的 `CreateTaskResult`。

轮询完成状态

使用返回的 `taskId` 调用 `tasks/get`,并遵守 `pollIntervalMs` 值。持续轮询,直到任务达到终态(`completed`、`failed` 或 `cancelled`)。

处理输入请求

如果任务状态为 `input_required`,读取 `inputRequests` 映射,将请求呈现给用户或模型,并通过 `tasks/update` 提交响应。

持久化任务 ID

持久存储任务 ID,以便在客户端崩溃或重启后能够恢复轮询。

面向 MCP 服务端

要从你的服务端返回任务:

声明支持

在你的 `server/discover` 能力中包含该扩展:

```jsonc
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    // Other fields...
    "capabilities": {
      "extensions": {
        "io.modelcontextprotocol/tasks": {},
      },
    },
  },
}
```

检查客户端能力

在返回 `CreateTaskResult` 之前,确认客户端已在其逐请求能力中包含该扩展。绝不要向未声明支持的客户端返回任务。

返回 CreateTaskResult

当请求将长时间运行时,以 `resultType: "task"` 和一个 `Task` 对象作为响应,该对象包含唯一的 `taskId`、初始状态、`ttlMs` 和 `pollIntervalMs`。任务必须在发送响应之前持久创建。

提供 tasks/get

在每次轮询时返回当前任务状态。对于终态,包含 `result`(在 `completed` 时)或 `error`(在 `failed` 时)字段。

处理 tasks/update

接受以未完成的 `inputRequests` 为键的 `inputResponses`。以空结果确认。忽略针对未知或已满足键的响应。

处理 tasks/cancel

以空结果确认取消请求。尽可能遵从,但取消是协作式的——任务仍可能达到非 `cancelled` 的终态。

客户端支持

NOTE

MCP Tasks 是核心 MCP 规范的扩展。宿主支持因客户端而异。

有关各客户端对扩展的支持情况,请参阅客户端矩阵。任务支持需要客户端和服务端双方的显式选择加入。

规范

Tasks 扩展在 ext-tasks 仓库中定义。它使用标准的 MCP 扩展协商机制:客户端在每个请求的 _meta 中发送的 io.modelcontextprotocol/clientCapabilities 的 extensions 字段中声明支持,服务端在 server/discover 返回的能力中声明其支持。

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。