
FastMCP v4 后台任务重构基于 SEP-2663 的 fastmcp-tasks 扩展设计全解【免费下载链接】fastmcp The fast, Pythonic way to build MCP servers and clients.项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp本篇技术指南基于 FastMCP 仓库中已定型并落地Shipped#4602、#4603的 v4 设计文档 dev-docs/v4-notes/background-tasks.md 编写围绕后台任务从 SEP-1686 迁移到 SEP-2663 扩展这条主线展开。文章会说明任务扩展的协议线形状、fastmcp-tasks可选包的打包与激活模型、FastMCP 原生服务端扩展 APImcp.add_extension、客户端三层调用体验以及设计中的范围边界、风险与已定案决策同时结合仓库内fastmcp_tasks包的源码实现与fastmcp核心中的任务声明原语给出可复现的配置与代码依据。读完你可以掌握如何用taskTrueTasksExtension在 FastMCP v4 上运行 MCP 后台任务理解其轮询式协议与 Docket 执行引擎的边界以及这套扩展 API 为何能同时成为未来 MCP Apps 集成的统一入口。TL;DR任务机制保留协议底座换为 SEP-2663FastMCP 的后台任务能力不会消失。MCP 规范把任务协议从核心中移出并合并为一个Final 状态的扩展——io.modelcontextprotocol/tasksSEP-2663它保留了 FastMCP 已经实现的轮询模型。截至当前仓库状态没有任何语言的 SDK 为它提供运行时实现而 FastMCP 拥有唯一接近生产形态的执行引擎Docket/Redis且其协议形态与 SEP-2663 高度一致。因此 v4 的决策是基于 SEP-2663 重建任务支持做成仓库内的可选包fastmcp-tasks用taskTrue门控激活与 MCP Apps 用appTrue门控的模式完全对齐。迁移过程中移除 SEP-1686 的线层wire layer保留并重新安置执行引擎同时引入FastMCP 原生的服务端扩展 API让任务以及后续的 Apps通过一个文档化的统一机制接入而不是继续对核心做特制改动。净效果是已经用mcp.tool(taskTrue)的服务端代码无需任何改动即可平滑过渡且 FastMCP 很可能成为 tasks 扩展在生态中的第一个运行时实现。背景任务的现状SEP-1686 时代FastMCP 3 曾基于SEP-1686短暂存在于 MCP 核心规范中的任务协议实现后台任务。该实现横跨 server、client、CLI 和一个 SDK shim约 4,000 行代码可拆成两个性质完全不同的部分见 fastmcp_tasks 包结构线层wire layer能力通告、tasks/get|result|list|cancel四个处理器、在增强版tools/call上返回的CreateTaskResult以及一个基于 Redis 的推送中继让 worker 能触达客户端以投递通知和 elicitation追问请求。执行引擎execution engine基于 Docket队列、worker、结果存储、TTL支持memory://或redis://后端外加 FastMCP 自己构建的持久化层按 auth 作用域复合键隔离任务访问、跨 worker 进程的请求上下文快照/恢复、与同步路径一致的参数强转以及fastmcp tasks workerCLI。SDK v2 迁移时把 SEP-1686 从核心规范中移除v4 设计笔记一度记录删除任务机制需要任务的用户停留在 FastMCP 3。当时的判断在信息不完整的前提下是正确的——假设后继协议要么不存在、要么不可实现。而这两个假设后来都被证伪。上游变化SEP-2663 做了什么任务协议是被重构而非删除。SEP-2663Tasks Extension已是 Final 状态于 2026-05-15 在上游合并取代 SEP-1686。它定义io.modelcontextprotocol/tasks扩展是一个基于 SEP-2133 扩展机制的能力协商特性保留了 SEP-1686 的轮询核心并加以收紧。线形状wire shape客户端通告任务能力在每次请求的_meta中。这是同意——我能处理任务结果——而不是发起任务的请求。客户端发出普通tools/call。由服务端决定是否以任务方式运行。若被任务化服务端返回CreateTaskResult一个携带resultType: task的 claimed 结果形状其中的taskId由服务端生成。客户端轮询tasks/get直到状态进入终态结果内联在该响应中返回。任务执行过程中的输入elicit/sample/roots采用轮询式状态翻转为input_required未决请求出现在inputRequests映射中客户端通过tasks/update应答。tasks/cancel是协作式的。推送是可选能力notifications/tasks走subscriptions/listen服务端可以不发。与 SEP-1686 的差异设计文档用一张对照表总结了差异最值得注意的是其中大部分是删除——因为规范在向 FastMCP 已经构建的方向靠拢维度SEP-1686旧SEP-2663新FastMCP 现状任务 id 生成客户端生成服务端生成已是服务端生成tasks/list存在移除枚举风险已是返回[]的桩结果获取独立的tasks/result内联进tasks/get合并两个处理器即可tasks/delete存在移除依赖 TTLTTL 是 Docket 原生能力创建竞态notifications/tasks/created必须持久化创建差一个读己之写read-your-writes检查任务内输入推送中继 _meta标记轮询input_requiredtasks/update替换掉最棘手的模块状态集合7 个含submitted、unknown5 个收缩映射表可增强请求任意仅tools/call仅工具面见范围LB 路由未规定Mcp-Name: taskId头共享 Redis 下无关紧要关键点目前没有任何运行时实现。ext-tasks仓库只有 schema 和文字规范TypeScript 与 Python SDK 只携带线类型和一致性测试夹具没有客户端/服务端实现。这个领域是开放的。决策构建它两个事实推翻了之前删除并等待的判断规范正是 FastMCP 已实现的形态只是去掉了一个可以丢弃的推送中继。重建主要由删除和一个薄薄的新线适配器组成而非从零开始。FastMCP 位置独特。SEP-2663 的隐含前提是持久化的服务端存储、服务端生成的高熵 id、容忍最终一致性的创建流程、多节点路由——这恰是 Docket/Redis 提供的。没有其他框架内置了这套能力。在迁移期间继续维护 SEP-1686 机制是死重它是_sdk_patches.pyshim、TaskNotificationHandler以及一批协议时代 xfail 的唯一原因。基于 SEP-2663 重建既能清除这笔技术债又能产出一个零代码改动迁移的旗舰 v4 能力。架构引擎与线的拆分引擎/线分层现有代码已经沿着这条线清晰分离重建只是把边界变成包边界移除SEP-1686 线层——能力通告、四个 CRUD 处理器以及最大的收获整个 Redis 推送中继server/tasks/elicitation.py、notifications.py。它存在只是因为 SEP-1686 没有基于轮询的任务内输入通道SEP-2663 的input_required/tasks/update取代了它。请求/响应存储保留推送信封push envelope不再需要。保留并重新安置Docket 执行引擎、auth 作用域键编码这是tasks/get/update/cancel的授权层——比规范中taskIds 可以当作 bearer token更强、上下文快照/恢复、参数强转、worker CLI。这些全部与线协议无关。新增一个薄的 SEP-2663 线适配器——能力、tasks/get/update/cancel方法以及一个决定是否任务化并执行的tools/call拦截器。在源码中可以看到这条边界的落地核心的 fastmcp_slim/fastmcp/utilities/tasks.py 只保留纯声明——TaskMode、TASKS_EXTENSION_ID反向 DNS 标识io.modelcontextprotocol/tasks、TaskConfig与TaskMeta——而 Docket 相关的依赖注入与安装提示全部迁入 fastmcp_tasks/fastmcp_tasks/dependencies.py模块 docstring 明确写着在 SEP-1686 → SEP-2663 迁移中从 fastmcp.server.dependencies 移出。打包与激活模型fastmcp-tasks是仓库内uvworkspace 成员模板沿用fastmcp_remote独立pyproject.toml、与主版本锁步、通过fastmcp元包再导出。与 MCP Apps 的开发者体验完全平行关注点MCP Apps后台任务作者标记核心mcp.tool(appTrue)mcp.tool(taskTrue)可选包prefab-uifastmcp-tasks额外依赖 extrafastmcp[apps]fastmcp[tasks]缺包行为响亮的安装提示服务端构建时响亮的安装提示核心只保留声明taskTrue/TaskConfig是组件上的元数据不导入任何引擎。引擎和线适配器都住在fastmcp-tasks包里。现有[tasks]extra 从 SEP-1686 机制改指向fastmcp-tasks因此pip install fastmcp[tasks]与taskTrue都会在现代化线协议之下继续工作。激活保持隐式但响亮沿用现有require_docket()模式绝不静默降级任何taskTrue都会在构建期触发对fastmcp-tasks的惰性导入缺装立即抛错。作者标记为任务、却在线内静默执行的工具是一个正确性 bug而不是优雅回退。require_docket的实现可见 fastmcp_tasks/fastmcp_tasks/dependencies.py#L45-L72缺装时提示pip install fastmcp[tasks]装了旧版pydocket时提示升级版本。扩展 APImcp.add_extensionMCP 扩展SEP-2133是 SDK v2 中真正的新抽象——v1 时代并不存在。MCP Apps 当时手工拼接集成并非错误选择而是先于该工具诞生。如今 FastMCP 的服务端完全绕过 SDK 的Extension类把ui能力手工拼接进低级服务端并直接遍历工具元数据而客户端原生转发ClientExtension。每新增一个协议扩展都意味着对核心的特制手术。Tasks 成为推动修复此问题的契机设计引入单一注册点from fastmcp import FastMCP from fastmcp_tasks import TasksExtension mcp FastMCP(Server) mcp.add_extension(TasksExtension(urlredis://...)) # 启用任务所必需 mcp.tool(taskTrue) # 意图这个工具可以以任务方式运行 async def crunch(dataset: str) - str: ...add_extension对taskTrue生效是必需的——不会因为存在taskTrue标记就被自动检测。这是有意为之扩展需要配置后端 URL、worker 并发、TTL 默认值add_extension(TasksExtension(...))是其天然归宿自动检测只会把这些配置打散到 settings/env 中并隐藏启用时刻。要求显式注册能让能力通告保持诚实——服务端仅在扩展已注册时才通告tasks能力。它移除了最危险的 footgun因为没人配置 Redis工具在生产环境静默运行在内存后端上。两个关注点保持清晰分离taskTrue是组件级意图这个工具可以是任务add_extension是服务端级启用与配置这个服务端运行任务方式如下。用了taskTrue却没有注册扩展会在构建期报出响亮的错误。在源码中ServerExtension基类fastmcp_slim/fastmcp/server/extensions.py定义了四类可贡献物协商能力settings()拼接到ServerCapabilities.extensions[identifier]新增请求方法methods()返回MethodBinding注册时通过add_request_handler挂到低级服务端tools/call拦截器intercept_tool_call()是工具体运行前的最后一道门——它组合在 FastMCP 中间件链之后、组件执行之前可以观察、短路或放行调用生命周期lifespan()随服务端生命周期进入/退出——这是 SDK 的Extension所缺失的钩子用于启动后端/worker。基类遵循 SDK 的 httpx 式形状每个贡献方法都有默认实现子类只需覆写所需部分。MethodBinding还有防呆约束不能绑定规范已有的请求方法tools/call、completion/complete等否则会静默遮蔽服务端自己的处理器见 extensions.py#L97-L108。扩展 vs 中间件判别准则为避免过度应用该抽象设计文档给出明确判别器扩展是客户端必须理解的协商性协议变更中间件是客户端永远看不见的单边服务端行为。PII 检测、鉴权、限流走中间件Tasks、Apps 走扩展。一个试金石删掉能力通告——如果客户端的任何行为没有改变那它就是中间件。客户端体验SEP-2663 移除了客户端把这次调用做成任务的标记——由服务端决定。这恰好映射到 FastMCP 现有的两层客户端表面友好的call_tool与低层的call_tool_mcp因此几乎没有新增 APIcall_tool(name, args)友好层通告能力若服务端把调用任务化则透明驱动轮询循环并返回完成后的结果。调用方完全察觉不到是否被任务化。任务内input_required会路由到客户端已有的 elicitation handler经tasks/update应答——因此后台 elicitation 与前台 elicitation 看起来完全一样零新增客户端 API。call_tool_mcp(...)低层把原始CreateTaskResultclaimed 形状交还给自行管理任务的调用方。友好接口上的快速返回标志立即得到Task句柄.status()、.wait()、.cancel()可 await不阻塞——这是进度与取消的逃生舱。客户端侧的实现在 fastmcp_tasks/fastmcp_tasks/client.pyTasksClientExtension自动注册到每个 FastMCPClient上调用方无需任何 opt-in其 claim resolver 在底层把tasks/get轮询到完成再以CallToolResult返回真实结果ToolTask则是显式句柄。模块 docstring 还注明任务只存在于现代协议modern protocol上——在 legacy 连接上 SDK 会剥离能力通告服务端永不任务化该扩展处于惰性inert状态。服务端侧TaskConfig三种模式直接翻译对应 fastmcp_slim/fastmcp/utilities/tasks.py#L42-L62 中的TaskModerequired→ 总是任务化对未声明的客户端返回-32021即MISSING_REQUIRED_CLIENT_CAPABILITYoptional→ 客户端声明了才任务化forbidden→ 永不任务化。TasksExtension.intercept_tool_call的判定逻辑见 fastmcp_tasks/fastmcp_tasks/extension.py#L213-L271它还会解析请求_meta中的版本规范避免对指向旧版本的tools/call错误地任务化最高版本的工具同时只在现代 era2026-07-28 起才认可客户端 opt-in。实操安装、配置与运行安装作为 FastMCP 的tasksextra 安装见 fastmcp_tasks/README.mduv pip install fastmcp[tasks]最小服务端from fastmcp import FastMCP from fastmcp_tasks import TasksExtension mcp FastMCP(Analytics) mcp.add_extension(TasksExtension(urlredis://localhost:6379/0)) mcp.tool(taskTrue) async def analyze(dataset: str) - str: # 长时间运行的工作。客户端立即拿到任务句柄并轮询结果 # 这段代码在后台 worker 中执行。 ...taskTrue是意图声明——该工具可能以任务方式运行——而按规范服务端在每次调用时决定是否真的任务化。需要更精细控制时使用TaskConfigfrom fastmcp.utilities.tasks import TaskConfig mcp.tool(taskTaskConfig(moderequired)) async def must_run_async(n: int) - int: # 总是以任务方式运行未 opt-in 的客户端会被明确告知。 ...注意注册TasksExtension是服务taskTrue工具的前提——工具声明意图扩展提供引擎。服务端注册了taskTrue工具却没有任务扩展会在启动时响亮失败而不是静默在线内运行。配置项与默认值后端在扩展上配置。每个选项都有对应的FASTMCP_DOCKET_*环境变量因此纯环境变量配置的部署可以无参数构造TasksExtension()fastmcp_tasks/fastmcp_tasks/settings.py 中DocketSettings完整定义了这些字段选项环境变量默认值说明urlFASTMCP_DOCKET_URLmemory://后端 URL。memory://用于单进程redis://host:port/db用于分布式 worker。nameFASTMCP_DOCKET_NAMEfastmcp队列名。同名同 URL 的服务端与 worker 共享同一任务队列。worker_nameFASTMCP_DOCKET_WORKER_NAMENoneDocket 自动生成worker 名称。concurrencyFASTMCP_DOCKET_CONCURRENCY10每个 worker 的最大并发任务数。redelivery_timeoutFASTMCP_DOCKET_REDELIVERY_TIMEOUT300s任务重投递超时worker 未在期限内完成任务任务会被重投递给其他 worker。reconnection_delayFASTMCP_DOCKET_RECONNECTION_DELAY5sworker 失去与后端连接后的重连间隔。minimum_check_intervalFASTMCP_DOCKET_MINIMUM_CHECK_INTERVAL50msworker 轮询新任务的频率。调低降低任务拾取延迟但增加 CPU高吞吐生产环境建议调高。此外TasksExtension构造器还接受url、name、worker_name、concurrency、redelivery_timeout、reconnection_delay、minimum_check_interval共 7 个关键字参数extension.py#L86-L108任何未传参数都会回落到环境变量默认值。两组额外的设置类值得了解TasksSettings前缀FASTMCP_TASKS_encryption_key用于对任务上下文快照静态加密。快照携带提交者的访问令牌与 HTTP 头写入 Docket 后端并存活到任务 TTL共享同一任务队列的服务端与 worker 必须配置相同密钥worker 无法解密的快照会让任务失败而不是以匿名身份运行。未设置时快照以明文 JSON 存储。密钥经 PBKDF2 派生 Fernet key任意非空字符串可用但建议至少 32 个随机字符。TasksClientSettings前缀FASTMCP_TASKS_CLIENT_poll_interval默认0.5秒是客户端等待后台任务时回退轮询的上限仅当服务端未通告自己的pollIntervalMs时生效——此时客户端从约20ms起步并倍增到该上限快速任务即时解决、长任务不会锤爆服务端。服务端通告了pollIntervalMs时精确遵从该值并忽略此设置。运行独立 worker分布式基于 Redis 的分布式部署中让专用 worker 进程与服务端并存python -m fastmcp_tasks.worker_cli worker server.py共享同一后端 URL 与队列名的 worker 与服务端共享任务队列因此执行能力可以独立于请求服务的前端节点横向扩展。worker CLI 实现见 fastmcp_tasks/fastmcp_tasks/worker_cli.py。实施顺序Sequencing先设计与单测扩展 API针对 tasks 的全表面能力、方法、拦截、客户端 claims/通知进行设计与测试——作为独立可测层在任务逻辑落地之前先用一个琐碎的内测扩展验证隔离性。构建fastmcp-tasks从被移除的 SEP-1686 层中抽取引擎编写 SEP-2663 适配器移植客户端半边。把 MCP Apps 迁移到扩展 API 上快速跟进不在关键路径上用 Apps 现有的绿色测试作为回归网。Tasks 先行因为只有它能触达扩展 API 的全表面先用 Apps 的子集设计会把自己逼进死角。Apps 成为第二个消费者用于确认设计具有通用性。v1 范围非目标仅轮询。可选的notifications/tasks推送与subscriptions/listen集成推迟到后续fastmcp-tasks版本让第二条 Redis 通知队列就此消亡而非移植。仅tools/call不领先规范。SEP-2663 只增强tools/call。FastMCP 3 曾在 SEP-1686 下对 prompts 和 resources 提供taskTrue先于 SDK——那是个错误它产生了线协议无法表达的能力、一批永久 xfail 和 sdk-feedback #3 的差距。本次重建不会重蹈覆辙task是仅限工具的表面通用 prompt/resource 任务脊梁被丢弃而非携带。若规范将来扩展增强类型表面随之增长。以 experimental 状态发布。ext-tasksschema 标记为 experimental 且无发布版本fastmcp-tasks初期同样标注 experimentalschema 演进时按自身节奏发版。风险与缓解风险缓解规范变动扩展仍为 experimental在无线相关的引擎上放一个薄线适配器以 experimental 发布SEP 本身是 Final即使字段名变动轮询模型也是稳定的。Era 门控——SDK 在 2026 之前的协商版本剥离capabilities.extensionssdk-feedback #2能力通告实质上要求 2026-07-28 eraFastMCP 3 覆盖 legacy 任务。#2 现在门控一个旗舰能力 → 上报上游。同时开发新抽象 全新功能先隔离构建并单测扩展 API步骤 1再在其上落地任务逻辑。命名混淆——[tasks]extra 在同名下改指向有意的 changelog 说明用户代码与 extra 名均不变只有线协议现代化。设计决策已定案以下是曾经的开放分叉维护者已拍板定案记录于此以保证实施方向无歧义线适配器位置——在fastmcp-tasks包内。引擎与 SEP-2663 线适配器都住在包中核心只携带taskTrue声明。这把 experimental schema 的变动与核心隔离代价是与 Apps 先例分叉Apps 的ui线胶水今天仍在核心中——Apps 迁移到扩展 API 时会向该模型收敛。扩展 API 形态——FastMCP 原生mcp.add_extension()启用 tasks 为必需项。选它而非对 SDK 的MCPServer(extensions...)做薄透传是因为 FastMCP 原生 API 能把 SDKExtension不提供的Context、组件注册表、auth 作用域交给扩展。add_extension对taskTrue是必需的不做自动检测——它是后端配置的唯一归宿也是能力通告的诚实来源。客户端默认——友好接口透明完成。call_tool驱动轮询循环并返回完成结果call_tool_mcp暴露原始CreateTaskResult快速返回标志给出Task句柄。experimental 标注——要。fastmcp-tasks至少在一个小版本周期内标注 experimental跟随 experimental 的ext-tasksschema。资源/提示词脊梁——丢弃仅限工具。本次重建不领先 SDK 的可增强请求类型纠正 SEP-1686 时代的错误。延伸阅读设计文档dev-docs/v4-notes/background-tasks.md任务特性一览feature programdev-docs/v4-notes/feature-program.mdfastmcp-tasks包实现fastmcp_tasks/README 见 fastmcp_tasks/README.md核心任务声明原语fastmcp_slim/fastmcp/utilities/tasks.py服务端扩展 API 基类fastmcp_slim/fastmcp/server/extensions.py任务扩展适配器fastmcp_tasks/fastmcp_tasks/extension.py后端/worker 配置fastmcp_tasks/fastmcp_tasks/settings.py客户端任务驱动fastmcp_tasks/fastmcp_tasks/client.py相关测试tests/tasks/、tests/server/test_dependencies.py【免费下载链接】fastmcp The fast, Pythonic way to build MCP servers and clients.项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考