MCP服务器(模型上下文协议服务器)
一个基于Flask的服务器,通过实现模型上下文协议(Model Context Protocol),使用自然语言增强大型语言模型(LLM)的外部工具能力,允许像天气查询和计算这样的工具直接在模型的文本输出中调用。
服务介绍
MCP 服务器实现
基于 Flask 的 Model Context Protocol (MCP) 完整实现,通过外部工具增强大型语言模型的能力。
概述
本仓库展示了如何构建一个处理 Model Context Protocol (MCP) 的服务器。MCP 是一种通过直接在模型的文本输出中调用工具来扩展 LLM 能力的方法。与函数调用不同,MCP 将工具定义直接放在上下文窗口中,并解析模型的自然语言响应以识别工具使用情况。
特性
- 🔧 完整的 MCP 实现:全解析、执行和响应处理
- 🌤️ 示例工具:带有参数验证的天气和计算器工具
- 🔄 对话流程:跨多次交互保持上下文
- 🧩 基于正则表达式的解析:灵活的工具调用文本解析
- 🚀 Flask API:用于聊天集成的 REST API 端点
项目结构
mcp_server/
├── app.py # Main Flask application
├── mcp_handler.py # MCP parsing and execution
├── mcp_example.py # Standalone MCP example
├── requirements.txt # Dependencies
├── tools/ # Tool implementations
│ ├── __init__.py
│ ├── weather.py # Weather API tool
│ └── calculator.py # Calculator tool
└── README.md # This file
安装
-
克隆仓库:
git clone https://github.com/yourusername/mcp-server.git cd mcp-server -
创建虚拟环境:
python -m venv venv source venv/bin/activate # 在 Windows 上: venv\Scripts\activate -
安装依赖项:
pip install -r requirements.txt -
设置环境变量:
# 创建一个 .env 文件并包含以下内容: LLM_API_KEY=你的_llm_api_key WEATHER_API_KEY=你的_weather_api_key FLASK_APP=app.py FLASK_ENV=development
使用
运行服务器
启动 Flask 开发服务器:
flask run
对于生产环境:
gunicorn app:app
API 端点
- POST /chat: 通过 MCP 处理聊天消息
curl -X POST http://localhost:5000/chat \ -H "Content-Type: application/json" \ -d '{ "messages": [ { "role": "user", "content": "波士顿的天气怎么样?" } ] }'
独立示例
运行示例脚本来查看 MCP 的实际效果:
python mcp_example.py
工作原理
- 工具注册:注册工具及其参数和执行逻辑
- 工具定义注入:将 XML 格式的工具描述添加到提示中
- LLM 响应处理:使用正则表达式模式识别 LLM 文本输出中的工具调用
- 工具执行:解析参数并将它们传递给相应的工具处理程序
- 结果注入:将工具执行结果插入回响应中
MCP 与函数调用对比
| 特性 | MCP | 函数调用 |
|---|---|---|
| 定义位置 | 在提示文本中 | 在 API 参数中 |
| 调用格式 | 自然语言 | 结构化的 JSON |
| 实现方式 | 文本解析 | API 集成 |
| 可见性 | 在响应中可见 | 可能被隐藏 |
| 平台支持 | 任何基于文本的 LLM | 需要 API 支持 |
示例对话
用户: 波士顿的天气怎么样?
LLM:
I'll check the weather for you.
get_weather(location="Boston, MA", unit="fahrenheit")
处理后:
I'll check the weather for you.
get_weather(location="Boston, MA", unit="fahrenheit")
Result from get_weather:
{
"location": "Boston, MA",
"temperature": 72,
"unit": "fahrenheit",
"conditions": "Partly Cloudy",
"humidity": 68,
"wind_speed": 5.8
}
添加您自己的工具
- 创建一个继承自
Tool的新类 - 定义参数和执行逻辑
- 向 MCP 处理程序注册
示例:
class MyTool(Tool):
def __init__(self):
parameters = [
{
"name": "param1",
"type": "string",
"description": "Description of param1",
"required": True
}
]
super().__init__(
name="my_tool",
description="Description of my tool",
parameters=parameters
)
def execute(self, param1):
# Tool logic here
return {"result": "Processed " + param1}
MCP 配置和调用流程
-
工具注册:
- MCP 工具向处理程序注册
- 每个工具提供其名称、描述和参数定义
-
工具定义注入:
- 工具定义被添加到系统消息中
- 格式遵循 MCP 的 XML 结构
-
LLM 响应处理:
- LLM 生成的响应可能包含工具调用
- 模式匹配在文本中识别工具调用
- 解析工具参数并传递给工具执行方法
-
工具执行:
- 使用提供的参数执行工具
- 结果被注入回对话中
-
对话管理:
- 包含工具结果的处理后的响应被添加到对话历史中
- 未来的 LLM 请求将包括此历史记录以提供上下文
示例对话
以下是一个对话示例:
用户: 波士顿的天气怎么样?
系统: 向 LLM 发送带有 MCP 工具定义的提示
LLM 响应:
I'll check the weather for you.
get_weather(location="Boston, MA", unit="fahrenheit")
MCP 处理程序: 解析响应,找到工具调用,并执行天气工具
工具执行结果:
Result from get_weather:
{
"location": "Boston, MA",
"temperature": 72,
"unit": "fahrenheit",
"conditions": "Partly Cloudy",
"humidity": 68,
"wind_speed": 5.8
}
处理后的响应(发送给用户):
I'll check the weather for you.
get_weather(location="Boston, MA", unit="fahrenheit")
Result from get_weather:
{
"location": "Boston, MA",
"temperature": 72,
"unit": "fahrenheit",
"conditions": "Partly Cloudy",
"humidity": 68,
"wind_speed": 5.8
}
用户: 你能计算 144 的平方根吗?
LLM 响应:
I can calculate that for you.
calculator(expression="sqrt(144)")
MCP 处理程序: 解析响应,执行计算器工具
工具执行结果:
Result from calculator:
{
"expression": "sqrt(144)",
"result": 12.0
}
处理后的响应(发送给用户):
I can calculate that for you.
calculator(expression="sqrt(144)")
Result from calculator:
{
"expression": "sqrt(144)",
"result": 12.0
}
The square root of 144 is 12.
这展示了从 LLM 的基于文本的调用到执行和响应处理的完整 MCP 工具使用流程。
许可证
MIT
贡献
欢迎贡献!请随时提交 Pull Request。