MCP

月伴飞鱼 2025-04-01 10:09:33
AI相关 > AI技术
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

MCP,全称是Model Context Protocol,模型上下文协议。

从本质上来说,MCP是一种技术协议,一种智能体 Agent 开发过程中共同约定的一种规范。

总的来说,MCP解决的最大痛点,就是Agent开发中调用外部工具的技术门槛过高的问题。

由于底层技术限制,大模型本身是无法和外部工具直接通信的。

因此Function calling的思路,就是创建一个外部函数(Function)作为中介,一边传递大模型的请求,另一边调用外部工具。

最终让大模型能够间接的调用外部工具。

image.png

例如,当我们要查询当前天气时,让大模型调用外部工具的Function Calling的过程就如图所示:

image.png

Function Calling唯一的问题就是,编写这个外部函数的工作量太大了,一个简单的外部函数往往就得上百行代码。

而且,为了让大模型认识这些外部函数,我们还要额外为每个外部函数编写一个JSON Schema格式的功能说明。

此外,我们还需要精心设计一个提示词模版,才能提高Function Calling响应的准确率。

  • 而MCP的目标,就是能在Agent开发过程中,让大模型更加便捷的调用外部工具。

为此,MCP提出了两个方案,其一,统一Function Calling的运行规范。

  • 首先是先统一名称,MCP把大模型运行环境称作 MCP Client,也就是MCP客户端。

同时,把外部函数运行环境称作MCP Server,也就是MCP服务器,

image.png

统一MCP客户端和服务器的运行规范,并且要求MCP客户端和服务器之间,也统一按照某个既定的提示词模板进行通信。

  • 可以避免MCP服务器的重复开发,也就是避免外部函数重复编写。

例如,像查询天气、网页爬取、查询本地MySQL数据库这种通用的需求。

大家有一个人开发了一个服务器就好,开发完大家都能复制到自己的项目里来使用,不用每个人每次都单独写一套。

GitHub上就出现了海量的已经开发好的MCP 服务器,从SQL数据库检索、到网页浏览信息爬取。

从命令行操作电脑、到数据分析机器学习建模,等等等等,不一而足。

只要你本地运行的大模型支持MCP协议,也就是只要安装了相关的库,仅需几行代码即可接入这些海量的外部工具。

MCP,Model Context Protocol,就是一种旨在提高大模型Agent开发效率的技术协议。

为了进一普及MCP协议,Anthropic还提供了一整套MCP客户端、服务器开发的SDK,也就是开发工具。

支持Python、TS和Java等多种语言,借助SDK,仅需几行代码,就可以快速开发一个MCP服务器。

MCP初体验

下载并安装 Claude for Desktop,注册并登录账号后,确保 Claude 能正常对话。

打开 Settings -> Developer 配置页面。

点击 Edit Config 按钮,进入 Claude 配置文件所在目录,打开 claude_desktop_config.json 配置文件,输入如下内容。

{
    "mcpServers": {
        "filesystem": {
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "/Users/aneasystone/Downloads/demo"
            ]
        }
    }
}

这是官方开发的 Filesystem MCP Server,用于操作你的本地文件。

  • 比如读取、编辑、搜索等。

最后一个参数是文件路径,表示只允许 Claude 访问这个目录,可以添加一个或多个。

配置好 Filesystem MCP Server 之后,重启 Claude Desktop 应用。

  • Claude Desktop 在启动时会自动加载所有的 MCP Server。

其实就是为每个 Server 启动一个独立的进程,运行配置文件中的命令。

加载成功后,在对话框右下角会看到一个小锤子的图标。

点击小图标,可以看到 Filesystem MCP Server 自带的所有工具列表。

MCP开发者指南

官方目前提供了 PythonTypeScriptJavaKotlin 四种 SDK 供开发者选择。

MCP Server 可以提供三种主要类型的能力:

安装 mcp[cli] 依赖:

$ pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ mcp[cli]

创建 mcp-server-weather.py 文件:

from mcp.server.fastmcp import FastMCP
 
mcp = FastMCP("weather")
 
@mcp.tool()
async def get_weather(city: str, date: str) -> str:
    """查询某个城市某个日期的天气.
 
    Args:
        city: 城市名称
        date: 日期
    """
    return '天气晴,气温25摄氏度'
 
if __name__ == "__main__":
    mcp.run(transport='stdio')

先通过 FastMCP 初始化 MCP Server,然后通过 @mcp.tool() 注解定义工具,最后通过 mcp.run() 启动 MCP Server。

其中 transport 参数表示传输协议的类型,决定了客户端如何和 MCP Server 通信,MCP 默认支持两种传输协议

标准输入和输出 (stdio):

  • 通过标准输入和输出流进行通信,这对本地集成和命令行工具特别有用。

服务器发送事件 (SSE):

  • 通过 HTTP POST 请求支持客户端与服务器之间的流式通信。

探索 MCP Server

网上还有大量的 MCP Server 开箱即用,可以用于文件处理、数据分析、软件开发、浏览器自动化、沟通提效等等。

  • 这些官网提供的 例子 可以作为很好的入门。

此外,社区也有不少人将各种 MCP Server 收集在一起:

MCP Client

目前已经有很多客户端集成了 MCP,比如 CursorClineLibreChatRoo CodeWindsurf Editor 等。

官方有一个 已集成 MCP 的应用列表

MCP Inspector

MCP Inspector 是一个用于测试和调试 MCP Server 的交互式开发工具。

使用下面的命令启动 MCP Inspector:

$ npx -y @modelcontextprotocol/inspector python3 /path/to/mcp-server-weather.py

注意参数的后面是我们的 MCP Server 的启动命令。

启动成功后,在浏览器输入 http://localhost:5173 就可以访问了。

在页面左下方,可以查看调试的历史记录。

基本原理

根据 MCP 的规范,为了确保适当的功能协商和状态管理,MCP Client 和 MCP Server 之间的通信遵循严格的 生命周期

整个生命周期可以分成三个阶段:初始化阶段、操作阶段和关闭阶段。

MCP Client 向 MCP Server 发送请求,属于操作阶段。

  • 在进入操作阶段之前,必须先执行初始化。

整个初始化的过程有点类似 TCP 的三次握手,首先,发送初始化消息。

{"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}

如果初始化成功,可以得到类似这样的消息。

{"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"weather","version":"1.4.1"}}}

接着再发送初始化完成消息。

{"method":"notifications/initialized","jsonrpc":"2.0"}

三次握手之后,就算初始化完成了。

接下来就可以发送请求了,比如调用工具。

{"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"合肥", "date":"明天"}},"jsonrpc":"2.0","id":2}

消息协议

JSON-RPC 2.0

在MCP中规定了唯一的标准消息格式,就是JSON-RPC 2.0。

JSON-RPC 2.0是一种轻量级的、用于远程过程调用(RPC)的消息交换协议,使用JSON作为数据格式。

  • 它不是一个底层通信协议,只是一个应用层的消息格式标准。

JSON-RPC2.0就约束了你给Server的消息必须遵循以下格式:

{
    "jsonrpc": "2.0", // 协议版本,固定为 "2.0"
    "method": "calculate", // 要调用的方法名
    "params": { // 方法参数,可以是对象或数组
        "expression": "5+3"
    },
    "id": 1                  // 请求标识符,用于匹配响应
}

而当MCP Server处理完成,JSON-RPC又约束了回复的消息必须长这样:

{
  "jsonrpc": "2.0", // 协议版本
  "result": 8,         // 调用结果
  "id": 1                  // 对应请求的标识符
}

这样两边就非常和谐的完成了一次请求处理。

在实际的JSON-RPC 2.0规范中,还规定了通知类消息的格式、异常时的标准错误代码等。

传输协议

MCP采用了带有SSE(Server-Sent Events)的HTTP协议作为Remote模式下的传输方式。

SSE(服务器发送事件) 是一种基于HTTP协议的单向通信技术,允许服务器主动实时向客户端推送消息。

  • 客户端只需建立一次连接即可持续接收消息。

它的特点是:

  • 单向(仅服务器→客户端)
  • 基于HTTP协议,一般借助一次HTTP Get请求建立连接
  • 适合实时消息推送场景(如进度更新、实时数据流等)

其基本通信过程如下:

image.png

MCP的HTTP With SSE模式

由于SSE是一种单向通信的模式,所以它需要配合HTTP Post来实现客户端与服务端的双向通信。

严格的说,这是一种HTTP Post(客户端->服务端) + HTTP SSE(服务端->客户端)的伪双工通信模式。

这种传输模式下:

  • 一个HTTP Post通道,用于客户端发送请求。
    • 比如调用MCP Server中的Tools并传递参数,注意,此时服务端会立即返回。
  • 一个HTTP SSE通道,用于服务端推送数据,比如返回调用结果或更新进度。
  • 两个通道通过Session_ID来关联,而请求与响应则通过消息中的ID来对应。

一次完整的会话过程用下图表示:

image.png

连接建立

  • 客户端首先请求建立 SSE 连接,服务端同意,然后生成并推送唯一的Session ID。

请求发送

  • 客户端通过 HTTP POST 发送 JSON-RPC2.0 请求(请求中会带有Session ID 和Request ID信息)。

请求接收确认

  • 服务端接收请求后立即返回 202 (Accepted) 状态码,表示已接受请求。

异步处理

  • 服务端应用框架会自动处理请求,根据请求中的参数,决定调用某个工具或资源。

结果推送

  • 处理完成后,服务端通过 SSE 通道推送 JSON-RPC2.0 响应,其中带有对应的Request ID。

结果匹配

  • 客户端的SSE连接侦听接收到数据流后,会根据Request ID 将接收到的响应与之前的请求匹配。

重复处理:

  • 循环2-6这个过程,这里面包含一个MCP的初始化过程。

连接断开:

  • 在客户端完成所有请求后,可以选择断开SSE连接,会话结束。

简单总结:通过HTTP Post发送请求,但通过SSE的长连接异步获得服务端的响应结果。

在最新的MCP标准(2025-03-26版)中,对目前的传输方式做了调整,改名为Streamable HTTP。

其主要变动在于允许在MCP Server端根据自身需要来选择:

  • 你可以选择简单的无状态模式,也可以按需选择支持目前的HTTP With SSE模式。

这给予了开发者更大的选择权,具体包括:

  1. 移除了专门的/sse端点,所有通信都通过单一/message端点进行。
  2. 任何 HTTP POST 请求都可被服务器按需升级为 SSE 流(不再强制)。
    1. 客户端也可通过GET 请求初始化 SSE 流(目前模式)。
  3. 服务器支持完全无状态部署。
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!