
Mcp server
MCP服务器实现的存储库
概述
MCP服务器实现
一个基于Flask的完整的Model Context Protocol (MCP) 实现,用以通过外部工具增强大型语言模型的能力。
概述
此存储库演示了如何构建一个处理Model Context Protocol (MCP) 的服务器,这是一种通过直接在模型文本输出中调用工具来扩展LLM功能的方法。与函数调用不同,MCP 将工具定义直接放入上下文窗口,并解析模型的自然语言响应以识别工具使用情况。
特性
- 🔧 完整MCP实现:全方位解析、执行和响应处理。
- 🌤️ 示例工具:具有参数验证的天气和计算器工具。
- 🔄 对话流程:在多次交互中保持上下文。
- 🧩 基于正则表达式的解析:灵活识别工具调用的文本解析方式。
- 🚀 Flask API:用于聊天集成的REST API端点。
项目结构
mcp_server/
├── app.py # 主Flask应用程序
├── mcp_handler.py # MCP解析与执行
├── mcp_example.py # 独立MCP示例
├── requirements.txt # 依赖项
├── tools/ # 工具实现
│ ├── __init__.py
│ ├── weather.py # 天气API工具
│ └── calculator.py # 计算器工具
└── README.md # 本文件
安装说明
-
克隆存储库:
bashgit clone https://github.com/yourusername/mcp-server.git cd mcp-server
-
创建虚拟环境:
bashpython -m venv venv source venv/bin/activate # 在Windows上: venv\Scripts\activate
-
安装依赖项:
bashpip install -r requirements.txt
-
设置环境变量:
bash# 创建一个包含以下内容的 .env 文件: LLM_API_KEY=your_llm_api_key_here WEATHER_API_KEY=your_weather_api_key_here FLASK_APP=app.py FLASK_ENV=development
使用方式
启动服务
启动Flask开发服务器:
bash
flask run
在生产环境中:
bash
gunicorn app:app
API端点
- POST /chat:带有MCP流程的消息处理。
bash
curl -X POST http://localhost:5000/chat \ -H "Content-Type: application/json" \ -d '{ "messages": [ { "role": "user", "content": "波士顿天气如何?" } ] }'
单独使用示例
运行示例脚本查看MCP的实际效果:
bash
python mcp_example.py
运作原理
- 工具注册:工具与其参数和执行逻辑一起注册。
- 工具定义注入:XML格式的工具描述被加入到提示信息中。
- 模型响应处理:正则模式识别出LLM文本输出中的工具调用。
- 工具执行:解析参数并传递给相应的工具处理程序。
- 结果插入:将工具执行的结果插回到响应中。
MCP 与函数调用对比
特性 | MCP | 函数调用 |
---|---|---|
定义位置 | 提示文本内 | API 参数 |
调用格式 | 自然语言 | 结构化JSON |
实现方式 | 文本解析 | API集成 |
可见性 | 在响应中可见 | 可能隐藏 |
平台支持 | 任何基于文本的LLM | 需要API支持 |
示例对话
用户: 波士顿天气如何?
LLM:
让我来检查一下波士顿的天气。
get_weather(location="波士顿, MA", unit="fahrenheit")
处理后:
让我来检查一下波士顿的天气。
get_weather(location="波士顿, MA", unit="fahrenheit")
get_weather的结果:
{
"location": "波士顿, MA",
"温度": 72,
"单位": "fahrenheit",
"条件": "部分多云",
"湿度": 68,
"风速": 5.8
}
添加自定义工具
- 创建一个继承于
Tool
的新类。 - 定义参数和执行逻辑。
- 注册到MCP处理程序中。
示例:
python
class MyTool(Tool):
def __init__(self):
parameters = [
{
"name": "param1",
"type": "string",
"description": "param1的描述",
"required": True
}
]
super().__init__(
name="my_tool",
description="我的工具的描述",
parameters=parameters
)
def execute(self, param1):
# 工具逻辑于此定义
return {"结果": "已处理 " + param1}
MCP配置和调用流
-
工具注册:
- MCP工具被注册到处理程序中。
- 每个工具提供其名称、描述和参数定义。
-
工具定义注入:
- 工具定义被添加到系统消息中。
- MCP遵循XML格式的定义格式。
-
LLM响应处理:
- 大模型生成可能包括工具调用的响应。
- 模式匹配在文本中识别工具调用。
- 工具参数被解析并传递给工具执行方法。
-
工具执行:
- 提供参数来执行工具。
- 结果被注入回会话中。
-
会话管理:
- 处理后的响应(工具结果)被添加到会话历史记录中。
- 来自工具的上下文信息在未来的调用中被包括在内。
示例对话
以下是一个典型的对话示例:
用户: 波士顿的天气如何?
系统: 将包含MCP工具定义的提示发送到LLM
大模型响应:
让我来检查一下波士顿的天气。
get_weather(location="波士顿, MA", unit="fahrenheit")
MCP处理程序: 解析响应,发现工具调用并执行天气工具
工具执行结果:
get_weather的结果:
{
"location": "波士顿, MA",
"temperature": 72,
"unit": "fahrenheit",
"conditions": "部分多云",
"humidity": 68,
"wind_speed": 5.8
}
经处理的响应(发送回用户):
让我来检查一下波士顿的天气。
get_weather(location="波士顿, MA", unit="fahrenheit")
得到结果:
get_weather的结果:
{
"location": "波士顿, MA",
"temperature": 72,
"unit": "fahrenheit",
"conditions": "部分多云",
"humidity": 68,
"wind_speed": 5.8
}
用户: 你能计算144的平方根吗?
大模型响应:
我可以帮你算出这个数字的平方根。
calculator(expression="sqrt(144)")
MCP处理程序: 解析响应,执行计算工具
工具执行结果:
calculator的结果:
{
"expression": "sqrt(144)",
"result": 12.0
}
经处理的响应(发送回用户):
我可以用计算器为您计算结果。
calculator(expression="sqrt(144)")
calculator的结果:
{
"expression": "sqrt(144)",
"result": 12.0
}
144 的平方根为 12。
这展示了完整的MCP工具使用流程,从大模型基于文本的调用,经执行后进行相应的回答处理。
许可证
MIT 许可证
您的支持
欢迎贡献!请自由提交Pull请求。