探索人工智能中的模型上下文协议 (MCP)
2025年03月18日 由 alex 发表
3682
0
模型上下文协议(MCP)简介
模型上下文协议(MCP)是一种开放标准,旨在将人工智能助手与实际存储数据的系统连接起来,这些系统包括内容存储库、业务工具以及开发环境。本质上,MCP 在大型语言模型(LLM)应用和外部数据或功能之间创建了一个通用接口。Anthropic(Claude AI 助手背后的团队)于 2024 年底推出了 MCP,以解决人工智能领域日益增长的集成挑战。开发者无需为每个数据库、API 或知识库构建一次性插件或自定义连接器,而是可以使用 MCP 作为一种通用协议,任何人工智能应用(客户端)和任何数据源(服务器)都能理解该协议。这极大地简化了人工智能系统获取上下文(相关信息)并代表用户执行操作的方式。
可以将 MCP 比作人工智能应用的“USB-C 接口”——一种标准化的即插即用接口,用于连接到各种工具和数据。就像 USB-C 让许多设备无论制造商如何都能互操作一样,MCP 定义了通用规则,让任何基于 LLM 的客户端都能与任何符合 MCP 标准的服务器进行通信。这种标准化与语言服务器协议(LSP)对编程环境所做的贡献相媲美:LSP 允许任何代码编辑器通过通用协议支持任何编程语言,将 M×N 的集成问题转变为 M+N。
关键在于减少需要管理的直接交互数量。在 M×N 的集成设置中,第一组的每个组件都必须与第二组的每个组件连接,从而产生 M×N 对。相比之下,当将其转变为基于 M+N LSP 的方法时,你可以让 M 个组件和 N 个组件中的每一个都与一个集中式的协议(即语言服务器协议)通信。这意味着你只需要管理 M+N 个连接,而不是每一个可能的配对。
类似地,MCP 将复杂的自定义人工智能集成转变为一个更易管理的生态系统——人工智能助手和数据/服务只需实现一次 MCP 即可相互协作。目标是实现更相关、更及时的人工智能(访问实时数据),以及一个更可持续的集成生态系统,其中一个 MCP 服务器的改进将使所有兼容客户端受益。

MCP 的关键组件
MCP 的设计遵循客户端-服务器架构,清晰地区分了人工智能应用和数据连接器的角色。该架构中的关键组件包括:
- MCP 主机(AI 应用)——需要外部信息或功能的人工智能(AI)或大型语言模型(LLM)驱动的应用。主机可以是聊天机器人、集成开发环境(IDE)或任何嵌入了 LLM 的工具。例如,Claude Desktop、类似 Cursor 的代码编辑器或聊天机器人界面都可以作为 MCP 主机。主机负责协调 LLM 的操作、管理多个连接,并将 AI 输出与检索到的上下文合并。它通常集成一个或多个 MCP 客户端。
- MCP 客户端——客户端是主机应用中的一个组件(通常是库或进程),管理与 MCP 服务器之间的 1:1 连接。每个数据源或工具都有其自己的客户端实例。客户端处理与服务器的所有消息交换,路由请求/响应,并跟踪服务器的能力。它们还处理会话细节,如初始化连接和与服务器协商功能。
- MCP 服务器——服务器是轻量级程序或服务,通过 MCP 接口暴露特定的数据或功能。服务器可以封装本地资源(如文件系统或数据库)或远程服务(如 Slack、Gmail、GitHub 等)。每个服务器以标准化的方式提供一种或多种功能,因此任何 MCP 客户端都可以查询或调用它们。这样,主机无需为 Google Drive、Slack 或 SQL 数据库等定制代码,因为它们各自可以有一个 MCP 服务器,主机只需通过 MCP 与它们通信。早期的服务器示例包括 Google Drive、Slack、Git 存储库、Postgres 数据库等的连接器。
- MCP 协议(基础协议)——这是客户端和服务器用于通信的语言和规则。MCP 使用 JSON-RPC 2.0 作为消息格式,加上一组定义好的方法和消息类型用于常见任务(初始化、列出功能、调用工具等)。通信可以通过不同的传输方式进行——通常是标准输入输出流(stdio,用于主机启动的本地服务器)或带有服务器发送事件(SSE)的 HTTP(用于远程服务器)。协议层处理消息的编码、交换以及会话管理(如保持连接开放以处理多个请求)。
MCP 功能(特性):
MCP 服务器究竟可以暴露什么?协议定义了服务器可以向 AI 模型提供的三类主要功能:
- 资源——模型可以检索作为上下文的只读数据。资源就像文件或文档:它们有模型可以读取的内容,但获取它们不应触发繁重的计算或副作用。示例包括文档文本、数据库记录内容、维基页面或任何由统一资源标识符(URI)标识的静态内容。在 MCP 中,资源通常通过类似 URI 的标识符引用(例如,服务器可能定义资源 users://{id}/profile,以通过 ID 获取用户配置文件)。客户端可以请求资源,服务器返回内容以插入到 LLM 的上下文(提示)中。资源使 AI 基于真实数据——模型可以按需提供最新信息,而不是仅依赖模型的训练。
- 工具——模型可以调用(通常在用户允许的情况下)的可执行函数或操作。工具让 AI 能够做的不仅仅是读取数据:它们可以执行计算、查询 API、发送消息、更新记录等。每个工具都定义有名称、描述和输入模式,指定它期望的参数。例如,服务器可能有一个工具 get_weather(latitude, longitude),它返回给定坐标的当前天气。AI 模型可以在需要时决定调用此工具——类似于 LLM 使用计算器或调用 API。工具很强大,因为它们支持代理行为:AI 可以作为代理,不仅进行聊天,还通过这些函数与其他系统交互。为了安全起见,客户端/主机通常会在执行前要求用户批准工具使用。与资源不同,工具可能有副作用或繁重的计算。
- 提示——预定义的提示模板或对话工作流程,帮助模型完成专门任务。可以将提示视为罐装指导或多轮模板,在需要时可以注入。例如,服务器可能提供代码审查或调试错误的提示模板,结构化模型对话的进行方式。使用提示模板确保 AI 遵循某种模式——就像使用标准表单或脚本一样——这可以为该任务产生更一致的结果。提示本质上让服务器提供最佳实践指令,因此用户或客户端无需每次从头开始制定。
这三种功能类型并不是严格的孤岛——最终,它们都只是将信息供应到模型的上下文窗口(通常为文本)。然而,区分它们有助于客户端适当处理它们(例如,工具需要传递参数和用户批准,而资源则作为内容获取和插入)。在实践中,许多 AI 集成非常注重工具(因为工具支持主动操作),但资源和提示对于提供被动上下文和指导同样重要。
用例和优势
MCP 的标准化方法为人工智能开发带来了一系列实际优势。以下是采用 MCP 的一些关键用例和优点:

总结来说,MCP(模型控制平面)的优势在于使AI系统更强大且更易构建。它为AI解锁了更丰富的功能(借助实时、上下文数据),同时减轻了希望添加这些功能的开发人员的负担。随着MCP生态系统的发展,我们可能会看到更具创意的代理行为(因为模型可以动态发现新工具)以及更多组织信任并集成AI到其工作流程中(这得益于MCP提供的安全性和控制力)。
技术细节:MCP架构和工作流程
深入探究,让我们来了解一下MCP在幕后是如何工作的——从客户端和服务器之间的初始握手到它们交换数据的方式。MCP通信基于JSON-RPC 2.0,这是一种使用JSON的轻量级RPC(远程过程调用)格式。这意味着每个请求或响应都是一个具有定义结构的JSON对象({"jsonrpc": "2.0", "method": ..., "params": ...}等),使其与语言无关且易于解析。同时支持同步请求(带响应)和异步通知/事件。

连接和传输:MCP 设计用于客户端和服务器之间有状态的、长生命周期的连接,而不是一次性的 HTTP 调用。当 MCP 客户端开始与服务器建立连接时,通常会通过以下两种方式之一进行:
- 本地(stdio)传输:如果服务器作为本地进程运行(例如,作为命令行界面程序或由主机启动的子进程),客户端和服务器可以通过进程的标准输入/输出流进行通信。这与语言服务器协议(Language Server Protocol)通常如何运行语言服务器作为通过 stdio 通信的子进程相似。这种方式效率高,并且避免了本地工具的网络开销。
- 远程(HTTP + SSE)传输:如果服务器是远程服务或独立运行(例如,在服务器或云端上),MCP 可以通过 HTTP 运行。在此模式下,请求可能作为 HTTP POST 发送,服务器使用服务器发送事件(Server-Sent Events,SSE)将响应或事件推送回客户端。SSE 允许服务器通过 HTTP 连接流式传输数据,这在工具的结果较大或服务器发送增量更新时非常有用(想象一下流式传输长文本或进度更新)。在任何情况下,传输层都负责可靠地传输 JSON-RPC 消息。

初始化握手:当连接建立后,首先进行的是握手以初始化和协商功能。客户端发送一个初始化请求,指明其支持的MCP协议版本以及一些自身信息。服务器以其自身的版本信息和提供的功能作为回应。这个握手过程确保双方使用兼容的MCP方言,并在基本设置上达成一致(例如,如果MCP规范发展,客户端可能只支持1.1版本,而服务器支持1.2版本——它们需要找到一个共同点,否则优雅地失败)。握手还可能包括初始配置,如客户端请求的“根”或范围。在MCP中,根通常指的是服务器的基础上下文或允许的数据集——例如,文件系统服务器的根目录路径,或API服务器的帐户范围。客户端可以提供这些信息,以便服务器了解其边界或起点。
发现服务器功能:初始化后,客户端通常会查询服务器能做什么。MCP定义了列出每种功能的标准方法:
- tools/list:客户端调用此方法来获取服务器提供的所有工具列表,以及每个工具的名称、描述和输入模式等详细信息。服务器返回一个包含工具列表及其定义的JSON对象。现在,客户端(以及最终的LLM)知道有哪些可用操作。类似地,还可能有resources/list和prompts/list方法(或客户端可能在初始化响应中获取这些信息)来枚举可用的资源端点和提示模板。有了这些信息,主机可以决定如何呈现或利用这些功能。例如,IDE可能会向用户显示可访问资源(文件)的列表,或者客户端可能会将工具描述嵌入到LLM的系统提示中,以便模型了解它们。
- 使用工具(函数调用):当AI模型决定调用一个工具时,序列可能如下:模型的输出(给客户端)表示希望使用特定工具(例如,get_weather)并提供参数(这可以通过特殊响应格式或函数调用机制发生,具体取决于AI)。然后,MCP客户端(通常在用户确认后)向服务器发送一个tools/call请求,其中包含工具的名称和要使用的参数。例如,{"method": "tools/call", "params": {"name": "get_weather", "arguments": {"latitude": 45.5, "longitude": -122.6}}}会要求服务器使用这些坐标执行天气工具。服务器执行相应的函数(这可能涉及API调用、数据库查询等)并返回结果。结果通常以结构化格式作为JSON-RPC响应的一部分返回。在MCP的设计中,服务器可以指示结果中的内容类型;例如,它可能返回一个JSON对象或文本块,以及元数据,如目标受众是谁(模型或用户)。在我们的天气示例中,服务器可能会响应{"result": {"content": [{"type": "text", "text": "{\"temperature\": 12, \"conditions\": \"cloudy\", ...}", "annotations": {"audience": ["assistant"]}}]}}——基本上以JSON文本的形式提供天气数据,标记为助理可见。客户端接收此信息并将其注入到LLM的上下文中(例如,就像助理“看到”了该文本一样),以便模型可以使用它来制定对用户的下一个回复。这一切都在幕后几秒钟内发生,使AI与外部数据的交互感觉无缝。
- 读取资源:当模型或用户需要一些上下文数据时,客户端会向服务器请求资源。这可以由模型提到资源URI或用户明确要求文件而触发。客户端发送一个resources/read(或类似)请求,其中包含资源的标识符(例如,{"method": "resources/read", "params": {"uri": "users://123/profile"}})。然后,服务器获取该资源(例如,查找用户123的个人资料)并返回其内容(通常为文本或结构化文本)。客户端可以将该内容插入到与模型的对话中,通常作为提示的一部分(以便模型在回答时可以参考)。资源还可能支持部分读取或订阅(在日志或流数据的情况下),但从根本上说,它们的行为就像文件系统中的读取文件一样——你请求内容,然后得到它。
- 使用提示模板:当主机或用户选择特定模板来引导对话时,可能会使用提示功能。例如,如果用户说“帮我调试这个错误”,而服务器有一个debug_error提示模板,客户端可以获取该提示(可能是一系列消息或指令)并将其附加到对话的开头。在底层,这可能是一个prompts/get调用,或者在连接时提供。提示也可能通过prompts/list列出,以便客户端UI可以向用户显示“可用策略”。一旦交付,提示将指导LLM如何构建其响应或交互。
会话和生命周期:MCP的客户端-服务器连接保持活动状态,允许多个顺序交互。客户端管理生命周期——它可以在完成时关闭服务器,或者只要主机应用程序打开就保持服务器运行。如果服务器提供通知或事件(例如,文件资源可能在文件更改时通知),这些会作为异步JSON-RPC通知发送给客户端,客户端可以通过更新上下文或通知用户来处理这些通知。MCP是有状态的,这也意味着服务器可以在需要时跨调用维护上下文(例如,缓存数据,或跟踪到外部API的用户会话)。
所有这些细节(方法、消息格式、错误处理等)都在MCP规范中定义。目标是任何符合MCP的客户端和服务器都实现这些相同的方法和消息类型,以便它们可以互操作。使用JSON-RPC和客户端-服务器模型的技术设计确保了低耦合:AI模型本身不直接讲JSON-RPC;客户端作为中介。这将LLM接口(提示和响应)与协议分开,这对安全性和清晰度都是有益的。LLM“看到”结果或可用工具描述,但JSON API调用通过客户端在带外发生。这种设计就是为什么你可以使用OpenAI的GPT-4(支持函数调用)作为MCP的主机——客户端只是将模型的函数调用映射到MCP的tools/call请求,反之亦然。模型不需要知道MCP的存在;客户端处理它。
总结:MCP的工作流程是:连接(打开通道,握手)→发现(服务器能做什么?)→使用(模型/用户请求资源或工具,服务器返回结果)→根据需要重复使用→关闭(关闭)。在整个过程中,格式化请求和处理响应的重担由MCP客户端和服务器库承担,因此使用MCP的开发人员可以专注于高层逻辑(提供什么工具或数据),而不是网络细节。
实施指南:使用MCP Python SDK
接触MCP的最简单方法之一是使用Python SDK,这是Python中协议的参考实现。此SDK允许你创建自己的MCP服务器(或客户端)并尝试将它们连接到AI模型。在本节中,我们将逐步介绍设置SDK、构建简单的MCP服务器并运行它。
安装
MCP Python SDK可通过PyPI获得。你可以使用简单的pip命令安装它。建议包含“cli”额外功能,以获取用于测试和运行服务器的命令行工具。
pip install uv
pip install "mcp[cli]""mcp[cli]"
这将安装mcp包及相关工具。(或者,如果只需要核心功能,可以使用pip install mcp进行安装,或者按照官方文档所示,使用项目自带的环境工具uv。)
请确保你的Python版本为3.10或更高,这是SDK所要求的。安装完成后,你应该能够在终端中运行mcp --help来查看可用的命令。
创建一个简单的MCP服务器
让我们用Python构建一个基本的MCP服务器。这个服务器将展示两种功能——一个工具和一个资源——以说明如何定义每种功能。
示例:我们将创建一个MCP服务器(server.py),它能够执行简单的加法计算(工具)并提供问候消息(资源)。
# server.py
from mcp.server.fastmcp import FastMCP
# Initialize an MCP server instance with a name
mcp = FastMCP("Demo Server")
# Define a tool function (simple addition)
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
# Define a resource function (personalized greeting)
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a greeting message for the given name."""
return f"Hello, {name}!"
在这段代码中,我们导入了FastMCP——一个高级类,它简化了服务器的构建过程。我们创建了一个名为“Demo Server”的mcp服务器实例。然后,我们使用SDK提供的装饰器来注册一个工具和一个资源:
- @mcp.tool()装饰器将add函数转换为一个MCP工具。默认情况下,工具的名称将是函数名(即add),SDK使用类型提示和文档字符串自动生成输入模式和描述。这个工具简单地返回两个整数的和。
- @mcp.resource("greeting://{name}")装饰器将get_greeting注册为一个通过URI模式识别的资源。字符串"greeting://{name}"表示这个资源可以通过URI方案greeting://和一个动态路径(name)来访问。如果客户端稍后请求greeting://Alice,这个函数将使用name="Alice"被调用,并返回"Hello, Alice!"。文档字符串可以作为资源的文档。
- 现在点击本地主机,你将看到MCP检查器。
就这样——我们就有了一个功能齐全的MCP服务器,包含一个工具和一个资源。你可以以类似的方式添加更多工具或资源,如果需要,甚至可以使用@mcp.prompt()定义提示模板。
运行服务器
要运行这个服务器,你有多个选项:
- 开发模式(检查器):MCP SDK包含一个名为MCP检查器的开发工具,它可以模拟客户端并让你与服务器进行交互。在确保已安装Node.js的前提下,你可以使用以下命令启动它:mcp dev server.py。

- 这将启动你的server.py,并打开一个交互式用户界面,你可以在其中测试调用add工具或读取greeting://...资源。这对于快速测试和调试非常有用。

- 直接执行:你也可以将服务器作为一个独立进程运行。例如,只需执行你的脚本:python server.py
- 在底层,因为我们使用了FastMCP,它会自动运行一个事件循环并等待客户端连接(默认使用stdio传输)。我们也可以在if __name__ == "__main__":块中显式调用mcp.run()来启动服务器。然后,服务器将等待一个MCP客户端通过stdio连接。
- 另外,SDK提供了一个快捷方式:mcp run server.py,这个命令的作用相同——运行你的服务器脚本并保持其开放以供客户端连接。
- 与AI主机集成:要看到真正的魔力,你需要将这个服务器连接到一个MCP兼容的AI客户端。如果你有Claude Desktop,你可以安装服务器以便Claude使用它。例如:mcp install server.py --name "Demo Server"
- 这个命令会在Claude Desktop中注册你的服务器(--name参数在UI中为其提供了一个友好名称)。然后,在Claude的界面中,你将能够启用并使用“Demo Server”作为数据源。Claude可以在对话中调用add工具或获取greeting资源。(通常,你可以向Claude提示类似“使用Demo Server将2和3相加”的内容,然后它会通过MCP调用工具。)
- 如果你没有Claude,还有其他客户端正在涌现。例如,你可以编写一个小型的MCP客户端脚本,连接到server.py并发出tools/call或resources/read请求——但这超出了我们这里的范围。关键是,现在任何MCP客户端都可以与这个服务器接口。
这个简单的演示只是冰山一角。使用Python SDK,你可以构建更复杂的服务器:连接到外部API、包装数据库查询,甚至控制硬件。SDK支持异步函数(如我们之前在天气示例中所使用的),并提供了用于流式传输结果、处理图像、管理认证等的实用工具。还有TypeScript、Java和Kotlin的SDK,它们具有类似的功能,使开发人员能够在自己选择的环境中实现MCP服务器。
MCP是AI工具空间中的一个相对较新的成员,自然会有人问它与其他将外部数据或功能与AI集成的方式相比如何。下面我们来看看几个相关概念以及MCP的不同之处:

结论
在这次深入探索中,我们了解了MCP的工作原理、其组件(主机、客户端、服务器)以及它支持的功能类型(资源、工具、提示)。我们通过技术工作流程展示了MCP在底层是一个任何平台都可以实现的简洁JSON-RPC协议。Python SDK示例说明,创建一个MCP连接器就像用装饰器编写几个函数一样简单,这使得任何支持MCP的AI都能立即使用这些功能。在将MCP与其他方法进行比较时,我们发现,虽然有其他方法可以将工具插入到AI中,但MCP的开放、可互操作的设计使其脱颖而出,成为不断增长的生态系统的基础。
文章来源:https://medium.com/stackademic/model-context-protocol-mcp-in-ai-9858b5ecd9ce