当前位置:首页>python>第4篇|用Python写第一个MCP Server:让AI调用你的计算工具

第4篇|用Python写第一个MCP Server:让AI调用你的计算工具

  • 2026-09-21 16:05:07
第4篇|用Python写第一个MCP Server:让AI调用你的计算工具

前面三篇,我们讲清了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名称;
  • Tool说明;
  • 参数名称;
  • 参数类型;
  • 当前用户的需求。

如果Tool只叫process,说明只写“处理数据”,模型很难准确判断它的用途。

而calculate_average配合清晰说明,模型就更容易在用户提出“计算平均数”时选择它。

因此,设计Tool时,函数命名和文档说明不是装饰,而是模型选择工具的重要依据。


七、处理空数组

计算平均值时,数组不能为空。

所以代码中增加了判断:

ifnot values:
raise ValueError("values不能为空")

如果用户传入:

{
"values": []
}

Tool不会执行除零运算,而是返回明确错误。

真实项目中的Tool也应该主动处理边界情况,例如:

  • 参数为空;
  • 数值超出范围;
  • 文件不存在;
  • 数据库记录不存在;
  • 外部API超时。

不要假设模型每次都能生成完美参数。

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服务的基本结构:

  • 创建Server实例;
  • 通过装饰器注册Tool;
  • 使用类型提示定义参数Schema;
  • 返回结构化结果;
  • 通过stdio等待客户端调用;
  • 使用Inspector完成测试。

MCP开发并不神秘。

它的核心,就是把普通程序能力包装成AI能够发现、理解和调用的标准接口。

普通函数解决业务问题,MCP让这个函数进入AI的工具世界。

下一篇,我们将继续把这个Server接入真实的AI编程工具,让AI根据自然语言自动决定何时调用calculate_average。

Reference
[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

最新文章

随机文章