ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

FastMCP v4 特性计划(Feature Program)全解析:采样移除、MRTR 启发式交互与 2026 协议时代的演进路线

FastMCP v4 特性计划(Feature Program)全解析:采样移除、MRTR 启发式交互与 2026 协议时代的演进路线 FastMCP v4 特性计划Feature Program全解析采样移除、MRTR 启发式交互与 2026 协议时代的演进路线【免费下载链接】fastmcp The fast, Pythonic way to build MCP servers and clients.项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp导读本文基于 FastMCP 仓库 v4 开发笔记中的 feature-program.md系统梳理 FastMCP v4.0 在 MCP Python SDK v2 迁移之后的前向特性计划Feature Program包括采样Sampling与 roots 的服务器端移除、基于多轮往返MRTR的启发式交互Elicitation、首个一等公民的 2026 客户端、FastMCP 原生扩展 API、SEP-2663 后台任务重建以及第二轮 SDK 委托收敛。读完本文你将掌握 v4 每项特性的状态判定体系Shipped / Designed / Planned / Not started、每项特性与 change-register.md、background-tasks.md、known-gaps.md 的对应关系并能据仓库源码核验每项结论的落地位置。背景v4 的三股驱动力与特性状态体系FastMCP v4.0 本质上是引擎换底engine swap。根据 index.md 的说明三股力量推动了大版本号MCP Python SDK v2 重建协议类型从mcp.types拆分为独立的mcp_types包所有协议字段从 camelCase 改为 snake_case如inputSchema→input_schema、mimeType→mime_type、isError→is_error。服务端请求处理模型重写handler 按方法字符串注册并返回裸结果模型不再有request_ctxContextVar服务端中间件成为 SDK 的一等概念。协议版本 2026-07-28SDK v2 单服务器可同时服务多个协议时代。在有会话的握手handshake时代之外引入了无会话sessionless的2026-07-28时代——通过server/discover发现能力并移除了服务端发起的请求SEP-2577。采样与 roots 从服务器 API 中移除2026-07-28时代移除了服务端在调用中途向客户端推送请求的能力这使ctx.sample、ctx.sample_step、ctx.list_roots无法工作。v4.0 选择将它们从服务器 API 中彻底移除而不是让它们只对旧客户端半工作。迁移是基础而本篇文章的主角——前向 v4 特性计划——是一系列基于迁移合并后的 PR 序列。每项特性都携带明确的状态标记状态含义Shipped已合并到main并附有对应 PRDesigned方案已定存在 API 草图尚未开始实现Planned形态已达成一致但设计细节仍待敲定Not started被识别为 v4 范围但尚未设计文中标注为 sketch 的代码块展示的是预期 API在当前代码树中尚无法解析。这一点在阅读下文代码示例时需特别注意。采样移除Sampling removal——Shipped in 4.0为什么采样必须死采样是推送形状push-shaped的 API服务端在调用中途借用客户端的模型ctx.sample、ctx.sample_step。2026-07-28时代移除了服务端发起的请求因此它无法在现代连接上工作而Client切换到modeauto默认值后现代连接成了默认体验而非边缘情况——时代门控era gate从边缘情况变成了默认体验。另外后台任务中的采样在 v2 下早已名存实亡worker 的后向通道back-channel在提交请求返回后即消失而从未构建过中继sdk-feedback #9。移除的完整清单弃用与时代门控在 #4448 中落地而移除完成了整个计划。以下内容全部消失ctx.sample、ctx.sample_step、ctx.list_rootsserver/sampling/包含SamplingTool与结构化结果采样FastMCP(sampling_handler..., sampling_handler_behavior...)examples/sampling/从源码看这一移除是硬移除。在 server/context.py 中已无sample/sample_step/list_roots方法server/server.py 的_REMOVED_KWARGS映射表会对FastMCP()传入的已移除 kwargs 抛出点名 SEP-2577 与迁移方向的TypeError。调用已移除的 Context 方法则直接触发AttributeError。仓库 change-register.md 将该变更标记为Breaking并给出验证位置tests/server/test_protocol_eras.py::test_removed_server_initiated_methods_are_absent。迁移故事没有 drop-in只有架构建议文档明确承认不存在一键替换no drop-in。指引是架构层面的——采样从你的服务器直接调用 LLM使用你自己的 API key而不是借用客户端的模型。roots把路径作为工具参数传入或通过 guard 模式其input_requests映射仍携带ListRootsRequest向客户端询问。什么被刻意保留客户端侧并不受影响客户端侧 provider handlersAnthropic、OpenAI、Google GenAI以及Client(sampling_handler..., roots...)保留——因为 FastMCP 客户端仍必须应答旧服务器legacy server的请求且 MRTR 需要客户端侧的这些 handlers。被移除的只是服务端推送发射器。ProxyClient的默认中继 handlers 因同样的互操作原因保留但现在直接调用 SDK 会话。这一服务端移除、客户端保留的边界在 client/client.py 中可见——sampling_handler仍是Client构造参数之一服务于应答旧服务器的互操作场景。MRTR 启发式交互MRTR elicitation——Guard 形式已发布声明式Resolve层已设计启发式交互如何在现代时代存活启发式交互通过多轮往返multi-round-tripMRTR在现代时代存活。2026 线路信封wire envelope将启发式交互编码为多轮输入请求工具返回InputRequiredResult并每轮重新执行每一轮都是完整的请求→响应周期。命令式ctx.elicit依赖会话后向通道而该通道在2026-07-28前台调用上已不存在在现代时代启发式交互只能通过 MRTR 触达。Guard 形式已发布4.0 中已发布的 guard 形式为工具返回InputRequiredResult并从ctx.input_responses/ctx.request_state读取客户端的回答每轮重新运行。它精确镜像了 SDK 的基础 guard 模型——没有 FastMCP 自创的 DX框架负责request_state的密封在握手时代连接上返回该结果会产生清晰的时代错误。从源码核验server/mixins/mcp_operations.py 的_on_call_tool将InputRequiredToolResult定义于 tools/base.py包装后通过 runner 以resultType: input_required到达线路server/context.py 提供input_responses/request_state属性框架在低层服务器上安装 SDK 的RequestStateBoundary中间件密封每个外发request_state并在工具运行前解封与验证每个入站回声——工具只看到明文篡改、过期或外部 token 被以冻结的线路错误拒绝server/server.py 的FastMCP(request_state_securityRequestStateSecurity(keys[...]))为多副本部署提供共享密钥省略时每个进程在临时密钥下密封单进程场景正确。尚未构建的声明式Resolve(...)层剩余工作是位于上述已发布原语之上的声明式Resolve(...)层当前状态为Designed方案已定、有 API 草图、未实现一个新的fastmcp.elicitation模块——Resolve、Elicit、ElicitationResult——作为 SDK resolver 的薄封装接入 FastMCP 自己的工具层FastMCP 工具不继承 SDK 的自动 resolver 接线。它将检测Annotated[_, Resolve(...)]参数、构建 resolver 计划并在第一轮返回 SDK 的InputRequiredResult而非工具体。以下为预期 API 草图testskip标记表明该模块当前尚不存在不可解析from typing import Annotated from pydantic import BaseModel from fastmcp import FastMCP, Context from fastmcp.elicitation import Resolve, Elicit, ElicitationResult mcp FastMCP(shipping) class Address(BaseModel): street: str city: str zip: str async def ask_address(ctx: Context) - Elicit[Address]: return Elicit(Where should we ship this order?, Address) mcp.tool async def create_shipment( order_id: str, address: Annotated[Address, Resolve(ask_address)], # unwrapped; decline - ToolError ) - str: return fShipping {order_id} to {address.city} mcp.tool async def maybe_ship( order_id: str, address: Annotated[ElicitationResult[Address], Resolve(ask_address)], # full outcome ) - str: if address.action ! accept: return cancelled return fShipping {order_id} to {address.data.city}注意两种声明式的差异create_shipment中Annotated[Address, Resolve(...)]在用户拒绝时抛ToolErrormaybe_ship中Annotated[ElicitationResult[Address], Resolve(...)]携带完整结果actiondata使工具可以优雅处理 cancelled 分支。命令式ctx.elicit的去向命令式ctx.elicit不会被重新接回以在现代时代存活在旧时代legacy eras通过会话后向通道工作在2026-07-28前台调用上被时代门控为抛出清晰错误在 #4448 中发布指引用户改用 guard 形式。早期通过后台任务中继让命令式ctx.elicit在现代连接上存活的计划双重死亡guard 模型取而代之且中继依赖的 2025 任务机制已被列入移除见 known-gaps.md。为什么启发式交互幸存而推送式采样没有文档给出一个决定性事实SDK 为启发式交互构建了服务端发射器Elicit/Resolve而没有为采样构建。线路携带全部三种输入请求类型sampling / elicitation / roots客户端也分发全部三种但只有启发式交互能由服务端产生。这就是启发式交互通过 MRTR 在 4.0 幸存、而推送式采样没有的原因。客户端侧已有基础FastMCP 客户端通过其启发式交互回调分发输入请求client/client.py 的_resolve_input_requiredinput_required_max_rounds上限控制驱动 SEP-2322 的InputRequiredResult直至终态这印证了剩余声明式工作只需确认 FastMCP 客户端像 SDK 自身客户端一样驱动 input-required driver的论断。中间件根分发Middleware root dispatch——Shipped#4553迁移已通过FastMCPServerMiddleware将initialize拦截路由到 SDK 的ServerMiddleware列表。#4553使该入口成为中间件分发的根FastMCP 的方法无关钩子on_message、on_request、on_notification现在对每一条入站消息触发——客户端取消、进度通知以及路由或验证失败请求——而不仅是到达组件 handler 的消息。组件方法继续运行自己的内部链方法集合加分发标志dispatch flag使两条通路互不重叠每个钩子对每条消息恰好触发一次。从源码核验FastMCPServerMiddleware定义于 server/low_level.py其_INTERIOR_METHODS同文件 L45方法集合用于区分内部已分发与根分发两条通路server/middleware/middleware.py 中的MiddlewarePhase与mark_interior_dispatched实现去重server/server.py 的_dispatch_component_middleware保持组件内部链。验证测试位于tests/server/middleware/test_message_visibility.py。全部十三个内置中间件在改动后无需修改即通过其测试套件。这一特性在 change-register.md 中被标记为New (coverage)。一等公民 2026 客户端First-class 2026 client——部分发布完整组合被上游阻塞已发布的客户端部分fastmcp.Client现在默认modeauto#4572探测server/discover回退到经典握手通过现有 handlers 应答多轮input_required请求同一 PR 还浮出extensions和result_claimsSEP-2133。客户端还放弃了其派生的协议辅助函数——扩展折叠、驱逐消息 handler、discover 综合——改用 SDK 自己的实现#4574。从源码核验 client/client.pymode参数文档明确auto默认探测server/discover并协商现代时代对任何不是现代对端正面证据的服务器按拒绝列表回退到 initialize 握手legacy强制握手、与 v4 前行为逐字节一致现代版本字符串如2026-07-28直接采纳该版本而无需探测。决策组合而非包装D16此处决策是compose, not wrapD16在 SDK 高层mcp.Client之上重建fastmcp.Client而非包装mcp.ClientSession。可干净组合的部分已发布其余部分在上游被双重阻塞mcp.Client在单一硬编码位置构造其ClientSession无注入钩子而 FastMCP 的session_class是承重设计ProxyClient替换为跳过结果验证的会话使后端 schema 违规在终端客户端暴露而非变成代理错误——需要一个与早前添加的notification_bindings参数同形的session_factory钩子。mcp.Client.__aenter__拒绝重入而 FastMCP 客户端刻意可重入其引用计数的上下文管理器用于修复代理会话复用死锁——重建还需 SDK 客户端容忍可重入进入。两者都必须先在上游落地session_factory单独是必要但不充分的。该工作流还拥有服务端无状态设计空洞——ctx.session_id/set_state往返和状态化代理亲和性——因为它们都归结为同一个问题没有会话时什么是会话 完整核算见 known-gaps.md 与 change-register.md。无状态时代的三个事实层级Known Gapsknown-gaps.md 给出了诚实的三分法仅针对2026-07-28连接当今所有客户端协商握手时代行为与以往完全一致协议构造上仅旧时代可用记录而非构建按会话日志级别、EventStore/可恢复性、ping 保活。构造上已无状态在现代可用tasks/get轮询按task_id键控、Docket/Redis 支撑、OAuth bearer 验证每次 POST 携带并重新验证凭据、请求内进度与日志通知随该 POST 自身的 SSE 汇送达。推迟到多协议工作流的设计空洞ctx.session_id/ctx.set_state/ctx.get_state现代请求上session_id铸造新鲜uuid4、缓存在请求返回即弃的connection.state上因此 set/get 静默不往返——无错误只是丢数据状态化代理亲和性退化代理_caches按请求级Connection键控现代连接上塌缩为无状态代理。危险在于代码当前不报错地返回读起来像可用实为静默降级。订阅、缓存提示、扩展、OTelSubscriptions, cache hints, extensions, OTel——状态分化一组为 v4 跟踪的协议特性群状态已分化缓存提示——已发布#4464服务端级作者体验FastMCP(cache_ttl..., cache_scope...)SEP-2549为每个可缓存结果盖章FastMCP 客户端通过选择加入的响应缓存遵循提示。源码位置server/server.py 的cache_ttl/cache_scope参数经build_cache_hintsserver/caching.py生成提示。cache_ttl以秒为单位cache_scope为public或private设 TTL 时默认private仅有 scope 而无 TTL 会在构造时被拒绝scope 单独不启用缓存因为客户端以 TTL 存在为门控。验证测试tests/server/test_cache_hints.py单元验证 与fastmcp.Client(cacheTrue)的端到端互操作。OpenTelemetry——已发布#4481span 默认开启无 exporter 时为空操作属性与 SDK 对齐FASTMCP_TELEMETRY_MODE设置支持native/propagation_only/off。对应 settings.py 的telemetry_mode与 telemetry.py 的实现。扩展——客户端侧已发布#4572Client(extensions..., result_claims...)广告选择加入的客户端扩展SEP-2133。服务端侧是独立的 Designed 工作流见下节。extensions/MCP Apps 能力广告的跨时代调和仍待定该能力在 pre-2026 协商版本被剥离——sdk-feedback #2。订阅——未启动Not started计划为subscriptions/listen表面由订阅总线支撑。FastMCP 原生扩展 APIFastMCP-native extension API——Shipped#4602扩展是什么MCP 扩展SEP-2133是可选的、能力协商的协议特性由反向 DNS 字符串标识——io.modelcontextprotocol/uiMCP Apps、io.modelcontextprotocol/tasksSEP-2663。它们是 SDK v2 中真正的新抽象v1 中不存在。SDK 通过Extension服务器类暴露它们贡献一个能力、加法请求方法、一个tools/call拦截器外加对称的ClientExtension含结果声明与通知绑定。现状与设计FastMCP 已原生转发ClientExtensionClient(extensions...)#4572。服务端则完全不使用 SDK 的Extension类MCP Apps 先于该抽象存在因此 FastMCP 在低层服务器上手工拼接ui能力到get_capabilities()并直接遍历工具元数据。这对一个扩展有效但每个新协议扩展都意味着对核心的定制手术bespoke surgery。设计中的工作是 FastMCP 原生服务器扩展 API——单一注册点mcp.add_extension(...)贡献协商能力、请求方法与tools/call拦截器并可访问 SDK 的Extension未提供的 FastMCP 级构造组件注册表、Context、auth scope。它以 SEP-2663 tasks 扩展为设计目标因为 tasks 锻炼了完整表面——能力和方法和拦截和客户端声明/通知——而 MCP Apps 只锻炼子集。Tasks 是探路者pathfinderMCP Apps 作为快速跟进迁移到扩展 API删除手工拼接并确认设计可泛化。扩展与中间件的判别器扩展 API 与中间件的区分标准扩展是客户端必须理解的协商契约变更中间件是客户端永远看不到的单边服务器行为。删除能力广告而客户端行为不变——那才是中间件。PII 检测、认证、限流属于中间件Tasks、Apps 属于扩展。判定测试删除能力广告——如果客户端行为毫无变化它就是中间件。后台任务SEP-2663——Shipped#4603重新构建的形态后台任务以fastmcp-tasks仓库内可选包形式回到现代时代重建于io.modelcontextprotocol/tasks扩展之上SEP-2663Final2026-05-15 上游合并。SEP-2663 取代 SEP-1686 但保留其轮询核心广告 tasks 能力的客户端发出增强的tools/call服务器决定是否作为任务运行返回携带服务器生成任务 id 的CreateTaskResult客户端轮询tasks/get直至终态结果内联在该响应中。FastMCP 现有 SEP-1686 线路层被移除而底下的 Docket/Redis 执行引擎原封不动移入fastmcp-tasks——规范朝着 FastMCP 已构建的方向移动因此重建主要是删除加薄线路适配器。taskTrue保持作者表面由fastmcp[tasks]extra 与显式mcp.add_extension(TasksExtension(...))门控是上述扩展 API 的第一个消费者因此已使用 tasks 的服务器无需改代码。v1 范围为仅轮询、仅tools/call。完整设计线路差异、引擎/线路拆分、打包、客户端体验、排序、风险、五个已解决决策见专门的 background-tasks.md 页面。核心要点add_extension是必须的taskTrue不会被自动检测。扩展需要配置后端 URL、worker 并发、TTL 默认值add_extension(TasksExtension(...))是其自然归宿同时保持能力广告诚实——服务器广告tasks能力当且仅当扩展已注册并消除最危险的坑生产环境因没人配置 Redis 而在内存后端上静默运行工具。客户端体验友好接口call_tool透明驱动轮询循环并返回完成结果服务器是否任务化不可见低层call_tool_mcp交回原始CreateTaskResult友好接口上的快速返回标志产出Task句柄.status()、.wait()、.cancel()、可 await而不阻塞。仓库中fastmcp-tasks/fastmcp_tasks/目录含worker_cli.py、input_store.py、wire_production.py等模块即该可选包的落地位置。SDK 委托第二轮SDK delegation, round two——Planned以上游为门控真正的 HTTP 简化是 v4 项目而非单个 PR。FastMCP 可以在上游补充三件事后将create_streamable_http_app折叠到 SDK 的Server.streamable_http_app()上按会话的事件存储作用域per-session event-store scoping用户中间件注入钩子user-middleware injection hook生命周期钩子lifespan hook。回报不仅是更少的代码——FastMCP 还将继承 SDK 的会话所有者凭据强制session-owner credential enforcement这是它今天缺少的安全增益。这是要提交的三项上游特性请求连同 known-gaps.md 描述的咨询卷宗。在它们落地之前change-register.md 中记录的四个 HTTP 覆盖事件存储会话作用域、生命周期调和、优雅传输终止、用户 ASGI 中间件钩子继续保留。一个值得在 FastMCP 侧浮出的潜在能力session_idle_timeout被管理器接受但从未被create_streamable_http_app设置——如果 FastMCP 想暴露它这是一行接线。全貌总结v4 特性状态一览特性状态关键 PR / 依据采样移除Shipped4.0#4448server/context.py、server/server.pyMRTR 启发式交互guard 形式Shipped4.0guard 形式已发布Resolve声明式层 Designedserver/mixins/mcp_operations.py中间件根分发Shipped#4553server/low_level.py一等公民 2026 客户端部分 Shipped完整组合被上游阻塞#4572、#4574client/client.py缓存提示Shipped#4464server/server.pyOpenTelemetryShipped#4481settings.py、telemetry.py客户端扩展SEP-2133客户端侧 Shipped服务端侧 Designed#4572#4602订阅Not startedsubscriptions/listen 订阅总线FastMCP 原生扩展 APIShipped#4602mcp.add_extension(...)后台任务SEP-2663Shipped#4603fastmcp-tasks包、taskTruemcp.add_extension(TasksExtension(...))SDK 委托第二轮Planned以上游为门控三项上游特性请求四个 HTTP 覆盖保留阅读本文后你可以将每项特性与其仓库落地位置一一对应需要验证服务端 API 移除时查 server/context.py 与_REMOVED_KWARGS需要编写现代启发式交互工具时参考 guard 形式的InputRequiredResult与ctx.input_responses/ctx.request_state需要启用后台任务时按 background-tasks.md 配置mcp.add_extension(TasksExtension(...))与taskTrue。所有状态与依据均可在此仓库的 v4 笔记体系index.md、change-register.md、known-gaps.md、protocol-2026.md、background-tasks.md中交叉核验。【免费下载链接】fastmcp The fast, Pythonic way to build MCP servers and clients.项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表