Agent学习笔记3:使用Python开发简单MCP服务
本文介绍了如何使用Python开发MCP(Model Context Protocol)服务,实现大语言模型与外部工具的交互。主要内容包括:MCP协议概述及其标准化、安全性优势;环境准备与FastMCP框架安装;通过装饰器定义MCP工具(文件写入和天气查询示例);服务启动配置(支持SSE和STDIO两种传输方式);环境变量安全管理;以及扩展建议(添加新工具和参数验证)。文章提供了完整代码示例,帮助
Agent学习笔记3:使用Python开发简单MCP服务
前言
在构建智能体应用时,让大语言模型与外部世界进行交互是一个核心需求。MCP(Model Context Protocol,模型上下文协议)提供了一种标准化的方式来实现这一目标。本文将通过一个实际的代码示例,带你快速掌握使用Python开发MCP服务的方法。
一、认识MCP协议
MCP是Anthropic推出的一种通信协议,专门用于连接大语言模型与外部工具、数据源。通过MCP,AI模型可以调用文件系统、数据库、Web API等各种外部资源,实现更强大的功能。
MCP的核心优势体现在三个方面。首先是标准化,它提供了统一的协议规范,使不同来源的工具可以无缝集成。其次是安全性,通过受控的工具调用机制,避免AI模型直接访问敏感资源。第三是可扩展性,支持动态注册和发现工具,易于扩展新的功能。
MCP采用经典的客户端-服务器架构。服务端负责提供各种工具,执行实际的功能逻辑;客户端负责管理连接,将用户请求路由到相应的工具;大语言模型则负责理解用户意图,决定调用哪些工具并生成最终响应。
二、环境准备
在开始开发之前,我们需要准备Python环境并安装必要的依赖包。FastMCP是MCP协议的Python实现框架,我们需要通过pip进行安装:
pip install mcp requests python-dotenv
mcp包提供了FastMCP框架的核心功能,requests库用于调用外部API,python-dotenv用于管理环境变量。这些是开发MCP服务的基本依赖。
三、代码结构解析
让我们先看一下完整的代码结构,然后逐部分详细讲解:
from mcp.server.fastmcp import FastMCP
import requests
import os
# 从环境变量获取API密钥,确保安全性
AMAP_API_KEY = os.environ.get("AMAP_API_KEY", "")
mcp = FastMCP()
@mcp.tool()
def write_file(filename:str, content:str) -> str:
"""往文件文件中写入内容"""
with open(f"D:/AITest/{filename}", "w", encoding="utf-8") as file:
file.write(content)
return f"文件{filename}写入成功"
@mcp.tool()
def get_weather(city:str) -> str:
"""查询某个城市或区县的天气"""
if not AMAP_API_KEY:
return "错误:未配置高德地图API密钥"
url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key={AMAP_API_KEY}&extensions=all"
response = requests.get(url)
return response.json()["forecasts"]
if __name__ == "__main__":
mcp.settings.port = 8001
mcp.run(transport='sse')
四、初始化FastMCP服务
代码的第一行导入了FastMCP框架的核心类,这是构建MCP服务的基础:
from mcp.server.fastmcp import FastMCP
import requests
import os
FastMCP框架的设计理念是让开发者专注于业务逻辑,而无需关心协议解析、请求路由等底层细节。框架提供了简洁的装饰器API,通过@mcp.tool()即可将普通函数注册为MCP工具。
初始化一个FastMCP实例作为服务的根对象:
mcp = FastMCP()
这个实例将承载所有的工具定义,并负责处理客户端的请求。
安全提示:为了保护敏感信息,建议将API密钥存储在环境变量中,而不是硬编码在代码里。通过os.environ.get()方式获取可以有效避免密钥泄露风险。
五、定义MCP工具
5.1 文件写入工具
工具是MCP服务的核心概念,每个工具代表一个可被AI模型调用的功能。文件写入工具演示了如何将文件系统操作封装为MCP工具:
@mcp.tool()
def write_file(filename:str, content:str) -> str:
"""往文件文件中写入内容"""
with open(f"D:/AITest/{filename}", "w", encoding="utf-8") as file:
file.write(content)
return f"文件{filename}写入成功"
这个工具包含几个关键要素。@mcp.tool()装饰器将普通Python函数注册为MCP工具,FastMCP会自动处理协议层面的细节。函数参数使用了类型注解(filename:str和content:str),MCP框架会基于这些类型注解生成参数模式定义,帮助大模型理解参数的类型约束。文档字符串描述了工具的用途,这是大模型判断是否应该调用该工具的重要依据。函数返回一个字符串,表示操作结果,会被传递回调用方。
安全提示:在实际应用中,文件操作工具需要特别注意安全性。建议限制可写入的目录范围,对文件名进行校验,防止路径遍历攻击。
5.2 天气查询工具
天气查询工具展示了MCP如何封装外部API调用:
@mcp.tool()
def get_weather(city:str) -> str:
"""查询某个城市或区县的天气"""
if not AMAP_API_KEY:
return "错误:未配置高德地图API密钥"
url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key={AMAP_API_KEY}&extensions=all"
response = requests.get(url)
return response.json()["forecasts"]
这个工具的实现流程很清晰:首先检查API密钥是否配置,然后接收城市名称作为参数,构建高德地图天气API的请求URL,接着发起HTTP GET请求获取天气数据,最后解析JSON响应并返回预报信息。
通过这个例子可以看到,MCP工具可以封装任意复杂的业务逻辑,包括调用第三方API、操作数据库、访问文件系统等。这种封装方式使得AI模型可以透明地使用这些功能,无需了解底层的实现细节。
安全提示:工具函数中应该包含适当的参数验证和错误处理逻辑,确保在异常情况下也能安全地返回信息,而不是暴露敏感的内部细节。
六、启动MCP服务
服务端的启动配置体现了MCP的灵活性:
if __name__ == "__main__":
mcp.settings.port = 8001
mcp.run(transport='sse')
这段代码使用SSE传输模式在端口8001上启动服务。SSE(Server-Sent Events,服务器发送事件)是一种基于HTTP的技术,允许服务器主动向客户端推送数据。相比另一种传输方式STDIO(标准输入输出),SSE支持跨网络访问,适合远程部署场景。
FastMCP支持两种传输方式,各有适用场景。STDIO方式通过标准输入输出进行进程间通信,适用于本地工具集成,延迟最低,不需要网络配置。SSE方式通过HTTP长连接实现双向通信,适合远程服务部署,可以被网络中的其他机器访问。
七、环境变量配置
为了安全地管理API密钥和其他敏感配置,我们使用环境变量。在项目根目录下创建.env文件:
# 高德地图API密钥
AMAP_API_KEY=your_api_key_here
# DeepSeek API密钥(用于客户端)
DEEPSEEK_API_KEY=your_deepseek_api_key_here
在代码中通过python-dotenv加载环境变量:
from dotenv import load_dotenv
load_dotenv()
AMAP_API_KEY = os.environ.get("AMAP_API_KEY")
安全最佳实践:
- 永远不要将包含真实密钥的
.env文件提交到版本控制系统 - 在
.gitignore中添加.env文件 - 为不同环境(开发、测试、生产)使用不同的配置
- 定期轮换API密钥
八、运行服务
启动MCP服务非常简单,只需运行脚本即可:
# 设置环境变量并启动服务
export AMAP_API_KEY=your_api_key_here # Linux/Mac
# 或
$env:AMAP_API_KEY="your_api_key_here" # Windows PowerShell
python mcp_server.py
服务启动后,会在指定端口监听SSE连接。当客户端连接并,服务会自动注册的所有请求工具列表时工具提供给客户端使用。
九、扩展建议
9.1 添加新工具
在现有代码基础上添加新工具非常方便,只需定义新的函数并使用@mcp.tool()装饰器即可:
@mcp.tool()
def read_file(filename: str) -> str:
"""读取文件内容"""
try:
with open(f"D:/AITest/{filename}", "r", encoding="utf-8") as file:
return file.read()
except FileNotFoundError:
return f"文件{filename}不存在"
except Exception as e:
return f"读取文件时出错:{str(e)}"
9.2 参数验证
为了确保工具的健壮性,可以添加参数验证逻辑:
@mcp.tool()
def get_weather(city:str) -> str:
"""查询某个城市或区县的天气"""
if not city or len(city.strip()) == 0:
return "城市参数不能为空"
# 限制城市名称长度,防止恶意输入
if len(city.strip()) > 50:
return "城市名称过长"
# 过滤特殊字符,防止注入攻击
if any(char in city for char in [";", "|", "&", "$"]):
return "城市名称包含非法字符"
# 原有逻辑...
9.3 工具调用日志记录
添加日志记录功能有助于监控和调试:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@mcp.tool()
def write_file(filename:str, content:str) -> str:
"""往文件文件中写入内容"""
logger.info(f"执行写文件操作:{filename}")
try:
with open(f"D:/AITest/{filename}", "w", encoding="utf-8") as file:
file.write(content)
logger.info(f"文件写入成功:{filename}")
return f"文件{filename}写入成功"
except Exception as e:
logger.error(f"文件写入失败:{str(e)}")
return f"写入文件时出错:{str(e)}"
9.4 访问控制
对于敏感工具,可以添加访问控制机制:
def check_access(allowed_users: list):
"""访问控制装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
# 实际应用中需要从请求上下文中获取用户信息
# 这里仅作为示例
return func(*args, **kwargs)
return wrapper
return decorator
@mcp.tool()
def sensitive_operation() -> str:
"""敏感操作工具"""
# 添加权限检查逻辑
return "操作执行成功"
十、安全最佳实践
10.1 敏感信息管理
API密钥、数据库密码等敏感信息绝对不能硬编码在源代码中。正确做法是使用环境变量或专业的密钥管理服务。在开发环境中可以使用.env文件配合python-dotenv管理;在生产环境中应该使用云服务商提供的密钥管理服务(如AWS Secrets Manager、Azure Key Vault等)。
10.2 输入验证与清理
所有来自外部的输入都可能包含恶意内容,工具函数必须对输入参数进行严格验证。验证内容包括:参数类型检查、长度限制、特殊字符过滤、格式校验等。对于文件名等路径相关的参数,要防止路径遍历攻击。
10.3 错误处理
工具函数应该捕获可能的异常并进行适当处理,而不是让异常信息直接暴露给调用方。错误信息不应该包含敏感的系统内部细节,如文件路径、数据库结构等。建议记录详细错误日志供开发者调试,但返回给用户的信息应该经过脱敏处理。
10.4 权限控制
根据实际需求,为不同的工具设置访问权限控制。敏感操作(如删除文件、执行系统命令等)应该要求额外的权限验证。在生产环境中,可以通过API密钥、令牌等方式实现访问控制。
10.5 网络安全
如果MCP服务需要暴露在公网,应该使用HTTPS/TLS加密通信。同时,应该配置适当的访问速率限制,防止恶意请求导致服务不可用。对于允许访问的客户端IP,可以考虑设置白名单。
十一、总结
通过本文的学习,我们了解了如何使用Python和FastMCP框架开发简单的MCP服务。核心要点包括:FastMCP框架提供了简洁的装饰器API来注册工具;工具函数通过类型注解和文档字符串提供元信息;SSE传输方式支持远程部署;MCP协议实现了AI与外部世界的标准化连接。
同时,我们也强调了开发MCP服务时需要注意的安全事项:不要硬编码API密钥、对用户输入进行严格验证、实现完善的错误处理机制、根据需要设置访问控制。这些安全最佳实践对于保护你的应用和数据至关重要。
参考资料
更多推荐



所有评论(0)