报告分享 | 模型上下文协议(MCP):实现大模型与外部工具的标准化交互
大模型虽具备卓越的理解、生成与推理能力,但仅靠内部运行或用户指令,难以充分施展其强大潜力。本报告介绍一种模型上下文协议(MCP),以标准化的方式连接大模型与外部工具、数据源等,实现高效、灵活的大模型应用扩展。
1 背景动机
近年来,大语言模型(Large Language Model, LLMs)在自然语言生成、机器翻译、问答和代码生成等复杂任务中取得了显著进展,展现出卓越的性能。然而,这些模型依赖于静态的、预先收集的训练数据集,导致它们在处理与最新发展相关的查询时,可能因缺乏最新信息而产生不准确或不相关的输出,即存在“知识过时”问题。此外,静态模型难以动态适应变化的上下文或有效整合外部实时信息,限制了它们在动态和现实世界应用中的上下文响应能力。
2023 年,OpenAI 引入函数调用功能,使语言模型能够以结构化方式调用外部 API,从而扩展了其能力,能够检索实时数据、执行计算和与外部系统交互。LangChain 和 LlamaIndex 等框架提供了标准化的工具接口,进一步促进了 AI 模型与外部服务的集成。尽管取得了这些进展,工具集成仍然存在碎片化问题,开发者需要手动定义接口、管理认证和处理每个服务的执行逻辑,不同平台的函数调用机制各不相同,增加了复杂性。
AI 应用与外部工具的集成主要依赖于以下几种方法:
- 手动 API 连接:开发者需要为每个外部工具或服务手动配置 API 连接,导致了系统的紧耦合和难以扩展。
- 标准化插件接口:如 OpenAI 的 ChatGPT 插件,简化了与外部工具的连接,然而这些插件通常是一单向的,且限制了跨平台的兼容性。
- AI 代理工具集成:框架如 LangChain 提供了结构化的方式,但这种集成方式仍然需要手动配置和维护,复杂度随工具数量增加。
- RAG 和向量数据库:通过向量搜索从知识库中检索相关信息,虽然解决了知识过时问题,但仅限于被动信息检索,无法执行主动操作。
2024 年,Anthropic 引入了模型上下文协议(Model Context Protocol, MCP),这是一个旨在标准化 AI 与工具交互的通用协议。MCP 受语言服务器协议(Language Server Protocol, LSP)启发,提供了一个灵活的框架,使 AI 应用能够动态地与外部工具通信,简化了 AI 应用的开发,并提高了其处理复杂工作流的灵活性。它提供一个统一的接口,使得 LLMs 能够以标准化的方式与各种数据源和工具进行交互,类似于 USB-C 接口在设备连接中的作用。
2 MCP 核心架构
MCP 架构由三个核心组件构成:MCP 主机、MCP 客户端和 MCP 服务器,它们协同工作,实现 AI 应用与外部工具和数据源的无缝交互。
- MCP 主机:提供 AI 应用的运行环境,集成交互工具和数据,支持与外部服务的通信。例如,Claude Desktop 和 VSCode 插件 Cline 等工具通过 MCP 主机与外部资源交互。
- MCP 客户端:作为中介,管理 MCP 主机与 MCP 服务器之间的通信,处理请求和响应,确保交互的顺畅性。它还负责实时更新任务进度和系统状态,并优化工具使用和性能。
- MCP 服务器:提供外部工具、数据源和预定义工作流模板,使 AI 模型能够执行操作和访问数据。它支持工具的自主发现和调用,增强了 AI 应用的灵活性和效率。
在传输层,MCP 支持多种传输机制,以适应不同的应用场景和需求。具体来说,它支持以下两种主要的传输方式:
- 标准输入/输出(Stdio):适用于本地和基于命令行的交互,特别适合在同一台机器上运行的场景。这种传输方式简单高效,适合对延迟要求较低且不需要复杂网络通信的场景。
- HTTP 与服务器发送事件(Server-Sent Events, SSE):适用于远程交互和流式场景,利用广泛采用的 Web 标准。SSE 则允许服务器向客户端发送实时更新,适合需要实时数据交互的应用。
MCP 的连接生命周期主要有以下几个阶段:
- 客户端发送 initialize 请求:客户端向服务器发送 initialize 请求,其中包含协议版本和客户端的能力信息。
- 服务器响应 initialize 请求:服务器收到客户端的 initialize 请求后,会返回其协议版本和服务器的能力信息作为响应。
- 客户端发送 initialized 通知:客户端收到服务器的响应后,发送 initialized 通知作为确认,表明初始化过程完成。
- 开始正常消息交换:初始化完成后,客户端和服务器之间就可以开始正常的请求-响应或通知等消息交换了。
MCP 协议定义了四种主要的消息类型,这些消息类型确保了客户端和服务器之间的高效、结构化和可靠的通信。
- 请求(Requests):客户端向服务器发送请求,期望得到响应。
interface Request {method: string;params?: { ... };
}
- 结果(Results):服务器对客户端请求的成功响应。
interface Result {[key: string]: unknown;
}
- 错误(Errors):服务器对客户端请求的失败响应。
interface Error {code: number;message: string;data?: unknown;
}
- 通知(Notifications):单向消息,不需要响应。
interface Notification {method: string;params?: { ... };
}
3 MCP 服务器
MCP 服务器是 MCP 架构中的关键组件,它为 AI 模型提供了与外部系统和资源进行交互的能力。MCP 服务器通过三种核心能力实现这一目标:工具(Tools)、资源(Resources)和提示(Prompts)。这些能力使得 AI 模型能够动态地发现、选择和执行外部工具,访问数据资源,并优化工作流。
-
工具(Tools):MCP 服务器的核心功能之一,允许 AI 模型调用外部服务和 API 来执行操作。这些工具可以是任何可以被 API 调用的服务,例如查询数据库、发送邮件或更新 CRM 记录。AI 模型可以根据任务上下文自主选择和调用适当的工具,而无需预先定义工具映射。
-
资源(Resources):允许 MCP 服务器向 AI 模型暴露结构化和非结构化的数据集,这些数据集可以来自本地存储、数据库或云平台。当 AI 模型请求特定数据时,MCP 服务器可以检索并处理相关数据,使得模型能够基于最新数据做出决策。
-
提示(Prompts):提示是预定义的模板和工作流,用于优化 AI 模型的响应并简化重复性任务。提示模板可以包含动态参数,这些参数可以根据用户的输入或上下文进行调整,使得 AI 模型能够灵活地处理不同的任务。例如,一个客户支持的聊天机器人可以使用提示模板来提供统一和准确的响应。
官方开源的 python-sdk 项目可以用于创建 MCP 服务器,暴露应用提供的工具、资源和提示等接口。本报告演示项目中提供的 echo 例子,使用 uv 作为 Python 项目的管理工具。
- 克隆项目到本地:
git clone https://github.com/modelcontextprotocol/python-sdk.git
- 进入官方提供的服务示例所在目录:
cd python-sdk/examples/fastmcp
- 以开发者模式添加项目依赖:
uv add --dev "mcp[cli]"
- 使用官方提供的 MCP 检查器进行调试:
uv run mcp dev echo.py
根据终端的输出,MCP 检查器可通过链接http://127.0.0.1:6274访问。
4 MCP 客户端
MCP 客户端在 MCP 架构中扮演着中介的角色,它运行在 MCP 主机环境中,管理 MCP 主机与一个或多个 MCP 服务器之间的通信。当前对于 MCP 客户端定义了两个关键的概念。
-
根(Roots):定义了逻辑边界,指示服务器预期操作的范围或上下文,为服务器提供操作的上下文和资源访问的指导。确保服务器的操作严格限制在指定的资源边界内,避免访问无关资源。
-
采样(Sampling):允许服务器直接通过客户端向 LLMs 发起推理请求,动态获取模型生成的补全内容。这一机制对于开发复杂的、交互式的、上下文感知的智能代理工作流至关重要。
同样,在项目路径 python-sdk/examples/clients/simple-chatbot/mcp_simple_chatbot/main.py
文件中,定义了大模型的聊天应用,将外部工具与大模型整合,在系统提示词中嵌入了配置好的工具列表。工具集成的逻辑如下:
- 从 MCP 服务器动态发现工具。
- 工具描述自动包含在系统提示中。
- 工具执行通过标准化的 MCP 协议处理。
当应用接收到用户输入时,大模型聊天应用的运行时流程为:
- 接收用户输入。
- 将输入连同可用工具的上下文一起发送给 LLM。
- 解析 LLM 的响应:
- 如果是工具调用 → 执行工具并返回结果。
- 如果是直接响应 → 返回给用户。
- 将工具结果发送回 LLM 进行解释。
- 将最终响应呈现给用户。
5 MCP 主机应用
官方编写了一些实用的 MCP 服务器,以及列举了第三方的 MCP 服务器以供检索,开源在 MCP servers 仓库中。本报告使用 Claude Desktop 来使用测试 MCP 主机的功能,借助 docker 容器来运行 MCP 服务器,并分别举例Time
,Filesystem
,Fetch
工具。
- Time MCP Server
一个提供时间和时区转换功能的 MCP 服务器,其可用工具包括get_current_time
和convert_time
,分别用于获取特定时区的当前时间以及在时区之间转换时间。Claude.app 配置和使用效果如下。
"mcpServers": {"time": {"command": "docker","args": ["run", "-i", "--rm", "mcp/time"]}
}
- Filesystem MCP Server
一个用于文件系统操作的 MCP 服务器,支持文件的读取和写入操作,可以创建新目录、列出目录内容以及删除目录,还支持在指定路径下搜索文件,获取文件的相关信息,如大小、修改时间等。Claude.app 配置和使用效果如下。
"mcpServers": {"filesystem": {"command": "docker","args": ["run", "-i", "--rm", "--mount","type=bind,src=C:/Users/yinha/Works,dst=/projects/Works","mcp/filesystem", "/projects/Works"]}
}
- Fetch MCP Server
一个提供网页内容抓取功能的 MCP 服务器,能够从网页中检索和处理内容,将 HTML 转换为 Markdown 格式,抓取工具会对响应内容进行截断。
"mcpServers": {"fetch": {"command": "docker","args": ["run", "-i", "--rm", "mcp/fetch"]}
}
6 潜在安全风险
论文 Landscape 详细分析了 MCP 服务器在其生命周期中面临的安全和隐私风险,并根据不同阶段做了如下总结。
- 创建阶段
- 名称冲突:恶意服务器可能伪装成合法服务器欺骗用户。
- 安装程序伪装:攻击者可能篡改安装程序,引入恶意代码。
- 代码注入/后门:恶意代码可能嵌入服务器代码库。
- 运行阶段
- 工具名称冲突:多个工具可能共享相同名称,导致 AI 应用调用错误工具。
- 斜杠命令重叠:多个工具可能定义相同命令,导致执行歧义。
- 沙箱逃逸:恶意工具可能突破沙箱隔离,访问主机系统。
- 更新阶段
- 权限持久化:更新后旧权限可能未撤销,导致权限滥用。
- 重新部署易受攻击的版本:用户可能回滚到旧版本,引入已修复的漏洞。
- 配置漂移:系统配置可能偏离安全基线,引入安全漏洞。
学习笔记
当前 MCP 还处于发展阶段,其生态也正在构建当中。或许它可以让大模型成为中枢和桥梁,将各种强大的工具紧密联结在一起,实现有机协同。此外,一旦各种工具开放面向大模型的服务接口,还需要深入考虑网络传输以及认证方面的安全问题,类似于 HTTPS 协议之于 HTTP 协议。