- 教程
- 文档
- 人工智能
【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
本篇技术指南围绕 mcp-for-beginners 课程中“Advanced server usage(高级 Server 用法)”一节的 Python 示例工程展开,完整讲解从虚拟环境搭建、依赖安装、代码运行到预期输出的全过程,并结合仓库内server.py、client.py与tools/目录的源码实现,剖析低层 Server 的list_tools/call_tool双处理器架构与 Pydantic 输入校验原理。读完本文,你将掌握如何在本地跑通一个基于 stdio 传输的 MCP Python 示例,并理解其可扩展架构的核心设计思想。
一、示例工程概览:文档对应哪个代码仓库
本节对应的原文档位于仓库根目录下的 translations/bg/03-GettingStarted/10-advanced/code/python/README.md(保加利亚语翻译版,英文原文见 03-GettingStarted/10-advanced/code/python/README.md),其内容是整个 10-advanced 章节 Python 示例的运行说明书。
该示例工程的完整源码位于 03-GettingStarted/10-advanced/code/python/,采用章节 README 中推荐的“低层 Server + 独立工具目录”架构,目录结构如下:
python/ --| client.py # 基于 stdio 传输的 MCP 客户端入口 --| server.py # 低层 MCP Server,仅注册两个请求处理器 --| tools ----| __init__.py # 工具注册表(以字典形式集中暴露所有工具) ----| add.py # add 工具的定义与处理函数 ----| schema.py # 基于 Pydantic 的输入模型(JSON Schema 来源)二、环境准备:创建虚拟环境并安装mcp[cli]
原文档给出的第一步是创建并激活 Python 虚拟环境:
python -m venv venv source ./venv/bin/activatepython -m venv venv会在当前目录生成名为venv的隔离虚拟环境,避免 MCP SDK 依赖污染系统 Python;source ./venv/bin/activate在 Linux/macOS 下激活该环境(Windows 下对应为venv\Scripts\activate);- 激活后,后续
pip安装与python运行均在此环境中进行。
第二步是安装依赖:
pip install "mcp[cli]"这里需要重点说明[cli]这个 extra 的含义:mcp是 Model Context Protocol 的官方 Python SDK,基础包已包含ClientSession、StdioServerParameters、mcp.server.stdio等核心模块;而[cli]额外附带命令行工具相关依赖。示例的客户端与服务器分别通过from mcp import ClientSession, StdioServerParameters, types与from mcp.server.lowlevel import NotificationOptions, Server导入 SDK,这些正是由mcp包提供的核心 API。若后续需要直接使用mcp命令行(如配合 MCP Inspector 调试),该 extra 也是必需的。
三、运行示例:python client.py与预期输出
环境就绪后,在原文档(即 03-GettingStarted/10-advanced/code/python/README.md)中执行:
python client.py正常情况下,终端会输出两行关键信息:
Available tools: ['add'] Result of add tool: meta=None content=[TextContent(type='text', text='8.0', annotations=None, meta=None)] structuredContent=None isError=False这两行输出逐字验证了整个 MCP 调用链已经走通:
Available tools: ['add']:客户端成功发起tools/list请求,服务器返回当前唯一的工具add;Result of add tool: ...:客户端随后以参数{"a": 5, "b": 3}发起tools/call请求,服务器返回TextContent(type='text', text='8.0'),即5 + 3 = 8.0(add工具将输入强制转为float后求和,故结果带小数位)。
注意text='8.0'这一细节:它印证了 tools/add.py 中float(input_model.a) + float(input_model.b)的实现——Pydantic 模型字段声明为float后,传入的整数5、3被转换为浮点数参与运算。
四、源码级剖析:低层 Server 的双处理器架构
要理解示例为何能以“一个 Server + 一个 tools 目录”就完成工具注册与调用,需要通读 server.py 的实现。与常规FastMCP逐个@mcp.tool()注册的方式不同,低层 Server 只为每个特性类型(工具、资源、提示词)维护两个处理器,本示例中即:
4.1 工具列表处理器handle_list_tools
对应 server.py 中的@server.list_tools()装饰器函数。其核心逻辑是遍历tools注册表中的每一个工具定义,将其包装为符合 MCP 协议返回类型的types.Tool:
@server.list_tools() async def handle_list_tools() -> list[types.Tool]: """List available tools.""" vm_tools = [] for tool in tools.values(): print(f"Registered tool: {tool['name']}") vm_tools.append( types.Tool( name=tool["name"], description=tool["description"], inputSchema=convert_to_json(tool["input_schema"]), ) ) return vm_tools这里的convert_to_json是示例中一个关键辅助函数(见 server.py),它接收一个 Pydantic 模型类,通过model_cls.schema()取得 JSON Schema,再精简为{"type": "object", "properties": ..., "required": ...}结构,作为 MCP 协议要求的inputSchema返回。这一设计让工具作者只需要声明 Pydantic 模型,无需手写 JSON Schema。
4.2 工具调用处理器handle_call_tool
对应 server.py 中的@server.call_tool()装饰器函数。它接收工具名name与参数字典arguments,通过名称查表、调用对应 handler 并统一包装返回结果:
@server.call_tool() async def handle_call_tool( name: str, arguments: dict[str, str] | None ) -> list[types.TextContent]: if name not in tools: raise ValueError(f"Unknown tool: {name}") tool = tools[name] result = "default" try: result = await tool"handler" except Exception as e: raise ValueError(f"Error calling tool {name}: {str(e)}") return [ types.TextContent(type="text", text=str(result)) ]可见:未知工具名会抛出ValueError;已知工具通过await tool"handler"异步调用;参数校验的失败会由 handler 内部抛出异常,进而在此处被捕获并转换为错误信息,避免服务器进程崩溃。所有工具的返回内容统一封装为types.TextContent,这也是客户端最终打印出text='8.0'的直接原因。
4.3 服务器启动与生命周期管理
server.py 中的run()函数展示了低层 Server 的启动方式:使用mcp.server.stdio.stdio_server()获取标准输入输出流,再调用server.run(...)传入InitializationOptions(含server_name="example-server"、server_version="0.1.0"与通过server.get_capabilities()计算的 capabilities)。其中NotificationOptions()用于声明服务器支持的协议通知类型,experimental_capabilities={}表示未启用实验性能力。
4.4tools/目录:工具定义与校验的落点
工具侧由三个文件组成,形成了“Schema 声明 → 工具定义 → 集中注册”的清晰链路:
- tools/schema.py 定义 Pydantic 输入模型:
from pydantic import BaseModel class AddInputModel(BaseModel): a: float b: float- tools/add.py 定义工具元信息与处理函数:
from .schema import AddInputModel async def add_handler(args) -> float: try: # Validate input using Pydantic model input_model = AddInputModel(**args) except Exception as e: raise ValueError(f"Invalid input: {str(e)}") """Handler function for the add tool.""" return float(input_model.a) + float(input_model.b) add = { "name": "add", "description": "Adds two numbers", "input_schema": AddInputModel, "handler": add_handler }这里体现了章节 README 强调的“在 handler 内做校验”策略:AddInputModel(**args)会依据a、b两个float字段对传入参数进行类型与必填性校验,参数缺失或类型不符会抛出异常并被捕获为ValueError。工具字典的四要素name、description、input_schema、handler与服务器端handle_list_tools/handle_call_tool的读取字段一一对应,这就是两个处理器能“无差别”驱动任意工具的原因。
- tools/init.py 以字典形式集中注册工具:
from .add import add tools = { add["name"] : add }今后每新增一个工具,只需在tools/下新增“Schema 文件 + 工具定义文件”,并在__init__.py中追加一条注册项,服务器端代码完全不需要改动——这正是该架构可扩展性的核心。
五、客户端视角:stdio 传输与调用链验证
client.py 演示了 MCP 客户端通过 stdio 传输与本示例服务器的完整交互流程,共三步:
- 构建服务器启动参数:
StdioServerParameters(command="python", args=["server.py"])指明以python server.py子进程方式启动服务器; - 建立会话并初始化:
stdio_client(server_params)打开双向标准流,ClientSession(read, write)建立会话,随后await session.initialize()完成 MCP 握手; - 依次调用协议方法:
session.list_tools()获取工具清单并打印名称,session.call_tool("add", {"a": 5, "b": 3})调用 add 工具并打印结果对象。
从打印出的Result对象可以看出,MCP 的工具调用返回值是一个包含content、meta、structuredContent、isError等字段的结构化结果;isError=False表明调用成功,content=[TextContent(...)]中承载服务器返回的文本内容。客户端入口通过asyncio.run(run())驱动异步流程(见 client.py)。
六、从示例到架构:为什么选用低层 Server
示例背后对应章节 03-GettingStarted/10-advanced/README.md 对“常规 Server vs 低层 Server”做了系统对比:常规 Server(Python 的FastMCP、TypeScript 的McpServer)通过@mcp.tool()/registerTool逐个注册特性;而低层 Server 则“每个特性类型只写两个处理器”——一个负责list(列出全部特性)、一个负责call(分发调用请求)。
本示例正是该理念的落地:在 server.py 中,无论将来注册多少个工具,服务器侧代码体量保持不变,新增工具的工作全部收敛到tools/目录内。章节 README 还给出了一种可直接推广的目录组织方式(app --| tools --| resources --| prompts),并指出低层 Server 的另一个优势在于可访问某些高级特性,例如课程后续章节(如 Sampling、Elicitation 相关能力)只有在低层 Server 上才可用,其中 Sampling 已在 MCP 协议版本2026-07-28中标记为 legacy/废弃特性。
此外,原文档在 03-GettingStarted/10-advanced/README.md 中还布置了扩展练习(Assignment):在给定代码基础上继续增加工具、资源和提示词,并体会“只需要在tools/目录中新增文件、无需改动其他位置”的架构优势(该练习未提供官方答案)。读者可以参照本示例的add工具模式,在tools/下复制出subtract.py、multiply.py等新工具并更新__init__.py注册表,即可直观验证这一结论。
七、小结:一条完整的验证闭环
从 translations/bg/03-GettingStarted/10-advanced/code/python/README.md(或英文原文 03-GettingStarted/10-advanced/code/python/README.md)出发,本示例形成了“环境搭建 → 依赖安装 → 一键运行 → 输出验证”的完整闭环,且每一步都有仓库源码作为事实依据:
| 环节 | 命令/文件 | 关键结论 |
|---|---|---|
| 环境隔离 | python -m venv venv && source ./venv/bin/activate | 独立运行 MCP SDK |
| 依赖安装 | pip install "mcp[cli]" | 官方 Python SDK 及其 CLI extra |
| 服务器 | server.py | list_tools/call_tool双处理器 + stdio 启动 |
| 工具定义 | tools/add.py | 名称/描述/Schema/处理器四要素字典 |
| 输入校验 | tools/schema.py | PydanticAddInputModel(a, b) |
| 客户端 | client.py | initialize → list_tools → call_tool |
| 预期输出 | Available tools: ['add']/text='8.0' | 验证工具列表与调用结果均正确 |
按此步骤在本地依次执行三条命令,即可复现完整的 MCP 低层 Server 端到端交互;再结合本节源码逐行阅读,就能透彻理解“两个处理器驱动任意工具”这一低层 Server 架构设计的精髓。
- 教程
- 文档
- 人工智能
【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
相关推荐
mcp-for-beginners 实战:用 TypeScript 低级服务器构建可验证的 MCP 工具,并借助 MCP Inspector 完成端到端测试
mcp for beginners 实战:用 TypeScript 低级服务器构建可验证的 MCP 工具,并借助 MCP Inspector 完成端到端测试 本
教程文档人工智能mcp-for-beginners 进阶指南:用 MCP 低层服务器(Low-Level Server)打造可扩展、可验证的工具架构
mcp for beginners 进阶指南:用 MCP 低层服务器(Low Level Server)打造可扩展、可验证的工具架构 本篇文章是 mcp for
教程文档人工智能mcp-for-beginners 实战:运行并理解基于低层服务器的 Python MCP 示例
mcp for beginners 实战:运行并理解基于低层服务器的 Python MCP 示例 导读 本文以 mcp for beginners 课程第 10
教程文档人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考