MCP服务器开发指南
概述
模型上下文协议即Model Context Protocol,简称MCP,它是一个开放协议,它规范了应用程序如何向大型语言模型(LLM)提供上下文。
MCP协议将不同模型的功能调用标准整合为统一的标准协议,几乎所有市场上的大型模型都可以连接到MCP,它定义了统一的集成方式。
在开发智能体(Agent)的过程中,经常需要将将智能体与数据和工具集成,MCP以标准的方式规范了智能体与数据及工具的集成方式,可以帮助在LLM之上构建智能体和复杂的工作流。
MCP官网: https://modelcontextprotocol.io
本文通过两个示例,构建自己的MCP Server:
-
文件操作服务器 :一个可以读写、列出、复制和删除本地文件的多功能工具集。
-
天气查询服务器 :一个能集成第三方网络 API,提供实时天气信息的服务。
准备工作:安装MCP SDK
首先,需要安装 mcp SDK
,这里使用Python库。这是构建MCP Server的基础。打开终端或命令行工具,运行以下命令:
python
pip install mcp
构建本地文件管理服务器
这个服务器将提供一套基本但非常实用的文件操作功能,让客户端能管理操作系统上的文件。
创建MCP服务器
创建一个名为 my_mcp_server.py
的Python文件。这个脚本使用FastMCP
框架来定义一系列工具函数,每个函数都对应一个文件操作。
MCP服务器提供以下五项关键文件操作功能:
read_txt
: 读取指定文本文件的内容。write_txt
: 向指定文本文件写入内容。list_files
: 列出目标目录下的所有文件。copy_file
: 复制文件。delete_file
: 删除文件。
每个函数都包含了周全的错误处理,确保在操作失败时能返回清晰的提示。
python
import os
import shutil
from typing import List, Optional
from mcp.server.fastmcp import FastMCP
# 初始化MCP服务实例
mcp = FastMCP("My_Mcp_Server")
@mcp.tool()
def read_txt(filepath: str) -> str:
"""读取文本文件内容
Args:
filepath (str): 文件路径
Returns:
str: 文件内容或错误信息
"""
try:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
return content
except Exception as e:
return f"Mcp Server 读取文件失败: {str(e)}"
@mcp.tool()
def write_txt(filepath: str, content: str, mode: str = 'w') -> str:
"""写入文本文件
Args:
filepath (str): 文件路径
content (str): 要写入的内容
mode (str, optional): 写入模式. 默认为 'w'
Returns:
str: 操作结果信息
"""
try:
with open(filepath, mode, encoding="utf-8") as f:
f.write(content)
return f"Mcp Server 写入文件成功: {filepath}"
except Exception as e:
return f"Mcp Server 写入文件失败: {str(e)}"
@mcp.tool()
def list_files(directory: str, pattern: Optional[str] = None) -> List[str]:
"""列出目录下的所有文件
Args:
directory (str): 目录路径
pattern (str, optional): 文件匹配模式,如 '*.txt'
Returns:
List[str]: 文件路径列表
"""
try:
if not os.path.exists(directory):
return [f"目录不存在: {directory}"]
files = []
for root, _, filenames in os.walk(directory):
for filename in filenames:
if pattern:
if filename.endswith(pattern.replace('*', '')):
files.append(os.path.join(root, filename))
else:
files.append(os.path.join(root, filename))
return files
except Exception as e:
return [f"列出文件失败: {str(e)}"]
@mcp.tool()
def copy_file(src: str, dst: str) -> str:
"""复制文件
Args:
src (str): 源文件路径
dst (str): 目标文件路径
Returns:
str: 操作结果信息
"""
try:
shutil.copy2(src, dst)
return f"文件复制成功: {src} -> {dst}"
except Exception as e:
return f"文件复制失败: {str(e)}"
@mcp.tool()
def delete_file(filepath: str) -> str:
"""删除文件
Args:
filepath (str): 要删除的文件路径
Returns:
str: 操作结果信息
"""
try:
if os.path.exists(filepath):
os.remove(filepath)
return f"文件删除成功: {filepath}"
return f"文件不存在: {filepath}"
except Exception as e:
return f"文件删除失败: {str(e)}"
# 添加动态欢迎词资源
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""获取个性化的问候"""
return f"Hello, {name}!"
if __name__ == '__main__':
# 启动MCP服务,使用标准输入输出作为传输方式
mcp.run(transport='stdio')
配置 mcp.json
为了让MCP客户端能找到并启动MCP服务器,需要在项目的根目录(或指定配置目录)下创建一个 mcp.json
文件。
bash
{
"mcpServers": {
"My_Mcp_Server": {
"command": "python",
"args": [
"D:/WorkSpace/AI/demo/my_mcp_server.py"
]
}
}
}
配置说明:
"My_Mcp_Server"
: 这是MCP服务器的唯一标识符,必须与代码中FastMCP("My_Mcp_Server")
的名称一致。"command"
: 启动服务器的命令,这里是python
。"args"
: 传递给命令的参数列表,这里是服务器脚本的绝对路径。
这里使用Cursor工具,配置后确保开启,然后状态是绿色

测试与使用
配置完成后,就可以在客户端中调用这些工具了。
示例 1:列出目录下的所有文件 示例 2:向文件写入内容
集成网络API的天气服务器
实现了基础的文件操作MCP服务器构建后,进一步拓展,开发一个能够查询天气信息的MCP服务器。
将外部API集成到MCP服务中:创建一个能从互联网获取数据的MCP Server。这个服务器将调用一个公开的天气 API,查询并返回未来一周的天气预报。
创建天气服务器脚本
这个脚本的核心是 get_weekly_weather
函数,它接收一个城市名称,通过 requests
库向天气 API 发送网络请求,并返回查询结果。
python
# 导入必要的库
import requests # 用于发送 HTTP 请求
import json # 用于解析 JSON 数据
from mcp.server.fastmcp import FastMCP # 从 mcp.server 库中导入 FastMCP
# 初始化 FastMCP 实例,并为服务器命名
# 这个名字有助于客户端识别不同的 MCP 服务
mcp = FastMCP("Weather_MCP_Server")
@mcp.tool()
def get_weekly_weather(city: str) -> dict:
"""
获取指定城市未来一周的天气预报。
通过调用一个公开的天气 API 来实现。这个工具展示了如何将外部 API 服务集成到 MCP 中。
Args:
city (str): 需要查询天气的城市名称,例如 "北京"、"上海"。
Returns:
dict: 包含天气数据或错误信息的字典。
"""
# 天气 API 的基础 URL
api_url = "https://api.xxx.com/api/weather"
# 构建请求参数
params = {
"city": city,
"type": "week" # 指定获取周度天气
}
try:
# 发送 GET 请求到天气 API,设置 10 秒超时
response = requests.get(api_url, params=params, timeout=10)
# 检查 API 是否返回了成功的状态码 (例如 200 OK)
response.raise_for_status()
# 解析返回的 JSON 数据
weather_data = response.json()
# 直接返回从 API 获取到的完整天气数据
return weather_data
except requests.exceptions.Timeout:
# 处理请求超时异常
return {"error": f"请求天气 API 超时: {api_url}"}
except requests.exceptions.RequestException as e:
# 处理其他网络相关的异常 (如连接错误)
return {"error": f"获取天气信息失败: {str(e)}"}
except json.JSONDecodeError:
# 处理 JSON 解析失败的异常,这可能意味着 API 返回了非 JSON 格式的错误页面
return {"error": "解析天气 API 响应失败,返回的可能不是有效的 JSON 数据。"}
except Exception as e:
# 捕获其他未知异常
return {"error": f"查询天气时发生未知错误: {str(e)}"}
# --- 主程序入口 ---
if __name__ == '__main__':
print("天气查询 MCP 服务器已启动...")
print("可用的工具: get_weekly_weather(city: str)")
print("示例城市: 北京, 上海, 广州, London")
# 启动 MCP 服务,使用标准输入输出 (stdio) 作为传输协议
# 这使得任何支持 stdio 的 MCP 客户端都能连接并使用此服务
mcp.run(transport='stdio')
更新 mcp.json
配置
将天气MCP服务器的配置添加到 mcp.json
文件中。
python
{
"mcpServers": {
"My_Mcp_Server": {
"command": "python",
"args": [
"D:\\WorkSpace\\AI\\demo/my_mcp_server.py"
]
},
"Weather_MCP_Server": {
"command": "python",
"args": [
"D:\\WorkSpace\\AI\\demo\\weather_mcp_server.py"
]
}
}
}

测试天气服务
现在,可以在客户端中像调用本地工具一样,调用天气查询服务了。
大模型回答输出结果如下: