MCP Python SDK 进度通知实战:从工具端 `report_progress` 到客户端 `progress_callback` 完整指南
人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载本文以官方 Python SDK 的进度progress通知机制为核心讲解如何让长时间运行的 MCP 工具主动上报进度以及客户端如何在每次工具调用中按需订阅这些进度更新。读完本文你将掌握服务端Context.report_progress与客户端call_tool(progress_callback...)的完整用法、两者的底层调用链与时序约束并学会在总量未知时如何优雅地处理进度展示。为什么需要进度通知一个需要 30 秒才能完成的工具如果在整整 30 秒内不发一言看起来就像是卡死了。进度通知progress notifications正是为解决这一问题而设计的工具端主动报告现在进行到哪一步客户端根据收到的信息自行决定如何绘制——可以是进度条、转圈动画spinner也可以只是一行日志。进度是工具还在运行时这一事实的对外表达它独立于工具调用的最终结果因此在 MCP 协议中是一条独立的notifications/progress通知而不是被塞进tools/call的响应里。服务端从工具中上报进度接收Context参数并调用report_progress在 SDK 中任何需要上报进度的工具函数只需额外声明一个ctx: Context参数然后在函数体内调用await ctx.report_progress(...)即可。完整示例见 docs_src/progress/tutorial001.pyfrom mcp.server import MCPServer from mcp.server.mcpserver import Context mcp MCPServer(Bookshop) mcp.tool() async def import_catalog(urls: list[str], ctx: Context) - str: Import book records from a list of catalog URLs. for done, url in enumerate(urls, start1): await ctx.report_progress(done, totallen(urls), messagefImported {url}) return fImported {len(urls)} records.report_progress接受三个参数每个参数的含义完全由你自行定义参数含义约束progress已经完成了多少必须递增。MCP 规范要求每次上报时该值只能增加不能重复同一个值也不能回退total总量是多少如果你知道可选默认Nonemessage描述当前这一步的一行人类可读文本可选默认Nonectx之所以能被注入纯粹是因为它的类型提示type hintSDK 会在调用时自动传入而模型LLM完全看不到这个参数。证据是import_catalog的输入 schema 中只有urls这一个属性——这一点在 tests/docs_src/test_progress.py 的test_context_parameter_is_invisible_to_the_model用例中被直接断言验证。关于Context对象的完整能力参见 Context 文档进度上报只是它提供的功能之一。底层调用链与无人监听即空操作原理从源码结构看ctx.report_progress的调用链是Context.report_progresssrc/mcp/server/mcpserver/context.py→session.report_progresssrc/mcp/server/session.py→ 请求对应的 outbound 通道。值得注意的是 src/mcp/server/session.py 中的 docstring 明确指出当调用方没有请求进度时report_progress是一个空操作no-op且该行为与分发器dispatcher无关——在 JSON-RPC 传输上它通过持有的DispatchContext以调用方的 token 发出notifications/progress在进程内直连分发器上它直接调用调用方的回调。这意味着服务端工具函数可以无条件地上报进度完全不必关心是否有人在听。是否有监听者、监听者是谁都由客户端那一侧决定。客户端按调用接收进度每次调用传入progress_callback客户端以每次调用为单位选择是否接收进度方式是在call_tool上传递progress_callback参数。完整示例见 docs_src/progress/tutorial001_client.py对应文档中的 client.py 代码import anyio from mcp import Client async def show(progress: float, total: float | None, message: str | None) - None: print(f{message} ({progress}/{total})) async def main() - None: async with Client(http://localhost:8000/mcp) as client: result await client.call_tool( import_catalog, {urls: [https://example.com/a.json, https://example.com/b.json]}, progress_callbackshow, ) print(result.structured_content) anyio.run(main)回调是一个async函数接收的参数正是服务端上报的原样值progress、total、message。其签名在 SDK 中以协议类ProgressFnT定义src/mcp/shared/dispatcher.pyclass ProgressFnT(Protocol): Callback invoked when a progress notification arrives for a pending request. async def __call__(self, progress: float, total: float | None, message: str | None) - None: ...从客户端源码看progress_callback的传递链为Client.call_toolsrc/mcp/client/client.py→session.call_tool→send_request把回调写入opts[on_progress]src/mcp/client/session.py→ 分发器根据该选项订阅进度通知。时序约束通知与响应各自独立送达有一个关键的时序事实需要牢记每条进度通知都是单独送达的与最终的响应并不同步。因此慢回调在call_tool已经返回之后仍可能还在运行只有进程内测试连接in-process test connection才会内联inline运行回调从而保证所有上报先于结果到达。这一行为在源码中有清晰体现。在 JSON-RPC 分发器中notifications/progress被单独拦截并通过self._spawn(...)为每条通知启动独立任务来调用回调src/mcp/shared/jsonrpc_dispatcher.py而在进程内直连分发器中回调是直接await内联执行的src/mcp/shared/direct_dispatcher.py。仓库中的测试 test_over_a_wire_dispatcher_callbacks_race_the_result 专门验证了这一行为在 wire 分发器legacy 模式上回调被事件门控call_tool返回时finished列表仍为空直到事件被释放后回调才陆续完成——这正是文档警告不要排除慢回调晚于结果到达的原因。直接上手试一试将server.py以 HTTP 方式启动然后在第二个终端运行客户端uv run mcp run server.py --transport streamable-httppython client.py预期输出如下Imported https://example.com/a.json (1.0/2.0) Imported https://example.com/b.json (2.0/2.0) {result: Imported 2 records.}服务端每次await ctx.report_progress(...)对应客户端一次show调用且顺序完全一致。进度并不捆绑在结果里而是在工具仍在工作时以流式方式不断送达。progress_callback属于调用而非Client必须特别强调progress_callback属于某次调用Client构造函数中不存在对应参数。因为不同调用往往想要不同的回调——某次调用可能驱动一个下载进度条下一次调用可能只想在日志里留一行。仓库测试 test_progress_callback_is_per_call_not_per_client 用inspect.signature同时断言了两件事progress_callback存在于Client.call_tool的参数列表中而不存在于Client.__init__的参数列表中。没有回调时report_progress是空操作现在把progress_callbackshow删掉再运行一次{result: Imported 2 records.}没有报错、没有警告结果完全相同。这是因为服务端在调用方未请求进度时会把report_progress当作空操作处理。因此正确的姿势是无条件上报不用操心有没有人在听。对应测试为 test_without_a_callback_report_progress_is_a_no_op。不知道总量时省略totaltotal是你知道分母时才使用的值。但在很多场景下你根本不知道总量清空一个 feed、沿着游标翻页、下载一个没有长度头的资源——这时就把total省略掉。完整示例见 docs_src/progress/tutorial002.pyfrom collections.abc import AsyncIterator from mcp.server import MCPServer from mcp.server.mcpserver import Context mcp MCPServer(Bookshop) async def fetch_records(feed_url: str) - AsyncIterator[str]: for title in (Dune, Neuromancer, Hyperion): yield f{feed_url}#{title} mcp.tool() async def import_feed(feed_url: str, ctx: Context) - str: Import every record a catalog feed yields. imported 0 async for record in fetch_records(feed_url): imported 1 await ctx.report_progress(imported, messagefImported {record}) return fImported {imported} records.此时客户端回调收到的total是None。客户端仍然可以展示活动状态例如目前已经导入了 3 条……但无法展示百分比。仓库测试 test_omitting_total_reaches_the_callback_as_none 验证了(1, None, ...)、(2, None, ...)、(3, None, ...)这样的回调序列。两个实用建议progress不一定要数某个特定的东西。字节、行数、页数都行——选择用户能一眼认出的单位只承诺你能兑现的total。不要为了画一个更好看的进度条而编造总量。小结任何接收Context的工具都可以调用await ctx.report_progress(progress, totalNone, messageNone)客户端在call_tool上传递progress_callback参数——按调用指定永远不放在Client上回调形如async (progress, total, message) - None在工具仍在运行时触发调用上没有回调时report_progress什么都不做所以请无条件上报不知道total时就省略它回调会收到None。进度与日志是两个不同的通道最后要区分两个容易混淆的概念进度是正在运行的工具展示给用户看的东西而工具为**运营方你**留下的日志行属于另一条独立的通道相关内容请参阅 日志Logging文档。两者虽然都源自一次工具调用但面向的对象、传递的通道和消费方式完全不同在设计服务端行为时应当分开考虑。赞分享人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载相关推荐MCP Python SDK 进度通知实战从工具端 report_progress 到客户端 progress_callbackMCP Python SDK 进度通知实战从工具端 report_progress 到客户端 progress_callback 导读 本文围绕 Model人工智能MCP 服务MCP ClientsMCP Python SDK 进度通知完整指南从服务端 report_progress 到客户端 progress_callbackMCP Python SDK 进度通知完整指南从服务端 report_progress 到客户端 progress_callback 本文基于当前仓库 doc人工智能MCP 服务MCP ClientsPython MCP SDK 进度通知Progress Notifications实战指南从 report_progress 到 progress_callback 的完整链路Python MCP SDK 进度通知Progress Notifications实战指南从 report_progress 到 progress_cal人工智能MCP 服务MCP Clients上一篇Ant Design Vue Watermark 水印组件完全指南API 配置、源码原理与防篡改机制下一篇F´ Hub 模式Hub Pattern深度解析用 GenericHub 实现跨部署、跨边界组件通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

V8 源码检出与开发工作流完全指南:从 fetch 到提交、审查与落地

V8 源码检出与开发工作流完全指南:从 fetch 到提交、审查与落地

V8 源码检出与开发工作流完全指南:从 fetch 到提交、审查与落地 【免费下载链接】v8 The official mirror of the V8 Git repository 项目地址: https://gitcode.com/gh_mirrors/v81/v8 本篇指南以 V8 官方文档 docs/source-code.md 为主体,系统讲…

2026/9/21 15:33:38 阅读更多 →
Agent Substrate egress代理与SD Mint:Actor如何零信任安全访问互联网完整指南

Agent Substrate egress代理与SD Mint:Actor如何零信任安全访问互联网完整指南

Agent Substrate egress代理与SD Mint:Actor如何零信任安全访问互联网完整指南 【免费下载链接】substrate Agent Substrate: the core system 项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate 在 Agent Substrate 这个面向 AI Agent 的…

2026/9/21 15:33:38 阅读更多 →
AltTab 代码注释重构实战:用 rework-comments 技能审计并精简“AI 可执行“的注释

AltTab 代码注释重构实战:用 rework-comments 技能审计并精简“AI 可执行“的注释

AltTab 代码注释重构实战:用 rework-comments 技能审计并精简"AI 可执行"的注释 【免费下载链接】alt-tab-macos Windows alt-tab on macOS 项目地址: https://gitcode.com/gh_mirrors/al/alt-tab-macos 导读 注释是代码里唯一会"骗人"…

2026/9/21 15:33:38 阅读更多 →

最新新闻

SAP ERP业务咨询问卷:系统配置的第一道关键决策点

SAP ERP业务咨询问卷:系统配置的第一道关键决策点

简介:这是一份面向SAP ERP项目实施前期的调研问卷,适用于咨询顾问、项目经理及企业内部关键用户开展业务现状梳理与需求收集。问卷按业务模块组织,涵盖企业基本状况、库存管理、BOM与工艺路线、生产计划、采购、车间生产、产品成本、产品配置…

2026/9/21 16:09:13 阅读更多 →
深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置

深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置

深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置 【免费下载链接】meshery Meshery, the cloud native manager 项目地址: https://gitcode.com/GitHub_Trending/me/meshery Meshery 使用 Relationships(关系&#xf…

2026/9/21 16:09:13 阅读更多 →
哈希表原理与实战:从哈希函数设计到冲突处理与缓存应用

哈希表原理与实战:从哈希函数设计到冲突处理与缓存应用

1. 数组做不到的事:哈希表到底在优化哪一环1.1 一次查询背后的复杂度账做后端开发的人,应该都有过这种经历:订单量从十万涨到百万,某天线上突然出现接口变慢的告警。排查到最后,发现不是数据库的问题,而是内…

2026/9/21 16:09:13 阅读更多 →
PouchDB 本地文档(Local Documents)完全指南:原理、实践与源码解析

PouchDB 本地文档(Local Documents)完全指南:原理、实践与源码解析

PouchDB 本地文档(Local Documents)完全指南:原理、实践与源码解析 【免费下载链接】pouchdb :kangaroo: - PouchDB is a pocket-sized database. 项目地址: https://gitcode.com/gh_mirrors/po/pouchdb 本地文档(Local do…

2026/9/21 16:09:13 阅读更多 →
飞书 CLI `drive +react-reply` 实战:为文档评论回复添加与删除表情回应(Reaction)

飞书 CLI `drive +react-reply` 实战:为文档评论回复添加与删除表情回应(Reaction)

CLIAI 技能 【免费下载链接】cli The official Lark/飞书 CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Calendar, Mail, Tasks, Meetings, and more, with 200 co…

2026/9/21 16:09:13 阅读更多 →
PowerPMAC上位机开发实战:用C#构建Winform运动控制界面

PowerPMAC上位机开发实战:用C#构建Winform运动控制界面

去年接手一个三轴检测设备的上位机项目,厂家只留了一台装着 PowerPMAC 调试软件的工控机。操作员每天开工要盯着命令行窗口,敲一堆类似#1j/#2j/的指令做回零和点动,稍微按错一个符号,轴就停在半路。于是"做一个能给人用的 Wi…

2026/9/21 16:08:12 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →