返回市场
MCP服务器

MCP服务器

作者:yisu2015062 星标更新:2025-03-26

项目介绍

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               # 此文件

安装

  1. 克隆仓库:

    git clone https://github.com/yourusername/mcp-server.git
    cd mcp-server
    
  2. 创建虚拟环境:

    python -m venv venv
    source venv/bin/activate  # 在Windows上:venv\Scripts\activate
    
  3. 安装依赖项:

    pip install -r requirements.txt
    
  4. 设置环境变量:

    # 创建一个.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开发服务器:

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

工作原理

  1. 工具注册:工具根据其参数和执行逻辑进行注册
  2. 工具定义注入:XML格式的工具描述被添加到提示中
  3. LLM响应处理:正则表达式模式识别LLM文本输出中的工具调用
  4. 工具执行:参数被解析并传递给适当的工具处理器
  5. 结果注入:工具执行的结果被插入回响应中

MCP与函数调用对比

功能MCP函数调用
定义位置在提示文本中在API参数中
调用格式自然语言结构化JSON
实现方式文本解析API集成
可见性在响应中可见可能隐藏
平台支持任何基于文本的LLM需要API支持

示例对话

用户:波士顿的天气怎么样?

LLM

我将为您查询天气。

get_weather(location="Boston, MA", unit="fahrenheit")

处理后

我将为您查询天气。

get_weather(location="Boston, MA", unit="fahrenheit")

get_weather的结果:
{
  "location": "Boston, MA",
  "temperature": 72,
  "unit": "fahrenheit",
  "conditions": "部分多云",
  "humidity": 68,
  "wind_speed": 5.8
}

添加您自己的工具

  1. 创建一个新的继承自Tool的类
  2. 定义参数和执行逻辑
  3. 注册到MCP处理器

示例:

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 {"result": "处理了 " + param1}

MCP配置和调用流程

  1. 工具注册

    • MCP工具被注册到处理器
    • 每个工具提供其名称、描述和参数定义
  2. 工具定义注入

    • 工具定义被添加到系统消息中
    • 格式遵循MCP的XML结构
  3. LLM响应处理

    • LLM生成可能包含工具调用的响应
    • 模式匹配识别文本中的工具调用
    • 工具参数被解析并传递给工具执行方法
  4. 工具执行

    • 工具根据提供的参数执行
    • 结果被注入回对话中
  5. 对话管理

    • 包含工具结果的处理响应被添加到对话历史记录中
    • 未来的LLM请求包括此历史记录以供上下文使用

示例对话

这里是一个对话示例:

用户:波士顿的天气怎么样?

系统向LLM发送包含MCP工具定义的提示

LLM响应

我将为您查询天气。

get_weather(location="Boston, MA", unit="fahrenheit")

MCP处理器解析响应,找到工具调用并执行天气工具

工具执行结果

get_weather的结果:
{
  "location": "Boston, MA",
  "temperature": 72,
  "unit": "fahrenheit",
  "conditions": "部分多云",
  "humidity": 68,
  "wind_speed": 5.8
}

处理后的响应(发送给用户):

我将为您查询天气。

get_weather(location="Boston, MA", unit="fahrenheit")

get_weather的结果:
{
  "location": "Boston, MA",
  "temperature": 72,
  "unit": "fahrenheit",
  "conditions": "部分多云",
  "humidity": 68,
  "wind_speed": 5.8
}

用户:你能计算一下144的平方根吗?

LLM响应

我可以为您计算这个。

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工具使用的完整流程,从LLM的文本调用到执行和响应处理。

许可证

MIT

贡献

欢迎贡献!请随时提交Pull Request。