前言
早期 GPT 系列依赖静态训练数据,存在 “孤岛式” 特性,在实际应用中无法理解用户历史上下文、调用外部工具或动态更新知识库。
随着 AI 应用场景复杂化,定制化 API 或插件连接模型与外部数据源的方式带来集成挑战,存在重复劳动、维护成本高、系统扩展性受限等问题。
如今,AI 发展进入新阶段,业界关注模型从 “被动回答” 转向 “主动执行”,需要标准化协议来打破数据孤岛、简化集成流程。
开源社区和企业对 AI 生态互操作性要求提高,Hugging Face 平台推动模型共享,LangChain 框架尝试工具调用增强模型能力,但都缺乏通用标准化的上下文传递机制。
2024 年 11 月,Anthropic 公司基于自身在可解释性和安全 AI 系统方面的专长,推出并开源了模型上下文协议(MCP),以解决上述问题。
一、什么是MCP?
MCP(Model Context Protocol,模型上下文协议),它像USB-C接口一样统一了AI与外部世界的连接标准。
想象一下:你的智能体(Agent)或大模型(LLM)原本被困在封闭房间,想使用某个工具需要单独给他开个窗口来获取工具的能力,但MCP却为它打开了连接数据库、开发软件如git、文件操作等工具的任意门,是不是有点科幻?
在 MCP 架构中,主机(Host)是可承载 AI 交互环境的应用程序,如 Claude Desktop、Cursor 等主流 AI 工具。他们不仅为用户提供与 AI 模型互动平台,还负责集成外部工具、访问多样数据资源,通过运行 MCP 客户端可以实现协议核心功能。
简单来说我们可以通过claude提供的sdk,集成MCP客户端进我们的软件中,即可实现MCP的使用。
而至于如何让大模型可以调用我们的服务,开发者只需要开发一个MCP Server,然后在具有MCP Client功能的平台配置即可使用,常用如Claude Desktop App、Cline、Cherry-studio。当然你也可以自己开发一个MCP Client。
二、MCP揭秘 🔍
MCP 的核心思想是将模型与外部系统之间的通信抽象为一个客户端-服务器架构,通过标准化的接口(如基于 JSON-RPC 的通信)实现上下文的动态传递和工具的灵活调用。
JSON-RPC(JSON Remote Procedure Call)是一种基于JSON格式的轻量级远程过程调用协议。我们常用的REST是通过URL来进行Get、Post操作资源的,而它是通过一个json把函数和参数都定义好发送给对方即可。
Anthropic 在发布时提供了初步的规范和 SDK(如 Python 和 TypeScript)具体来看一下官方代码,如何创建一个客户端:
以NodeJs为例,我们直接看官网的实例中的processQuery函数,地址放在下方,如下图所示,代码已经非常清晰地描述了通讯逻辑:
案例:https://modelcontextprotocol.io/quickstart/client#node
用一个时序图可以描述这个顺序:
走到这里,我们发现MCP只剩下一个秘密,那就是MCP Client是怎么调用MCP Server的?搞清楚这点,MCP就清晰了。
模型上下文协议 (MCP) 支持 Mcp客户端和 MCP 服务器之间通信主要有两种传输机制:
- 标准输入/输出 (STDIO)
- 服务器发送事件 (SSE)
每种方法都有不同的特征、优势和用例。
STDIO
工作原理:
- 客户端作为一个子进程启动MCP服务器。
- 通信通过进程流进行:客户端写入服务器的STDIN,服务器在STDOUT上响应。
- 每条消息以换行字符分隔。
- 消息格式为JSON-RPC 2.0。
特点:
- 本地性:在与客户端相同的机器上运行。
- 性能:非常低的延迟和开销(无需网络栈)。
- 简单性:直接进程通信,无需网络配置。
- 关系:客户端和服务器之间的一对一关系。
- 安全性:由于没有网络暴露,更安全。
使用场景:
- 本地集成和在同一机器上运行的工具。
- 安全敏感的操作。
- 低延迟需求。
- 单客户端场景。
- 命令行工具或IDE扩展。
实现示例:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'local-server',
version: '1.0.0'
});
// 注册工具...
// 使用STDIO传输
const transport = new StdioServerTransport(server);
transport.listen();
SSE
工作原理:
- 客户端通过HTTP GET请求连接到服务器的SSE端点。
- 建立一个持久连接,服务器可以向客户端推送事件。
- 对于客户端到服务器的通信,客户端通过HTTP POST请求向另一个端点发送消息。
- 通信通过两个通道进行:
- 事件流(GET):服务器到客户端的更新。
- 消息端点(POST):客户端到服务器的请求。
特点:
- 远程访问:可以在与客户端不同的机器上托管。
- 可扩展性:可以并发处理多个客户端连接。
- 协议:通过标准HTTP协议工作(不需要特殊协议)。
- 持久性:维护一个用于服务器到客户端消息的持久连接。
- 认证:可以使用标准HTTP认证机制。
使用场景:
- 跨网络远程访问。
- 多客户端场景。
- 公共服务。
- 需要多个用户访问的集中式工具。
- 与Web服务的集成。
实现示例:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import express from 'express';
const app = express();
const server = new Server({
name: 'remote-server',
version: '1.0.0'
});
// 注册工具...
// 使用SSE传输
const transport = new SSEServerTransport(server);
app.use('/mcp', transport.requestHandler());
app.listen(3000, () => {
console.log('MCP server listening on port 3000');
});
选择STDIO还是SSE?
客户端一般两者都支持,我们仅需在意Mcp Server用什么方式。如果你希望本地运行,考虑安全场景,不对外部开放的话,那STDIO就可以了。如果你希望你的Server为多个用户(客户端)使用,那就毫无疑问选择SSE即可,后续升级更新都是保持同步的。
考虑因素 | STDIO | SSE |
---|---|---|
位置 | 仅限本地机器 | 本地或远程 |
客户端 | 单个客户端 | 多个客户端 |
性能 | 低延迟 | 高延迟(网络开销) |
设置复杂性 | 较简单 | 较复杂(需要HTTP服务器) |
安全性 | 本质上更安全 | 需要显式的安全措施 |
网络访问 | 不需要 | 需要 |
可扩展性 | 仅限本地机器 | 可以在网络中分发 |
部署 | 每用户安装 | 集中安装 |
更新 | 分布式更新 | 集中更新 |
资源使用 | 使用客户端资源 | 使用服务器资源 |
依赖 | 客户端依赖 | 服务器依赖 |
三、总结 🛠️
引文:
- https://norahsakal.com/blog/mcp-vs-api-model-context-protocol-explained/(图2)
- https://x.com/akshay_pachaar/status/1900456268084764689(图4)
- https://docs.roocode.com/features/mcp/server-transports#how-stdio-transport-works
我发现很多博文的动图和图片做的都很好,后续会专门开一期分享热点技术的图和来源。除上述列举,其他图为本人制作。
这里是GIS宇宙,我们下期再见!
本人其他平台账号:
- 微信公众号:GIS宇宙
- CSDN:GIS_宇宙
- 知乎:GIS宇宙
- 掘金:GIS宇宙