MCP Python SDK 的 Context 机制:请求注入、自有资源读取与动态列表通知

发布时间:2026/9/20 5:10:01

MCP Python SDK 的 Context 机制:请求注入、自有资源读取与动态列表通知 MCP Python SDK 的 Context 机制请求注入、自有资源读取与动态列表通知【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk在 Model Context ProtocolMCP的 Python SDK 中工具Tool的参数来自模型而其余的一切——你正在处理的请求、你所在的服务器、一条通回客户端的通道——都来自同一个对象Context。本文基于官方文档 i18n/de/pages/handlers/context.md英文原版见 docs/handlers/context.md深入讲解Context的注入机制、它对模型不可见的原理、它提供的全部能力读资源、报进度、elicitation、回写会话并结合仓库源码验证其底层实现。读完你将能够在自己的 MCP 服务器中通过类型注解声明式地使用Context让工具读取服务器自有资源并在运行时动态注册工具后主动通知客户端刷新列表。Context你不构造它你请求它Context的设计哲学是声明式注入你既不构造它也不配置它只需在函数签名里开口要即可。SDK 会为每一个请求构建一个全新的Context并传入。熟悉 FastAPI 的开发者会立刻认出这种模式声明一个以框架自身类型FastAPI 中是Request这里是Context注解的参数框架负责注入。无需注册、无需配置——类型注解本身就是全部机制。从源码看SDK 中Context是一个 PydanticBaseModel见 src/mcp/server/mcpserver/context.py#L32它内部持有ServerRequestContext每请求的原始记录定义于 src/mcp/server/context.py#L30-L49与MCPServer实例的引用从而把会话、请求元数据、lifespan 上下文等能力统一暴露给处理函数。请求 Context注解即机制向任意工具添加一个以Context注解的参数即可。以下示例取自 docs_src/context/tutorial001.pyfrom mcp.server import MCPServer from mcp.server.mcpserver import Context mcp MCPServer(Bookshop) mcp.tool() def search_books(query: str, ctx: Context) - str: Search the catalog by title or author. return f[request {ctx.request_id}] Found 3 books matching {query!r}.关键点如下SDK 为每个请求构建全新的Context并注入请求之间互不共享。参数名无关紧要ctx、context、c都可以SDK 通过注解annotation而非参数名来识别它。源码中的文档注释也明确说明The context parameter name can be anything as long as its annotated with Contextsrc/mcp/server/mcpserver/context.py#L61-L62。资源Resource和提示Prompt处理器同样可以声明Context方式完全一致。ctx.request_id是你当前函数正在处理的请求的 ID。源码中它被转换为字符串返回src/mcp/server/mcpserver/context.py#L291-L294。对模型不可见这是最需要内化的部分。下面是tools/list为search_books报告的输入模式input schema{ type: object, properties: { query: {title: Query, type: string} }, required: [query], title: search_booksArguments }只有一个属性。ctx不是参数它永远不会出现在模式中模型永远不会被告知它的存在也没有任何客户端能够填写它。它是你与 SDK 之间的契约在线上wire不可见。从实现上可以印证这一点Context通过类型注解被识别并在调用前被剥离injected不会进入函数参数的模式推导过程工具参数的 JSON Schema 只由真正的业务参数生成。动手试一下使用 MCP Inspector 启动服务器uv run mcp dev server.pysearch_books的表单只有一个query字段。用dune调用它[request 3] Found 3 books matching dune.这个数字恰好是这次请求的编号。再次调用工具数字会变化每个请求都有自己的Context。Context 提供什么注入的对象很小巧。除了request_id它还包括await ctx.read_resource(uri)在工具内部读取服务器自己的资源见下文专节。await ctx.report_progress(progress, total, message)在长时间调用期间向调用方流式回报进度。完整故事见 Fortschritt进度英文版 docs/handlers/progress.md。源码中它转发到会话的report_progresssrc/mcp/server/mcpserver/context.py#L113-L121。await ctx.elicit(message, schema)与await ctx.elicit_url(...)暂停工具向 Host 端的人提出一个问题。这是 Elicitationelicitation英文版 docs/handlers/elicitation.md的主题。源码中elicit通过elicit_with_validation实现elicit_url则引导用户跳转到外部 URL 完成带外交互如敏感凭据收集、OAuth 授权、支付流程并在完成后通过ctx.session.send_elicit_complete(elicitation_id)通知客户端src/mcp/server/mcpserver/context.py#L189-L255。ctx.session与当前客户端的会话的服务端一侧。你发送给客户端的通知都在这里最后一节会用到它。ctx.headers传输层携带的请求头stdio 下为None。读取自定义头用(ctx.headers or {}).get(x-...)。头部是客户端提供的输入——适合用于 locale 或 feature flag永远不能当作身份identity。源码中的headers属性正是从传输层请求对象上取出的src/mcp/server/mcpserver/context.py#L281-L289。ctx.request_context原始的每请求数据记录。你最常取用的字段是lifespan_context即你的启动代码startup code通过 yield 交付的对象见 Lifespan生命周期英文版 docs/handlers/lifespan.md。该字段定义于ServerRequestContext.lifespan_contextsrc/mcp/server/context.py#L41。日志logging刻意不在此清单中。服务器的日志应使用 Python 的logging模块就像任何其他 Python 程序一样。原因见 Logging日志英文版 docs/handlers/logging.md的简短说明。值得注意的是Context上的log/info/debug等方法已随 2026-07-28 协议版本废弃见源码中的deprecated标记src/mcp/server/mcpserver/context.py#L257。提示注入只发生在你注册的那个函数上。你的工具调用的辅助函数并不会获得自己的Context请把ctx作为普通参数向下传递。不存在可以从别处取用的当前上下文ambient current context。读取自有资源工具与客户端共享同一事实来源服务器的资源不只是给客户端用的工具同样可以读取from mcp.server import MCPServer from mcp.server.mcpserver import Context mcp MCPServer(Bookshop) mcp.resource(catalog://genres) def genres() - str: The genres the catalog is organised into. return fiction, non-fiction, poetry mcp.tool() async def describe_catalog(ctx: Context) - str: Describe how the catalog is organised. [contents] await ctx.read_resource(catalog://genres) return fThe catalog is organised into: {contents.content}完整代码见 docs_src/context/tutorial002.py。ctx.read_resource通过**服务resources/read的同一个注册表registry**来解析 URI因此工具得到的就是客户端会得到的东西一个ReadResourceContents的可迭代对象每个内容块一个。对于这个 URI 只有一个contents.content # fiction, non-fiction, poetry contents.mime_type # text/plaincontent正是genres()返回的内容。单一事实来源客户端浏览资源你的工具消费资源没有人需要复制这个字符串。describe_catalog的唯一参数就是Context因此它的输入模式完全没有属性。模型以{}调用它。从源码看ctx.read_resource实际上调用MCPServer.read_resource(uri, ...)并做了一层额外的保护如果资源返回了InputRequiredResult2026-07-28 多轮往返流程这里会抛出RuntimeError提示应改用MCPServer.read_resource(uri, context)来接收并转发——因为ctx.read_resource只是内容读取器src/mcp/server/mcpserver/context.py#L151-L187。告知客户端列表已变更运行时动态注册服务器能提供什么并不在导入import时就固定。可以在运行时注册工具然后告知客户端from mcp.server import MCPServer from mcp.server.mcpserver import Context mcp MCPServer(Bookshop) def recommend_book(genre: str) - str: Recommend a book in the given genre. return fIn {genre}, try Dune. mcp.tool() async def enable_recommendations(ctx: Context) - str: Switch on the recommendation tool. mcp.add_tool(recommend_book) await ctx.session.send_tool_list_changed() return Recommendations are now available.完整代码见 docs_src/context/tutorial003.py。mcp.add_tool(recommend_book)把一个普通函数注册为工具名称、描述和模式与mcp.tool()推导的方式完全一致。从源码看MCPServer.add_tool委托给工具管理器见 src/mcp/server/mcpserver/server.py#L609 与 src/mcp/server/mcpserver/tools/tool_manager.py#L39。await ctx.session.send_tool_list_changed()发送notifications/tools/list_changed。收到它的客户端会再次调用tools/list从而看到recommend_book。同族的兄弟方法还有send_resource_list_changed()、send_prompt_list_changed()以及针对单个资源变更的send_resource_updated(uri)。2026-07-28 连接订阅流与 notify_* 方法在 2026-07-28 协议的连接上客户端只在自己打开的subscriptions/listen流上接收变更通知因此上面的send_*方法无法到达这些流。此时应使用Context的 publish 方法它们会同时向所有已订阅的流投递await ctx.notify_tools_changed()await ctx.notify_prompts_changed()await ctx.notify_resources_changed()await ctx.notify_resource_updated(uri)从源码看这些方法通过SubscriptionBus订阅总线发布对应的事件对象ToolsListChanged、PromptsListChanged、ResourcesListChanged、ResourceUpdated其中notify_resource_updated以精确字符串匹配每个流的过滤器src/mcp/server/mcpserver/context.py#L129-L149。完整故事——包括跨副本水平扩展——见 Abonnements订阅英文版 docs/handlers/subscriptions.md。验证在任何人运行enable_recommendations之前你所承诺的那个工具并不存在。强行调用它会得到模型可读的错误Unknown tool: recommend_book运行enable_recommendations之后完全相同的调用就成功了。工具列表是真正动态的tools/list反映的是当下已注册的内容。总结在参数上以Context注解用于工具、资源或提示SDK 就会注入它。参数名由你决定。它对模型不可见输入模式永远只包含你真正的业务参数。ctx.request_id标识当前请求ctx.request_context.lifespan_context是你的启动代码 yield 出来的对象。await ctx.read_resource(uri)让工具读取服务器自己的资源与客户端共享同一事实来源。ctx.session是回到客户端的通道send_tool_list_changed()及其同族方法会提示客户端重新拉取你变更过的列表在 2026-07-28 连接上则改用ctx.notify_*系列方法经由订阅流投递。进度回报report_progress与 elicitationelicit/elicit_url同样从Context开始各自有独立章节。模型永远看不到、只由你自己的函数填充的参数是 Abhängigkeiten依赖英文版 docs/handlers/dependencies.md的主题。【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/20 10:30:24

OpenClaw开源框架构建企业级智能客服系统实战

1. 项目背景与核心价值在数字化转型浪潮中,智能客服系统已成为企业提升服务效率、降低运营成本的关键基础设施。OpenClaw作为一款开源的对话系统框架,其模块化设计和可扩展性使其成为构建企业级智能客服的理想选择。本系列前九篇已系统讲解了OpenClaw的基…

2026/9/20 10:30:24

Hugo 模板时间方法 Before:判断时间先后顺序的权威指南

Hugo 模板时间方法 Before:判断时间先后顺序的权威指南 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址: https://gitcode.com/gh_mirrors/hu/hugo Hugo 的 time.Time 值自带一系列时间比较方法,其中 Bef…

2026/9/20 10:30:24

OpenResearch实战指南:用软件工程方法管理科研项目

1. 当“OpenResearch”成为一个热词,它到底在说什么最近“OpenResearch”这个词在技术圈和科研圈被反复提及,很多人第一次看到它,会下意识地把它理解成“开放研究”或者“开源科研”的缩写。这个理解方向没错,但远远不够。我最初接…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/20 5:01:23

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/20 5:09:33

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码