python-sdk 服务端开发指南:MCPServer 三大原语、可选能力与错误处理全解析
python-sdk 服务端开发指南MCPServer 三大原语、可选能力与错误处理全解析【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdkMCPModel Context Protocol服务端向已连接的客户端暴露三类核心原语它们的区别在于由谁决定使用Tool 由模型Model选择并调用Resource 由应用Application决定读取Prompt 由人Person通过菜单或斜杠命令主动触发。本文基于官方 Python SDKpython-sdk整理服务端侧文档 docs/servers/index.md完整梳理三个原语及其周边的可选能力补全、媒体返回、图标、错误处理并给出可运行的示例与源码级佐证帮助读者快速建立服务端开发的全局视图。三大原语谁决定、谁使用一个MCPServer向连接的客户端暴露三个原语primitive它们由不同的角色触发职责互不重叠原语使用决策者本质参考文档Tool模型Model模型挑选并调用的动作docs/servers/tools.mdResource应用Application应用决定读取的只读数据docs/servers/resources.mdPrompt人Person人从菜单或斜杠命令按名字触发docs/servers/prompts.mdTool模型的“手”一个Tool就是模型可以调用的一个函数。用mcp.tool()装饰一个普通 Python 函数即可完成声明——不需要手写 schema、JSON 或协议。SDK 从函数签名中读取三样东西名字取函数名描述取 docstring参数取类型注解。例如search_books工具完整示例见 docs_src/tools/tutorial001.pymcp.tool() def search_books(query: str, limit: int) - str: Search the catalog by title or author. return fFound 3 books matching {query} (showing up to {limit}).SDK 依据类型注解生成 JSON Schema并在tools/list时发给客户端{ type: object, properties: { query: {title: Query, type: string}, limit: {title: Limit, type: integer} }, required: [query, limit], title: search_booksArguments }类型注解在这里就是契约而非文档如果客户端传limit: tenSDK 会在你的函数执行前就拒绝它。通过uv run mcp dev server.py启动 MCP InspectorTools 标签页会依据类型注解自动渲染出表单。Resource应用的“资料库”Resource是暴露给应用读取的只读数据配置文件、记录、文档由mcp.resource(uri)声明。与 Tool 最大的区别是Resource 用 URI 寻址而不是用名字。客户端请求config://app而不是请求get_config。mcp.resource(config://app) def get_config() - str: The active shop configuration. return themedark\nlanguageenresources/list返回的是名称、URI、描述与 MIME 类型不会调用你的函数只有resources/read读取某个具体 URI 时函数才会执行。因此暴露上千个资源也只为真正被打开的那几个付费。URI 中的{占位符}使资源变成模板它从resources/list移到resources/templates/list以模式而非地址的形式列出。客户端填入占位符后读取具体 URI如users://42/profile一个函数服务所有匹配的 URI匹配到的值作为同名参数传入。占位符与函数参数名必须一致否则装饰器会在导入期直接抛出ValueErrorValueError: Mismatch between URI parameters {user_id} and function parameters {user}返回类型不限于strstr原样作为文本bytes变成 base64 的BlobResourceContents其余 JSON 可序列化对象dict、Pydantic 模型、dataclass自动序列化为 JSON 文本。mime_type默认为text/plain需要手动标注。详见 docs/servers/resources.md。Prompt人的“快捷指令”Prompt是用户从客户端菜单中挑选的消息模板用户选择斜杠命令或按钮、填入参数渲染出的消息像用户自己输入一样进入对话。用mcp.prompt()声明返回的str变成一条 user 消息mcp.prompt() def review_code(code: str) - str: Review a piece of code. return fPlease review this code:\n\n{code}prompts/list返回的是扁平化的命名字符串参数列表arguments: [{name: code, required: true}]没有 JSON Schema——因为这是人填写的表单不是模型构造的载荷。参数缺少默认值时必填缺少必填参数会直接导致请求以 JSON-RPC 错误-32602/-32603失败因为流程中根本没有模型在回路里。返回str是单条消息返回UserMessage/AssistantMessage的列表则可以预置多轮对话甚至用一条预填的 assistant 消息来引导模型的下一句回复。详见 docs/servers/prompts.md。围绕三大原语的可选能力三个原语之外服务端还可以声明以下能力均对应独立文档补全 Completions服务端为 prompt 参数与 resource 模板参数提供自动补全建议。媒体 Media工具除文本外还能返回图片、音频以及客户端 UI 中展示的图标。错误处理 Handling errors区分模型可恢复的错误与模型绝不能看到的错误。Completions提示参数自动补全补全只作用于两类对象prompt 的参数与resource 模板的参数。每台服务器只需注册一个mcp.completion()处理器所有补全请求都会进入这里按引用类型分支处理mcp.completion() async def complete( ref: PromptReference | ResourceTemplateReference, argument: CompletionArgument, context: CompletionContext, ) - Completion | None: ...ref是PromptReference或ResourceTemplateReference用isinstance区分argument.name是待补全的参数名argument.value是用户已输入的前缀context.arguments是已经解析出的参数值dict[str, str] | None用于实现依赖参数先选owner再补全repo返回Completion(values[...])或返回None表示无建议SDK 会转为空列表绝不报错。SDK 不会替你过滤argument.value只是前缀startswith需要自己写。值得注意的细节是注册处理器即声明能力。你从未列出completions但 SDK 检测到处理器后自动声明了CompletionsCapability而没有处理器时补全请求会得到 JSON-RPC 的Method not found。这与三大原语不同——MCPServer始终声明三个原语无论是否注册了对应处理器。Media图片、音频与图标SDK 为二进制结果提供了Image与Audio两个辅助类以及用于在客户端 UI 中展示服务端/工具/资源/prompt 形象的Icon类型。三者均在 docs/servers/media.md 中说明。mcp.tool() def logo() - Image: Return the project logo. return Image(pathlogo.png)Image只接受path读取文件或data原始字节二选一MIME 类型按后缀推断.png→image/png未知后缀回退到application/octet-stream。在线上它变成ImageContent块字节 base64 编码 MIME 类型。Audio形态完全相同支持.wav、.mp3、.ogg、.flac等。媒体结果没有structured_content也没有输出 schema——它是给模型看的不是给应用解析的数据。工具还可以返回EmbeddedResource文本或 base64 blob 连同 URI 与 MIME 类型让客户端以附件形式展示ResourceLink则只发送一个可稍后resources/read的指针。Icon是元数据而非内容它不携带图片只用一个srcURI 指向图片https:或data:URI可选mime_type、sizes如48x48、any与themelight/dark。同一个icons[...]关键字被MCPServer(...)、mcp.tool()、mcp.resource()和mcp.prompt()共同接受。Handling errors三种失败三种路径工具可能以三种方式失败SDK 对它们区别对待源码见 src/mcp/server/mcpserver/exceptions.py抛ToolError来自mcp.server.mcpserver.exceptions→ 请求成功返回但is_errorTrue你的消息出现在content中模型能读到并自行修正重试。这是绝大多数情况下的正确选择。抛MCPErrorfrom mcp import MCPError→ 整个tools/call请求以 JSON-RPC 错误失败code、message、data原样透传给主机应用模型什么都看不到。错误码常量INVALID_PARAMS即-32602等由mcp.types导出。抛其他任何异常→ 视为崩溃模型只得到is_errorTrue且仅有Error executing tool name异常文本可能泄露内部实现绝不离开服务器完整 traceback 以ERROR级别写入服务端日志。判断标准只有一句话更聪明的模型能否避免这个错误能 →ToolError不能 →MCPError。Resource 侧同理ResourceNotFoundError转为协议规定的-32602并把 URI 放进dataResourceError对应非“未找到”的失败-32603其余异常除MCPError外都是崩溃。坏参数则根本到不了你的函数——SDK 会先按输入 schema 拒绝同样返回模型可读的is_errorTrue工具错误。深入源码MCPServer 的注册 API上述装饰器最终都汇聚到MCPServer类定义于 src/mcp/server/mcpserver/server.py的注册方法。以add_tool为例src/mcp/server/mcpserver/server.pydef add_tool( self, fn: Callable[..., Any], name: str | None None, title: str | None None, description: str | None None, annotations: ToolAnnotations | None None, icons: list[Icon] | None None, meta: dict[str, Any] | None None, structured_output: bool | None None, ) - None: ... self._tool_manager.add_tool(fn, namename, ...)参数说明name/title/description覆盖从函数名、docstring 推断出的默认值title是 UI 展示用的人类可读名称annotations行为提示非安全机制如read_only_hintTrue、open_world_hintFalse帮助客户端决定是否询问用户icons工具在客户端 UI 中的图标列表structured_outputNone时按返回类型注解自动探测是否结构化输出True/False可强制开关。remove_tool(name)提供反向操作。tool()装饰器src/mcp/server/mcpserver/server.py本质上就是add_tool的语法糖——若误用为tool未加括号会直接抛出TypeError提示“Did you forget to call it? Use tool() instead of tool”。文档地图按需直达服务端各主题页面相互独立可跳转至所需页面。若尚未构建过服务器建议先从Erste Schritte快速上手开始i18n 德语版对应 i18n/de/pages/servers/index.md建议阅读英文原版 docs/servers/index.md 保证内容最新。完整页面清单如下页面核心内容tools.mdTool 声明、输入 schema、可选参数、Field约束、模型参数、async、注解structured-output.mdTool 返回值形状content与structured_content的配套参考resources.mdResource 声明、URI 模板、返回类型与mime_typeuri-templates.mdRFC 6570 完整寻址语法与路径安全规则prompts.mdPrompt 声明、多消息、标题与参数描述、运行时增删completions.mdprompt 参数与 resource 模板参数的自动补全media.md工具返回图片/音频、EmbeddedResource、Iconhandling-errors.mdToolError/MCPError/ 崩溃三类错误的抉择注册的函数内部发生的事情——Context、依赖注入、在调用中途向用户追问输入——属于下一节Im Handler在处理器内部的主题。建议读者按“原语 → 可选能力 → 处理器内部”的顺序阅读即可完整掌握 python-sdk 服务端开发的全貌。【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考