前面三篇,我们讲清了MCP的基本架构,以及Tools、Resources和Prompts的区别。
从这一篇开始,正式进入实战。
我们的目标非常简单:使用Python开发一个可以运行的MCP Server,并向AI客户端提供一个名为calculate_average的Tool。
输入一组数字:
{
"values": [12.5, 13.8, 11.9]
}
返回平均值:
{
"average": 12.73
}
项目虽然简单,却包含了MCP Server开发最核心的流程:
安装SDK、创建Server、注册Tool、定义参数、返回结果,以及通过stdio与客户端通信。
一、先说明一个重要版本变化
很多旧教程使用下面的写法:
from mcp.server.fastmcp import FastMCP
但在2026年7月发布的官方Python SDK 2.0中,FastMCP已经更名为MCPServer,旧导入路径也不再保留。
因此,本篇使用当前稳定版语法:
from mcp.server import MCPServer
虽然名称变了,但核心开发方式没有改变:仍然可以通过装饰器注册Tool、Resource和Prompt,参数Schema也仍然可以根据Python类型提示自动生成。(MCP Python SDK[1])
二、创建Python项目
官方Python SDK要求Python 3.10或更高版本,并推荐使用uv管理项目和依赖。(MCP Python SDK[2])
首先创建项目:
uv init mcp-average-server
cd mcp-average-server
安装带命令行工具的官方SDK:
uv add "mcp[cli]"
没有使用uv,也可以直接通过pip安装:
pip install "mcp[cli]"
安装完成后,在项目目录中创建文件:
server.py
最终目录非常简单:
mcp-average-server/
├─ pyproject.toml
└─ server.py
三、创建MCP Server
打开server.py,先写入下面两行代码:
from mcp.server import MCPServer
mcp = MCPServer("average-calculator")
第一行导入官方SDK提供的高级Server类。
第二行创建一个MCP Server实例,并给它命名为:
average-calculator
这个名称相当于服务的身份标识。
未来,一个Host可能同时连接文件服务、数据库服务、代码仓库服务和计算服务。清晰的名称有助于开发者区分不同Server。
四、注册第一个Tool
接下来,编写计算平均值的函数:
@mcp.tool()
defcalculate_average(values: list[float]) -> dict[str, float]:
"""计算一组数字的平均值,结果保留两位小数。"""
ifnot values:
raise ValueError("values不能为空")
average = round(sum(values) / len(values), 2)
return {
"average": average
}
这段代码中,最关键的是:
@mcp.tool()
它告诉SDK:
❝下面这个普通Python函数,需要作为MCP Tool对外提供。
Server启动后,支持MCP的客户端就可以发现calculate_average,查看它的参数,并向它发起调用。
五、类型提示为什么重要?
函数参数写成了:
values: list[float]
它表示values必须是一个由数字组成的数组。
返回类型写成:
dict[str, float]
它表示函数返回一个字典,键为字符串,值为浮点数。
这些类型提示不仅是给程序员看的。
官方SDK会根据类型提示自动生成Tool的输入Schema。客户端看到的参数结构,大致相当于:
{
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"type": "number"
}
}
},
"required": ["values"]
}
我们不需要手写JSON Schema,也不需要自己完成参数解析、数据校验和协议序列化,SDK会处理这些工作。(MCP Python SDK[3])
这也是使用高级MCP SDK的价值:
开发者主要关注业务函数,而不是底层协议细节。
六、为什么还要写函数说明?
函数下面有一行文档说明:
"""计算一组数字的平均值,结果保留两位小数。"""
这段文字会成为Tool描述的重要来源。
模型通常会结合以下信息判断是否调用一个Tool:
如果Tool只叫process,说明只写“处理数据”,模型很难准确判断它的用途。
而calculate_average配合清晰说明,模型就更容易在用户提出“计算平均数”时选择它。
因此,设计Tool时,函数命名和文档说明不是装饰,而是模型选择工具的重要依据。
七、处理空数组
计算平均值时,数组不能为空。
所以代码中增加了判断:
ifnot values:
raise ValueError("values不能为空")
如果用户传入:
{
"values": []
}
Tool不会执行除零运算,而是返回明确错误。
真实项目中的Tool也应该主动处理边界情况,例如:
不要假设模型每次都能生成完美参数。
Tool本身必须具备基本的输入防护能力。
八、启动stdio服务
在文件末尾加入:
if __name__ == "__main__":
mcp.run(transport="stdio")
完整代码如下:
from mcp.server import MCPServer
mcp = MCPServer("average-calculator")
@mcp.tool()
defcalculate_average(values: list[float]) -> dict[str, float]:
"""计算一组数字的平均值,结果保留两位小数。"""
ifnot values:
raise ValueError("values不能为空")
average = round(sum(values) / len(values), 2)
return {
"average": average
}
if __name__ == "__main__":
mcp.run(transport="stdio")
运行服务:
uv run server.py
运行后,终端看起来可能没有任何变化。
这通常不是程序卡死,而是Server正在等待MCP客户端通过标准输入发送消息。
stdio模式使用进程的标准输入和标准输出传输MCP消息,适合本地AI应用启动和管理MCP Server。官方教程同样通过mcp.run(transport="stdio")启动本地服务。(Model Context Protocol[4])
需要特别注意:
stdio模式下,不要随意使用print()向标准输出打印调试信息。
因为标准输出是协议通信通道,额外文字可能破坏消息格式。调试日志应该写入标准错误或日志文件。
九、使用MCP Inspector测试
只启动Server还不够,我们还需要确认客户端是否能够发现并调用Tool。
官方提供了MCP Inspector,用于查看Tools、Resources、Prompts、参数Schema和执行结果。(Model Context Protocol[5])
在项目目录运行:
uv run mcp dev server.py
命令会启动开发环境并打开Inspector。
进入Tools页面后,可以看到:
calculate_average
输入:
{
"values": [12.5, 13.8, 11.9]
}
调用结果为:
{
"average": 12.73
}
Inspector还会根据list[float]自动生成数组输入界面,这说明SDK已经成功把Python类型转换成了Tool Schema。
十、一次调用到底发生了什么?
表面上,我们只是调用了一个Python函数。
但内部经历了完整的数据流:
MCP客户端
↓
发送Tool调用请求
↓
stdio传输JSON-RPC消息
↓
MCP Server解析参数
↓
执行calculate_average
↓
序列化返回结果
↓
MCP客户端接收结果
这些协议处理、参数校验和结果序列化,都由SDK完成。
我们真正编写的业务代码只有几行。
结语
至此,我们已经完成了第一个可以运行的MCP Server。
它虽然只会计算平均值,却已经具备MCP服务的基本结构:
MCP开发并不神秘。
它的核心,就是把普通程序能力包装成AI能够发现、理解和调用的标准接口。
普通函数解决业务问题,MCP让这个函数进入AI的工具世界。
下一篇,我们将继续把这个Server接入真实的AI编程工具,让AI根据自然语言自动决定何时调用calculate_average。
[1] What's new in v2 - MCP Python SDK: https://py.sdk.modelcontextprotocol.io/whats-new/
[2] MCP Python SDK - MCP Python SDK: https://py.sdk.modelcontextprotocol.io/
[3] MCP Python SDK - MCP Python SDK: https://py.sdk.modelcontextprotocol.io/
[4] Build an MCP server - Model Context Protocol: https://modelcontextprotocol.io/docs/develop/build-server
[5] MCP Inspector - Model Context Protocol: https://modelcontextprotocol.io/docs/tools/inspector