跳到主要内容

模型上下文协议(MCP)

定义

**模型上下文协议(MCP)**是一个开放标准,定义了 AI 应用程序连接外部工具、数据源和服务的统一方式。MCP 不是为每种 AI 模型和外部系统的组合构建一次性集成,而是提供了一种共享语言:主机应用程序通过定义良好的协议与 MCP 服务器通信,服务器公开任何合规 AI 客户端都可以发现和使用的能力(工具、资源、提示)。MCP 由 Anthropic 于 2024 年底引入,并立即作为开放标准发布,邀请更广泛的生态系统采用和扩展。

在 MCP 出现之前,AI 应用程序的工具集成是碎片化的。每个提供商都有自己的函数调用格式;每次集成都必须为每个新的 AI 后端重新实现。为一个模型编写的代码执行工具在切换提供商时需要重写,而新的数据源需要为每个想要访问它的 AI 应用程序定制管道。MCP 通过将"AI 如何与工具通信"(协议)与"哪个 AI"和"哪个工具"分开来解决这个问题,因此任何 MCP 兼容的客户端都可以使用任何 MCP 兼容的服务器,无需额外的胶水代码。

实际影响是显著的:开发者可以构建一次 MCP 服务器——用于数据库、文件系统、REST API、代码运行器——每个支持 MCP 的 AI 应用程序都可以访问它。该协议与传输无关(在本地进程中通过 stdio 运行或在远程服务中通过 HTTP/SSE 运行),支持双向通信,并包含能力协商握手,使客户端和服务器可以准确宣传其支持的内容。

工作原理

客户端-服务器架构

MCP 遵循严格的客户端-服务器模型,有三个不同的角色。主机应用程序是面向 AI 的应用程序(聊天 UI、编码助手、自主代理),它嵌入一个或多个 MCP 客户端。每个 MCP 客户端与单个 MCP 服务器保持 1:1 连接,充当主机与该服务器能力之间的中介。MCP 服务器是拥有和公开实际能力的进程——它知道如何调用天气 API、读取文件或查询数据库。这种分离意味着单个主机应用程序可以同时连接到许多服务器,每个服务器提供不同的工具集。

传输层

MCP 与传输无关:相同的 JSON-RPC 2.0 消息格式在两种内置传输上运行。stdio 传输用于本地服务器——主机将服务器作为子进程生成,并通过其标准输入和标准输出流进行通信。这是最简单的部署:没有网络、没有端口、没有身份验证开销。HTTP 与 SSE(服务器发送事件)传输用于远程或共享服务器:客户端以 HTTP POST 调用发送请求,并通过 SSE 端点接收流式响应。这支持多个客户端可以共享的集中托管服务器,并支持在云或容器环境中部署。协议规范中引入了第三种传输类型可流式 HTTP,作为更强大的 HTTP/SSE 双向流式传输的后继者。

能力:工具、资源和提示

MCP 服务器公开最多三种类型的能力。工具是可调用的函数——类似于 LLM API 中的函数调用——AI 可以调用它们来执行操作或检索信息。每个工具都有名称、描述和定义其输入参数的 JSON Schema。资源是 AI 可以访问的只读、类文件的数据源——本地文件、数据库记录、实时 API 快照——由 URI 标识。资源是 MCP 中的上下文注入等效物:它们让服务器向 AI 提供结构化数据,而无需工具调用往返。提示是存储在服务器上的可复用提示模板;它们允许服务器作者定义常见的交互模式(如"总结此文件"),客户端可以直接向用户展示。

能力协商和会话生命周期

当客户端连接到服务器时,协议以 initialize 握手开始。客户端发送其协议版本和支持的能力;服务器以其协议版本和提供的能力响应。这种协商确保具有不同功能集的客户端和服务器可以优雅地互操作——不支持提示的客户端将不会使用它们,即使服务器提供它们。初始化后,客户端调用 tools/listresources/listprompts/list 来发现服务器公开的内容。发现响应包括完整的 schema、描述和元数据。从那时起,客户端可以在会话中按需代表 AI 模型调用能力。

何时使用 / 何时不使用

场景MCP自定义 REST/API 集成原生函数调用
构建应该跨多个 AI 提供商工作的工具最佳选择——写一次,与任何 MCP 客户端使用每个提供商需要自己的集成锁定到单个提供商的 API 格式
在组织内的多个 AI 应用程序之间共享工具最佳选择——一个服务器,多个客户端需要在每个应用中复制集成代码不适合跨应用共享
单一提供商应用中的简单一次性工具过度设计——增加协议开销简单情况适用最简单的选项
将现有数据源(文件、数据库)作为 AI 上下文公开资源能力专为此目的构建需要自定义检索逻辑没有等效概念
长时间运行操作的实时流式结果通过 SSE 传输支持需要自定义流式逻辑支持有限
气隙或高度受限的环境stdio 传输不需要网络完全控制完全控制

比较

MCP vs OpenAI 函数调用

OpenAI 函数调用和 MCP 都允许 AI 模型调用结构化工具,但它们在不同级别上运行。函数调用是一个 API 级别功能:工具 schema 在请求有效载荷中传递,工具实现存在于您的应用程序代码中,该模式特定于 OpenAI 的 API 格式。MCP 是一个协议级标准:工具存在于独立的服务器进程中,协议处理发现和调用,任何合规的客户端都可以使用任何合规的服务器,无论哪个 AI 提供商驱动客户端。函数调用是单一提供商应用程序中简单、进程内工具的正确选择;当您希望可移植、可复用的工具服务器跨提供商和应用程序工作时,MCP 是正确选择。

MCP vs LangChain 工具

LangChain 工具是一个框架抽象:它们将 Python 可调用对象包装在 LangChain 代理运行时理解的标准化接口中。它们在 LangChain 生态系统内功能强大,但不定义进程间通信协议——LangChain 工具不能被非 LangChain 应用程序调用而无需额外管道。MCP 是一个有线协议:它准确定义了消息如何在进程之间序列化和传输。用 TypeScript 编写的 MCP 服务器可以被 Python MCP 客户端调用,无需共享框架依赖。两者并不互斥——LangChain 和其他框架可以实现 MCP 客户端来使用 MCP 服务器。

MCP vs 直接 REST API 调用

直接 REST API 调用提供最大灵活性且没有协议开销,但每个新的 AI 应用程序必须为其调用的每个 API 重新实现相同的身份验证、错误处理和结果格式化。MCP 提供了一个统一的信封,抽象了这些差异:无论服务器是在调用天气 API、SQL 数据库还是 GitHub 仓库,AI 应用程序总是发出相同的 tools/call 请求。权衡是 MCP 需要服务器基础设施(运行的服务器进程),而直接 REST 调用只是一个 HTTP 请求。

代码示例

最小 MCP 服务器

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Create the server instance with a name and version
const server = new McpServer({
name: "demo-server",
version: "1.0.0",
});

// Register a tool — the AI can call this to get the current time
server.tool(
"get_current_time",
"Returns the current UTC time in ISO 8601 format.",
{}, // No input parameters required
async () => ({
content: [
{
type: "text",
text: new Date().toISOString(),
},
],
})
);

// Register a tool with input parameters
server.tool(
"add_numbers",
"Adds two numbers together and returns the result.",
{
a: z.number().describe("The first number"),
b: z.number().describe("The second number"),
},
async ({ a, b }) => ({
content: [
{
type: "text",
text: String(a + b),
},
],
})
);

// Start the server using stdio transport (runs as a child process)
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Demo MCP server running on stdio");

最小 MCP 客户端

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

// Create a transport that spawns the server as a child process
const transport = new StdioClientTransport({
command: "node",
args: ["./demo-server.js"],
});

// Create and connect the client
const client = new Client(
{ name: "demo-client", version: "1.0.0" },
{ capabilities: {} }
);

await client.connect(transport);

// Discover available tools
const { tools } = await client.listTools();
console.log("Available tools:", tools.map((t) => t.name));

// Call a tool
const result = await client.callTool({
name: "add_numbers",
arguments: { a: 21, b: 21 },
});

console.log("Result:", result.content);
// Output: [{ type: 'text', text: '42' }]

await client.close();

实用资源

  • 模型上下文协议规范 — 权威协议规范,涵盖所有消息类型、传输和能力定义。
  • MCP TypeScript SDK — 用于构建 MCP 服务器和客户端的官方 TypeScript/JavaScript SDK,由 Anthropic 维护。
  • modelcontextprotocol.io — 官方 MCP 网站,包含快速入门指南、概念文档和社区构建服务器注册表。
  • MCP 服务器示例仓库 — 涵盖数据库、文件系统、网络搜索等的精选参考 MCP 服务器实现集合。

另请参阅