从零开始创建MCP Server实战指南
一、MCP协议核心概念
1.1 什么是MCP?
MCP(Model Context Protocol) 是一个标准化的“沟通规则”,由公司Anthropic提出,专门用于让大语言模型(LLM,比如通义千问、ChatGPT等)与外部工具或服务“对话”。
为什么需要MCP?
- 想象场景:假设你让一个AI助手帮你订机票,它需要:
- 查询航班信息(调用航空公司API)。
- 读取你的日历安排(调用日历工具)。
- 发送确认邮件(调用邮件系统)。
- 问题:如果每个工具的接口都不一样,AI需要学习多种“方言”,这会很混乱。
- MCP的作用:就像USB接口一样,统一了LLM与外部工具的“语言”,让AI能安全、标准化地调用任何工具,无需关心底层实现细节。
直观类比:
- MCP = USB接口:
- 工具:U盘、鼠标、硬盘等外设。
- MCP Server:外设本身(提供功能)。
- MCP Client:电脑(通过USB接口调用外设)。
- 效果:无论外设如何变化,电脑都能通过USB统一管理。
1.2 核心组件(用测试工程师视角拆解)
1. MCP Server
- 定义:提供具体功能的“服务端程序”。
- 作用:像一个工具箱,里面装着各种工具(比如文件读写、数据库查询、API调用等)。
2. MCP Client
- 定义:LLM的“遥控器”,负责向Server发送指令并接收结果。
- 作用:像一个翻译官,把LLM的自然语言指令翻译成Server能理解的请求。
3. 工具(Tool)
- 定义:Server提供的具体功能单元,是MCP的核心价值所在。
简单示例(测试场景模拟)
场景:测试“获取天气”功能
-
Server端:
- 提供工具
get_weather(city)
,通过调用第三方天气API返回数据。 - 需要测试:API密钥是否配置正确?网络请求是否超时?返回数据格式是否符合预期?
- 提供工具
-
Client端:
- 当LLM发送指令“获取北京天气”,Client应:
- 调用
get_weather("北京")
。 - 将API返回的温度数据(如25°C)转为自然语言反馈给LLM。
- 调用
- 当LLM发送指令“获取北京天气”,Client应:
-
测试用例示例:
- 正常用例:输入“上海”,验证返回温度是否为合理数值。
- 异常用例:
- 输入“火星” → 验证是否返回“城市不存在”错误。
- 断开网络 → 验证是否返回“网络连接失败”。
- 安全用例:
- 尝试调用未授权的工具(如
delete_weather_api_key()
) → 验证是否被拒绝。
- 尝试调用未授权的工具(如
二、环境准备
2.1 基础依赖
- 可参照MCP实践第一步–磕磕碰碰搭环境,已在本地搭建了一个mcp-client
三、从零实现MCP Server(Python示例)
3.1 第一个MCP Server:获取桌面文件列表
在之前的mcp-client工程中新建一个server1.py的文件。
文件代码如下:
import asyncio
import logging
import osfrom mcp import stdio_server
from mcp.server import InitializationOptions, NotificationOptions
from mcp.server.fastmcp import FastMCPfrom server import MCP_SERVER_NAMEmcp = FastMCP()
# 配置日志
logging.basicConfig(level=logging.INFO,format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(MCP_SERVER_NAME)@mcp.tool()
def get_desktop_files() -> str:"""获取桌面上的文件列表"""desktop_path = os.path.expanduser("~/Desktop")return os.listdir(desktop_path)async def main():# 使用 stdio_server 建立 STDIO 通信async with stdio_server() as (read_stream, write_stream):# 构造初始化选项init_options = InitializationOptions(server_name=MCP_SERVER_NAME,server_version="1.0.0",capabilities=mcp._mcp_server.get_capabilities(notification_options=NotificationOptions(),experimental_capabilities={}))logger.info("通过 STDIO 模式启动 MCP Server ...")# 使用内部的 _mcp_server 运行服务await mcp._mcp_server.run(read_stream, write_stream, init_options)if __name__ == "__main__":asyncio.run(main())
关键点:
@mcp.tool()
:标记工具函数,供LLM调用。transport='stdio'
:通过标准输入输出通信(适合轻量级场景)。
3.2 运行与测试
uv run .\mcp-client.py .\server.py,.\server1.py
同时连接到两个mcp server:
在问题中输入:请获取桌面的文件信息,输出结果如下图所示:
下一步:尝试将MCP Server集成到之前编写的https://blog.csdn.net/weixin_44872675/article/details/147236350?spm=1001.2014.3001.5502AI应用中,例如:
- 让LLM直接将通过接口文档生成的接口用例,调用mcp server进行请求发送。