概述
系列定位:本文是“AI 应用核心框架与协议”系列的第 5 篇,也是 MCP 协议深度解析四篇系列的第 1 篇。在前四篇建立了 LangChain 生态认知、LangChain4j 源码内核、Spring Boot 集成和 LLM 通信协议之后,本文将聚焦 AI 工具标准化的核心协议——MCP。理解 MCP 的架构设计与概念模型,是后续实现跨框架工具复用、构建 Agent 工具市场的前提。
总结性引言:作为 Java 架构师,你对“标准化”带来的价值一定深有体会——如果没有 Servlet 规范,每个 Web 服务器都需要为每种应用框架写一个适配器;如果没有 JDBC 规范,每个数据库都需要为每种 ORM 框架提供专属驱动。现在,AI 工具领域正面临同样的“前标准化”混乱局面:OpenAI 说工具的 JSON 参数要放在 function.arguments 里,Anthropic 说应该放在 input 里;LangChain 用 Python 的 @tool 装饰器定义工具,LangChain4j 用 Java 的 @Tool 注解;一个为 Claude 写的天气查询工具,无法在 GPT-4o 的 Agent 中使用。这种碎片化严重阻碍了 AI 工具的复用和生态发展。MCP(Model Context Protocol)正是为了解决这个问题而生——它定义了一套标准的 Client-Server 协议,让任何 LLM 厂商、任何 Agent 框架、任何工具开发者都可以用同一种方式描述和调用工具。MCP Server 像是一个“微服务”——它通过标准接口(tools/list、tools/call)暴露自己的能力,任何支持 MCP Client 的应用都可以发现并调用它。MCP Client 像是一个“RPC Stub”——它封装了底层的通信细节,让上层 Agent 框架只需关心“这个工具有什么用、怎么调用”,而不需要关心“这个工具是本地方法还是远程 MCP Server”。本文将从 MCP 的起源与问题背景出发,系统拆解其架构设计、消息格式、四大核心概念与安全模型,帮助你建立起对 MCP 的完整认知,为后续的通信流程、Java 实现和生态应用打下坚实基础。
核心要点:
- MCP 的使命:解决 Function Calling 的巴别塔——统一不同 LLM 厂商、Agent 框架、工具开发者之间的工具描述与调用协议。
- Client-Server 架构:Host 发起连接,Client 管理连接,Server 提供 Resources/Tools/Prompts 三大能力(加高级的 Sampling)。
- JSON-RPC 2.0 消息格式:Request/Response/Error/Notification 四种标准消息类型,简单、语言无关、易于实现。
- 四大核心概念:Resources(数据源,URI 标识)、Tools(可执行函数,JSON Schema 参数)、Prompts(参数化提示词模板)、Sampling(Server 委托 Host 调用 LLM)。
- 能力协商:
initialize握手交换capabilities,Client 和 Server 互相了解对方能做什么。 - 类比 USB-C:MCP Server = USB-C 设备,MCP Client = USB-C 接口,LLM/Agent = 主机——设备可以即插即用,不需要为每种接口准备不同的转接头。
文章组织架构图:
flowchart TD
n1["1. MCP 的起源:碎片化与标准化需求"] --> n2["2. MCP 架构设计:Host/Client/Server/Transport"]
n2 --> n3["3. 消息格式:JSON-RPC 2.0 四种消息"]
n3 --> n4["4. 四大核心概念:Resources/Tools/Prompts/Sampling"]
n4 --> n5["5. 能力协商、生命周期与安全模型"]
n5 --> n6["6. MCP 与 Function Calling 关系"]
n6 --> n7["7. 与前後系列的衔接"]
n7 --> n8["8. 面试高频专题"]
classDef nodeStyle fill:#f1f5f9,stroke:#334155,stroke-width:1.5px,color:#1e293b
class n1,n2,n3,n4,n5,n6,n7,n8 nodeStyle
架构图说明:
- 总览说明:全文 8 个模块从 MCP 的起源与问题背景出发,逐步深入到架构设计、消息格式、核心概念、安全模型,最后以与 Function Calling 的关系、系列衔接和面试题收尾。
- 逐模块说明:模块 1-2 解决“为什么”和“是什么”——MCP 要解决什么问题、它的整体架构如何设计;模块 3-4 是全文核心——消息格式和四大概念是理解 MCP 具体运作的基础;模块 5 是工程保障——能力协商和安全性是 MCP 生产可用性的保障;模块 6 揭示 MCP 与 Function Calling 的层次关系;模块 7-8 承上启下与面试巩固。
- 关键结论:MCP 是 AI 工具生态的“标准化层”——它不替代 Function Calling(那是 LLM 厂商的底层协议),而是在 Function Calling 之上定义了一套统一的工具描述和调用协议。它的设计哲学与微服务架构高度一致——最小能力单元(每个 MCP Server 专注单一领域)、可插拔 Transport(Stdio/SSE/WebSocket 按需选择)、能力协商(Client 和 Server 互相了解对方的能力边界)。掌握了 MCP,你就掌握了构建开放、可复用、跨框架 AI 工具生态的钥匙。后续系列将逐步展开 MCP 的通信流程、Java 实现与生态应用。
1. MCP 的起源:Function Calling 的碎片化与标准化需求
1.1 Function Calling 的巴别塔
当前 LLM 生态中,各厂商的 Function Calling(工具调用)格式呈现出严重的碎片化。核心问题在于:每个模型都定义了自己的工具描述 JSON 结构,且语义相近却互不兼容。例如:
- OpenAI:工具定义放在
tools数组,参数使用function.parameters(JSON Schema),模型返回tool_calls数组,其中每个元素包含id、function.name、function.arguments(JSON 字符串)。 - Anthropic Claude:工具定义放在
tools数组,参数使用input_schema(同样 JSON Schema),但模型返回的是content块数组,类型为tool_use,包含id、name、input(已解析的 JSON 对象)。 - Google Gemini:工具定义使用
functionDeclarations,参数为parameters,返回functionCall对象,包含name和args(JSON 对象)。 - Azure OpenAI:基本沿袭 OpenAI 格式,但额外支持
strict参数控制 JSON 模式,认证方式也不同。
更严重的是,Agent 框架(LangChain、LangChain4j、Semantic Kernel)为了屏蔽这些差异,各自引入了自己的 Tool 抽象。例如,LangChain4j 使用 @Tool 注解和 ToolSpecification,LangChain 使用 @tool 装饰器,Semantic Kernel 使用 KernelFunction。于是,一个为 LangChain 编写的天气查询工具,无法直接用在 LangChain4j 上,更不用说在不同 LLM 厂商之间切换——你需要写适配代码,将工具定义转换为各厂商要求的 JSON 格式。
这种碎片化导致了 “M×N 问题”:M 个 Agent 框架 × N 个 LLM 厂商 = M×N 种适配组合。开发者被迫为每种组合编写和维护转换逻辑,严重阻碍了 AI 工具的复用和生态发展。
1.2 MCP 的价值主张:成为 AI 世界的“USB-C”
MCP 协议应运而生。它的核心思想是:定义一个统一的 Client-Server 协议,让 Server 端通过标准接口暴露 Resources、Tools、Prompts,Client 端(任何 LLM 或 Agent 框架)通过标准接口发现和调用这些能力。这就像 USB-C 接口——一个 USB-C 设备可以插入任何 USB-C 接口(无论是 MacBook、手机还是显示器),而无需关心底层协议细节。
在 AI 生态中,MCP Server 相当于“USB-C 设备”(提供具体工具),MCP Client 相当于“USB-C 接口”(统一接入层),LLM/Agent 相当于“主机”(消费工具能力)。只需要编写一次 MCP Server,它就可以被 Claude Desktop、VS Code 插件、你的 Spring Boot 应用(通过 LangChain4j)、或者任何实现了 MCP Client 的 Agent 框架直接使用。
1.3 对比现有标准:为什么不是 OpenAPI 或 gRPC?
你可能会有疑问:OpenAPI(REST 接口描述)和 gRPC 的 .proto 定义不也是用于接口标准化的吗?为什么 AI 工具需要 MCP?关键在于 “发现 + 动态调用” 能力:
- OpenAPI 描述了 REST 接口,但 AI Agent 需要运行时动态发现有哪些工具可用、它们的参数 Schema 是什么,并根据用户意图动态构造调用。OpenAPI 不具备内置的发现机制(需要显式绑定端点)。
- gRPC 提供了接口定义,但通常依赖强类型的代码生成,不适合 LLM 根据自然语言动态选择工具。
- MCP 专为 AI 场景设计:
tools/list方法让 Client 动态获取工具列表和 JSON Schema,tools/call方法让 LLM 生成的参数被直接转发给工具执行。这种“发现-调用”模式极其契合 Agent 工作流。
MCP 不是另一个 RPC 框架,它是建立在现有通信协议之上的“上下文协议”,专门解决 AI 上下文(工具、数据、提示)的标准化问题。
2. MCP 的架构设计:Host、Client、Server 与 Transport 层
2.1 三大角色详解
MCP 架构定义了三个清晰的角色:Host、Client、Server。我们用一个 Java 工程师熟悉的类比来理解:
- Host(宿主):这是最终用户直接交互的应用,例如 Claude Desktop、一个基于 Spring Boot 的客服 Agent,或者 VS Code 插件。它是业务入口,负责发起 MCP 连接。类比微服务架构中的“主应用程序”。
- Client(客户端):运行在 Host 进程内部,是一个协议栈。它维护与一个 MCP Server 的专用连接,负责发送请求(如
tools/list、resources/read),接收响应和通知,并管理连接生命周期。一个 Host 可以拥有多个 MCP Client,每个连接到一个不同的 MCP Server。类比 RPC 框架的 Stub(如 gRPC Stub)——封装了通信细节,让上层只看到本地方法调用。 - Server(服务端):提供具体的上下文能力。一个 MCP Server 是轻量级的、无状态的,专注于单一领域(如一个 Filesystem Server 只提供文件操作,一个 GitHub Server 只提供 Issues/PR 管理)。类比微服务——它通过标准接口暴露自己的一组能力。
它们的交互关系如下图所示:
flowchart LR
User[用户] --> Host
subgraph Host [Host 应用进程]
App[业务逻辑] --> Client1[MCP Client A]
App --> Client2[MCP Client B]
end
Client1 -->|Transport: Stdio| Server1[MCP Server A\n文件系统]
Client2 -->|Transport: SSE| Server2[MCP Server B\n天气查询]
Client2 -->|Transport: WebSocket| Server3[MCP Server C\n数据库查询]
图表主旨概括:该图展示了 MCP 架构中 Host、Client、Server 三大角色的物理部署关系,以及 Transport 层的多样性。一个 Host 可以内嵌多个 MCP Client,每个 Client 连接到不同的 MCP Server,使用的 Transport 协议可以不同。
逐层分解:
- 用户层:用户只与 Host 交互,无需关心底层 MCP 连接。
- Host 层:包含业务逻辑,例如一个客服 Agent 的意图识别与对话管理。Host 内部分别实例化了两个 MCP Client,一个连接文件系统 Server,另一个同时连接天气和数据库 Server(多路复用)。
- Client 层:MCP Client 封装了 JSON-RPC 消息的序列化、反序列化和 Transport 发送接收。
- Transport 层:展示了三种典型协议。Client A 与本地文件系统 Server 通过 Stdio 通信;Client B 与远端天气 Server 通过 SSE 通信;Client B 还与数据库 Server 通过 WebSocket 通信(Client 可以管理多个 Transport 连接)。
- Server 层:每个 Server 独立部署,专注单一领域。
设计原理映射:这种架构完美体现了关注点分离:Host 负责业务编排,Client 负责协议转换,Server 负责能力提供。Transport 的可插拔设计让同一个 Server 可以在开发阶段使用 Stdio 本地调试,在生产环境切换为 SSE 或 WebSocket 进行远程部署,而无需修改一行 Server 代码。
工程联系与关键结论:Java 工程师可将其视为微服务架构中的 Service Mesh 数据平面:MCP Client 是 Sidecar 代理,负责服务发现、协议转换和路由;MCP Server 是具体的微服务实例。这种设计让 AI 工具天然具备了分布式、可扩展、多语言的特点。在实际开发中,你只需要为每种后端能力编写一个 MCP Server,然后通过配置的方式将它们“插入”到你的 Agent Host 中,即插即用。
2.2 Transport 层的可插拔设计
MCP 规范将 Transport 层抽象为**“可靠、有序的消息传输通道”**。无论是 Stdio、SSE 还是 WebSocket,只要实现了“发送消息”和“接收消息”的语义,上层协议(JSON-RPC)完全不感知。下表和图对比了三种 Transport 的特性:
flowchart TD
classDef subA fill:#f0f4ff,stroke:#93a3d3,stroke-width:1.5px
classDef subB fill:#f0fff4,stroke:#93c5a3,stroke-width:1.5px
classDef subC fill:#fef9f0,stroke:#c4a77d,stroke-width:1.5px
classDef nodeStyle fill:#ffffff,stroke:#cbd5e1,stroke-width:1.5px,color:#1e293b
subgraph C["WebSocket"]
direction TB
App3["Host/Client"] <-->|"全双工"| Svr2["远程 MCP Server"]
Note3["双向实时,运维稍复杂"]
end
subgraph B["SSE"]
direction TB
App2["Host/Client"] -->|"HTTP POST"| Svr1["远程 MCP Server"]
Svr1 -->|"SSE 流"| App2
Note2["单向推送,兼容性好"]
end
subgraph A["Stdio"]
direction TB
App1["Host"] -->|"stdin"| Proc["子进程 MCP Server"]
Proc -->|"stdout"| App1
Note1["低延迟,本地通信"]
end
class A subA
class B subB
class C subC
class App1,Proc,Note1,App2,Svr1,Note2,App3,Svr2,Note3 nodeStyle
图表主旨概括:对比 MCP Transport 层的三种实现方式,展示其通信模式、延迟特性和适用场景。
逐层分解:
- Stdio:Host 通过子进程的 stdin/stdout 通信,没有网络开销,延迟极低,适合本地工具(如 Filesystem、Git 等),但仅限同一台机器。
- SSE:Client 通过 HTTP POST 发送 JSON-RPC 请求,Server 通过 SSE(
text/event-stream)推送响应和通知。基于 HTTP,防火墙友好,适合微服务间通信,但 Server 无法主动向 Client 发起请求(除非通过已有的 SSE 连接推送)。 - WebSocket:全双工通道,双方可自由发送消息。适合需要双向实时交互的场景(如 Server 主动通知 Client 资源变化,或 Agent 需要持续接收工具执行进度)。延迟比 SSE 更低(无需反复建立连接),但需要维护长连接和心跳。
设计原理映射:Transport 层的抽象正是 MCP 设计优雅的地方。它遵循了依赖倒置原则:上层协议不依赖具体通信方式,而是依赖一个“消息通道”抽象。在 Java 中,你可以定义 Transport 接口,包含 send(message) 和 onMessage(callback),然后分别为 Stdio、SSE、WebSocket 提供实现。这种设计让 MCP 能适应从命令行工具到云原生微服务的各种部署场景。
工程联系与关键结论:在实际应用中,开发阶段推荐使用 Stdio——你可以像运行 JUnit 测试一样启动一个 MCP Server 进程进行调试。上生产环境时,为了支持多 Host 并发访问,应将 Server 部署为独立进程并暴露 SSE 端点,前面加一层 Nginx 反向代理和 TLS 终端。如果工具执行耗时较长且需要实时推送进度,则考虑 WebSocket。选择的关键是权衡部署复杂度和通信需求。
3. 消息格式:JSON-RPC 2.0 的四种消息类型
MCP 协议的消息层基于 JSON-RPC 2.0,这是一个轻量级的远程过程调用协议,使用 JSON 作为数据格式。它简洁、语言无关、易于实现,已被广泛应用于 Web3(以太坊)、编辑器 LSP 协议等领域。JSON-RPC 2.0 定义了四种消息类型:
3.1 Request(请求)
客户端发送的调用请求,必须包含 jsonrpc、method,可选的 id(如果没有 id,则视为通知 Notification)。params 为结构化参数,可以是数组或对象。例如,查询工具列表的请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
jsonrpc:固定为"2.0"。id:请求标识符,可以是字符串或数字,用于关联响应。method:要调用的方法名,MCP 定义了大量以resources/、tools/、prompts/开头的标准方法。params:方法参数,对于tools/list通常为空对象(但可包含分页信息)。
3.2 Response(响应)
服务器对请求的成功响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"inputSchema": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "城市名称" }
},
"required": ["city"]
}
}
]
}
}
id必须与请求的id一致。result包含方法的返回值,其结构与具体方法相关。
3.3 Error(错误响应)
当请求失败时,服务器返回错误对象:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Invalid Request",
"data": "详细错误信息"
}
}
error.code:整数错误码,MCP 使用 JSON-RPC 定义的标准错误码(如 -32600 无效请求、-32601 方法不存在)以及自定义范围。error.message:简短描述。error.data:可选的附加信息。
3.4 Notification(通知)
通知是一种没有 id 的请求,服务器不需要响应。MCP 用通知实现 Server 主动推送事件,例如资源变更:
{
"jsonrpc": "2.0",
"method": "notifications/resources/updated",
"params": {
"uri": "file:///path/to/changed/file.txt"
}
}
- 因为没有
id,服务器不发送响应。 - 常用于 Server 到 Client 的事件流。
工程映射:JSON-RPC 2.0 的请求-响应模式与 HTTP 相似,但独立于传输协议。在 Java 实现中,你通常会有一个 Message 抽象类,子类 RequestMessage、ResponseMessage、ErrorMessage、NotificationMessage。序列化与反序列化可以使用 Jackson 的 @JsonTypeInfo 根据 id 存在与否进行鉴别。
4. 四大核心概念:Resources、Tools、Prompts、Sampling
MCP 定义了四种基础能力原语,它们构成了 AI 应用可获取的“上下文”范畴。
4.1 Resources(资源)—— 只读数据源
Resources 代表服务器暴露的只读数据,通过 URI 标识。例如:
file:///path/to/document.pdf:本地文件postgres://database/table/schema:数据库表结构api://external/api/users:外部 API 数据
发现方法:resources/list,返回 URI 列表及其 MIME 类型、描述。
读取方法:resources/read,参数为 uri,返回内容(文本或 Base64 二进制)。
订阅通知:resources/subscribe 后,当资源变更时,Server 会发送 notifications/resources/updated 通知。
Java 类比:Resources 就是 MCP 的“GET 接口”——像 REST 的 GET /resources/{id},但 URI 作为统一标识符,且内置了订阅机制,类似于 Spring 的 @EventListener 或响应式编程中的 Flux。
4.2 Tools(工具)—— 可执行函数
Tools 代表 Server 端可被调用的执行动作,这正是 Function Calling 标准化的核心。每个 Tool 包含:
name:唯一标识。description:自然语言描述,帮助 LLM 判断何时使用。inputSchema:JSON Schema 格式的参数定义,与 Function Calling 的参数规范完全对齐。
发现方法:tools/list 返回工具列表。
调用方法:tools/call,传入 name 和 arguments(JSON 对象),返回 content 数组(可包含文本、图片等)。
完整示例:一个天气查询和文件读取工具的定义(tools/list 响应片段):
{
"tools": [
{
"name": "get_weather",
"description": "获取指定城市当天的天气情况,包括温度、湿度、天气状况",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如 Beijing"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认为摄氏度"
}
},
"required": ["city"]
}
},
{
"name": "read_file",
"description": "读取指定路径的文件内容(文本文件)",
"inputSchema": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "文件的绝对路径"
},
"encoding": {
"type": "string",
"description": "文件编码,默认 UTF-8"
}
},
"required": ["file_path"]
}
}
]
}
Java 类比:Tools 就是 MCP 的“POST 接口”——像 POST /tools/{name},请求体为 JSON 参数,返回执行结果。与 Function Calling 的适配将在第 6 节详述。
4.3 Prompts(提示词)—— 参数化模板
Prompts 提供预定义的、可复用的提示词模板,支持参数化。通过中央化管理,让 Prompt Engineering 的成果能在不同 Agent 之间共享。
发现方法:prompts/list
获取方法:prompts/get,传入模板名称和参数,返回渲染后的完整 Prompt 文本。
例如,一个“代码审查”模板:
- 模板名:
code_review - 参数:
language(编程语言)、style(审查风格,如 strict/relaxed) - 调用
prompts/get后,Server 返回拼接好的 Prompt:“请以 {language} 代码:...”
Java 类比:这类似于 Thymeleaf 或 JSP 的视图模板,将可变部分抽象为参数。在工程上,你可以将 Prompt 模板存储在配置中心,由专门的 MCP Server 管理,实现 Prompt 的版本控制和 A/B 测试。
4.4 Sampling(采样/委托推理)—— Server 请求 LLM 能力
这是 MCP 的高级特性:Server 可以向 Client 请求 LLM 推理。例如,一个“代码审查 Server”在分析完代码后,可以通过 Sampling 请求 Host 的 LLM 生成审查报告摘要。
注意:Sampling 本质上是一个反向调用,因此安全性要求极高——防止恶意 Server 滥用 Host 的 LLM 配额。MCP 在 capabilities 协商中明确了 Sampling 支持,并且 Host 可以对请求进行授权控制(如弹出用户确认)。
Java 类比:这类似于回调函数或 Spring Cloud 的 @EnableFeignClients 反向调用。Server 定义了需要 LLM 完成的任务,Client(Host)负责调用 LLM 并将结果传回 Server。
四大核心概念关系图:
flowchart TD
subgraph MCP Server
R[Resources<br>数据源<br>URI 标识] -->|resources/list<br>resources/read| Client
T[Tools<br>可执行函数<br>JSON Schema] -->|tools/list<br>tools/call| Client
P[Prompts<br>参数化模板] -->|prompts/list<br>prompts/get| Client
S[Sampling<br>请求 LLM] -->|反向调用| Client
end
Client[MCP Client] --> Agent[Agent 框架]
Agent --> LLM[LLM]
图表主旨概括:展示 MCP Server 向 Client 暴露的四种能力类型及其发现/调用方法,以及 Client 如何将能力传递给 Agent 框架和 LLM。
逐层分解:
- Resources 和 Tools 是最基础的两种能力,分别对应“读取”和“执行”。
- Prompts 为对话模板提供了标准化封装。
- Sampling 是一个反向箭头,表示 Server 可以请求 Client 的 LLM 能力,实现更复杂的 Agent 协作。
- Client 作为中间层,汇聚这些能力并交给 Agent 框架,最终由 Agent 编排 LLM 使用。
设计原理映射:这四种原语覆盖了 AI 应用所需的上下文种类:数据(Resources)、动作(Tools)、知识(Prompts)和推理委托(Sampling)。设计上遵循了“最小化核心、最大化扩展”的原则——你可以在 Server 上自由组合这些能力。
工程联系与关键结论:在 Spring Boot 中实现 MCP Server 时,你通常会用一个 @RestController 类似的方式暴露这些能力,但底层是通过 JSON-RPC 而不是 HTTP 语义。对于 Java 工程师,关键是理解:MCP Server 相当于一个提供了特定接口的微服务,接口签名由 MCP 规范定义。Agent 框架通过 MCP Client 与之交互,就像 Spring Cloud Feign 调用远程服务一样。
5. 能力协商、生命周期与安全模型
5.1 initialize 握手与能力交换
MCP 连接建立后,首先进行能力协商,确保双方了解彼此的支持范围。这一过程通过 initialize 请求和响应完成,时序如下:
sequenceDiagram
participant Client as MCP Client
participant Server as MCP Server
Client->>Server: initialize (capabilities: {tools, resources}, clientInfo)
Server-->>Client: initialize response (capabilities: {tools, prompts, sampling}, serverInfo)
Client->>Server: initialized notification
Note over Client,Server: 进入正常通信状态
Client->>Server: tools/list
Server-->>Client: tools/list response
Client->>Server: tools/call
Server-->>Client: tools/call response
Client->>Server: shutdown request
Server-->>Client: shutdown response
图表主旨概括:展示 MCP 从握手、能力交换、正常操作到关闭的完整生命周期。
逐层分解:
initialize请求:Client 发送自身的capabilities和clientInfo。例如"capabilities": {"tools": {}, "resources": {"subscribe": true}}表示 Client 支持工具调用、资源读取和资源订阅。initialize响应:Server 返回自己的capabilities和serverInfo。例如"capabilities": {"tools": {"listChanged": true}, "prompts": {}}表示 Server 提供工具列表变更通知和提示词模板。initialized通知:Client 确认握手完成。- 随后即可进行正常的方法调用。
shutdown:Client 请求优雅关闭,Server 停止接受新请求,处理完已接受的请求后断开连接。
设计原理映射:能力协商类似于 TCP 三次握手后的特性协商,或者 HTTP/2 的 SETTINGS 帧。它避免了调用不支持的方法导致的运行时错误,同时为协议的平滑升级提供可能。
工程联系与关键结论:在 Java 客户端实现中,你可以将 capabilities 映射为一个 Capabilities 对象,并在发送 initialize 时根据当前配置动态生成。Server 端需要在注册时明确声明自己的能力集,并在运行中遵循该声明。这种模式类似于声明式接口(@EnabledCapability),增强了系统的健壮性。
5.2 安全模型基础
MCP 协议本身不定义认证和授权机制,但提供了清晰的集成点:
- 传输安全:Stdio 依赖操作系统进程隔离;SSE/WebSocket 必须使用 TLS 加密(HTTPS/WSS)。
- 身份认证:可以在 Transport 层添加自定义 HTTP Header(如
Authorization: Bearer <token>),或在initialize参数的meta字段传递认证信息。更规范的做法是结合 OAuth2 Proxy。 - 权限校验:Server 端应实现细粒度的 RBAC。例如,数据库 Server 可以为不同 Client 提供不同权限的数据库账户,或限制某些 Tools 只能被特定 Client 调用。实现时可在
tools/call处理逻辑中检查 Client 身份与操作的授权。
最佳实践:在生产环境中,通常会在 MCP Server 前放置 API 网关,统一负责 TLS 终结、认证和限流。MCP Client 与网关之间的通信与普通微服务无异。
6. MCP 与 Function Calling 的关系:标准化层
许多开发者初识 MCP 时会混淆它与 Function Calling 的界限。严格来说:
- Function Calling 是 LLM 厂商内部的机制:它定义了模型如何输出一个结构化的工具调用请求,以及如何将工具结果返回给模型。每种厂商有自己的格式。
- MCP 是 工具提供者与工具消费者之间的协议:它定义了工具如何被发现、描述和调用,与具体的 LLM 无关。
MCP 是 Function Calling 之上的标准化层。一个典型的集成流程如下:
sequenceDiagram
participant LLM
participant Agent as Agent 框架
participant MCPClient as MCP Client
participant MCPServer as MCP Server
Agent->>MCPClient: tools/list
MCPClient->>MCPServer: tools/list (JSON-RPC)
MCPServer-->>MCPClient: 工具列表
MCPClient-->>Agent: 转换为 ToolSpecification 列表
Agent->>LLM: 发送 Prompt + tools (按厂商格式)
LLM-->>Agent: Function Calling 请求 (tool_name, arguments)
Agent->>MCPClient: tools/call (name, args)
MCPClient->>MCPServer: tools/call (JSON-RPC)
MCPServer-->>MCPClient: 执行结果
MCPClient-->>Agent: 结果
Agent->>LLM: 追加工具结果,继续推理
图表主旨概括:揭示 MCP 在 LLM Function Calling 和实际工具执行之间的角色——作为标准化的工具抽象层,将厂商无关的工具描述和调用与具体的模型调用解耦。
逐层分解:
- Agent 框架通过 MCP Client 获取工具列表,得到与厂商无关的工具定义(符合 MCP 的 JSON Schema)。
- Agent 框架将 MCP 工具定义转换为 LLM 需要的格式(如 OpenAI 的
tools参数),这个过程只需编写一次适配器。 - 当 LLM 返回工具调用请求时,Agent 框架再通过 MCP Client 调用远程 Server,完全不依赖厂商。
设计原理映射:这是一个典型的适配器模式 + 外观模式。MCP 是外观,对 LLM 和 Agent 屏蔽了后端工具的复杂性;适配器负责将 MCP 的统一格式与各厂商格式互转。这种设计让新增 LLM 厂商只需实现一个适配器,即可复用所有 MCP Server。
工程联系与关键结论:作为 Java 架构师,你可以将 MCP 视为工具领域的 JDBC。JDBC 定义了一组接口(Connection、Statement、ResultSet),各数据库厂商提供驱动实现。MCP 定义了 tools/list、tools/call 等接口,各工具开发者提供 MCP Server 实现。Agent 框架通过 MCP Client(类似 JDBC Driver)与 Server 通信。你完全可以用一个 ToolProvider 接口来抽象 MCP 连接,并在 Spring 容器中注入多个 ToolProvider Bean,由它们负责从不同的 MCP Server 拉取工具定义并执行调用。这样,你的 Agent 就天然具备了跨厂商、跨框架的工具复用能力。
7. 与前后系列的衔接
本文作为 MCP 系列的开篇,承接了前文的相关主题,并为后续篇章埋下伏笔:
- 关联本系列第 4 篇(LLM 服务化协议):第 4 篇拆解的 REST、SSE、gRPC 协议,正是 MCP Transport 层的候选协议。MCP 本身不绑定任何特定 Transport,而是建立在它们之上。理解这些底层协议的性能与适用场景,有助于你为 MCP Server 选择合适的传输方式。
- 关联本系列第 1 篇(LangChain 生态):第 1 篇中提到 MCP 是“工具标准化的未来”,本文是对这一论断的系统展开,详细拆解了其标准化原理与架构设计。
- 关联系列一第 5 篇(Tools 深度):该篇建立了工具的抽象模型(
name+description+parameters+execute),MCP 的 Tools 正是这一模型的标准化协议实现。 - 关联后续(本系列第 6 篇 MCP 通信流程):本文建立了概念模型,下一篇将通过完整的
initialize → tools/list → tools/call → shutdown时序图,逐一拆解每个消息的精确 JSON 结构和流转细节。 - 关联后续(本系列第 7 篇 MCP Java 实现):本文是理论篇,第 7 篇将用 Spring Boot 3.4.x + LangChain4j 1.0.0-alpha1 实现一个完整的 MCP Server(暴露数据库查询 Tools 和文档 Resources)以及一个 MCP Client 集成示例。
建议阅读路径:读者应先理解本文的架构与概念,然后阅读下一篇的通信细节,最后动手实践第 7 篇的代码。这样才能形成从理论到实现的完整闭环。
8. 面试高频专题
(以下题目均假设读者为 Java 架构师,站在工程角度回答)
Q1. 什么是 MCP?它主要解决什么问题?为什么它被称为 AI 工具的“USB-C”?
① 一句话回答:MCP 是 Anthropic 发布的标准化 Client-Server 协议,旨在统一 AI 应用中工具(Tool)、数据源(Resource)和提示词(Prompt)的暴露与调用方式,解决 Function Calling 生态的碎片化问题。
② 详细解释:不同 LLM 厂商(OpenAI、Anthropic、Google)的 Function Calling 格式各不相同,Agent 框架也各自定义了 Tool 抽象。这导致一个工具需要为每种组合编写适配。MCP 定义了统一的消息格式(JSON-RPC 2.0)和能力发现机制,让 Server 以标准接口暴露能力,Client 通过标准协议调用,实现即插即用。
③ 多角度追问:
- MCP 和 OpenAPI 有什么不同? OpenAPI 描述静态 REST 端点,缺少动态发现和函数调用语义;MCP 专为 LLM 设计,内置工具发现、参数 Schema、异步通知等。
- MCP 是否只能用于 Claude? 不,任何 LLM 和 Agent 框架只要实现 MCP Client,就能接入所有 MCP Server。
- MCP 是否依赖特定的传输协议? 不,MCP 支持 Stdio、SSE、WebSocket 等可插拔传输。
④ 加分回答:MCP 的设计理念与 JDBC 类似——JDBC 统一了 Java 应用与数据库的交互,MCP 统一了 AI 应用与工具的交互。它们都通过抽象接口将具体的实现细节隔离,从而实现生态的互操作性。
Q2. MCP 的三大角色 Host/Client/Server 分别是什么?它们的分工是怎样的?
① 一句话回答:Host 是最终用户交互的应用,Client 是 Host 内负责与 Server 通信的协议栈,Server 是提供 Resources、Tools、Prompts 等能力的服务端。
② 详细解释:Host 发起连接并管理 Client 的生命周期,业务逻辑在此层;Client 封装 JSON-RPC 消息的发送/接收、序列化和传输管理;Server 专注于单一领域的能力提供,响应 Client 的请求。多个 Client 可连接多个 Server。
③ 多角度追问:
- 为什么需要 Client 这个独立角色? 解耦——Host 无需关心底层通信细节,可以像调用本地方法一样使用远程工具。
- Server 是否必须是无状态的? MCP 推荐 Server 无状态,但有状态的场景可以通过 Session 机制在 Server 端实现。
- 能否在同一 Host 中连接多个同类型的 MCP Server? 可以,例如同时连接一个 GitHub Server 和一个 GitLab Server。
④ 加分回答:在 Spring 应用中,Host 是你的 @SpringBootApplication,Client 可以被封装为一个 @Service 类,Server 则是一个独立部署的进程。通过依赖注入,你可以轻松替换 Client 的 Transport 实现(例如开发时使用 Stdio,生产时使用 SSE)。
Q3. MCP 的四大核心概念(Resources/Tools/Prompts/Sampling)各自是什么?它们有什么发现和调用方法?
① 一句话回答:Resources 是 URI 标识的只读数据源;Tools 是带 JSON Schema 的可执行函数;Prompts 是可参数化的提示词模板;Sampling 是 Server 反向请求 Host 的 LLM 推理能力。
② 详细解释:Resources 通过 resources/list 发现,resources/read 读取;Tools 通过 tools/list 发现,tools/call 调用;Prompts 通过 prompts/list 发现,prompts/get 获取;Sampling 通过 Server 向 Client 发送特定请求实现。
③ 多角度追问:
- Resources 和 Tools 的本质区别是什么? Resources 是幂等的只读数据,Tools 可能产生副作用(如写文件、发请求)。
- Prompts 为什么需要独立出来? 可复用、可版本化管理,避免硬编码。
- Sampling 的安全性如何保证? Host 可以展示用户确认弹窗,或对 Server 的 Sampling 请求进行频次控制和额度限制。
④ 加分回答:在 Java 建模时,可用 Resource、Tool、Prompt 三个领域类,加上 SamplingRequest 和 SamplingResponse。每个领域类都有对应的 List 和 Call 服务方法。
Q4. MCP 的消息传输层有哪几种选择?它们的适用场景有什么不同?
① 一句话回答:主要可选 Stdio、SSE 和 WebSocket。Stdio 适合本地进程通信,延迟最低;SSE 适合基于 HTTP 的单向推送,防火墙友好;WebSocket 适合需要双向实时交互的场景。
② 详细解释:Stdio 通过子进程 stdin/stdout 通信,适合开发环境和本地工具;SSE 基于 HTTP,Client POST 请求,Server 通过长连接推送响应,适用于微服务部署;WebSocket 全双工,延迟低,适合需要 Server 主动推送进度或事件的场景。
③ 多角度追问:
- 如何在 Spring Boot 中实现 Stdio Transport? 使用
ProcessBuilder启动子进程,获取其输入输出流。 - SSE 和 WebSocket 在运维上的主要区别是什么? SSE 可以与普通 HTTP 负载均衡无缝集成,WebSocket 需要特殊配置(如 Nginx 的
proxy_set_header Upgrade)。 - 是否可以使用 gRPC 作为 Transport? MCP 规范未禁止,但官方未定义,理论上可以,只需要满足有序、可靠的消息传递。
④ 加分回答:LangChain4j 的 MCP 模块目前支持 Stdio 和 SSE Transport。实际项目中,我推荐开发时使用 Stdio 快速迭代,CI/CD 部署时将 Server 打包为 Docker 镜像并暴露 SSE 端点,通过 API 网关对外提供能力。
Q5. MCP 的 initialize 握手是如何工作的?为什么要交换 capabilities?
① 一句话回答:initialize 握手是 Client 和 Server 在连接建立后的首次交互,双方交换自己的 capabilities,以声明各自支持的功能,避免后续调用不支持的方法。
② 详细解释:Client 发送 initialize 请求,携带自身能力(如 {"tools": {}, "resources": {"subscribe": true}})和客户端信息。Server 返回自己的能力和服务器信息。之后 Client 发送 initialized 通知,双方进入正常操作。能力协商类似于 HTTP/2 的 SETTINGS 帧,为协议扩展奠定基础。
③ 多角度追问:
- 如果 Client 声明支持 Sampling,但 Server 不支持,会发生什么? Server 在响应中不声明 Sampling 能力,Client 就不会向该 Server 发送 Sampling 请求。
capabilities是否可以动态更新? 当前规范在握手时固定,后续可能引入动态更新机制。- 如果握手失败怎么办? 连接关闭,Client 应提示错误。
④ 加分回答:在 Java 实现中,可以用一个 Capabilities 对象封装所有能力布尔值或子对象,并在 initialize 处理时进行验证。Server 端可以在配置文件(如 YAML)中定义能力声明,避免硬编码。
Q6. MCP 是如何解决 Function Calling 碎片化问题的?请简述其与 Function Calling 的关系。
① 一句话回答:MCP 在 LLM 的 Function Calling 之上定义了统一的工具发现和调用协议,将厂商私有格式与 Agent 框架的 Tool 抽象解耦,通过标准化的 JSON Schema 描述工具参数,实现一次编写、多平台使用。
② 详细解释:传统 Function Calling 要求 Agent 框架为每个 LLM 厂商编写适配器。而 MCP 将工具定义和调用统一为 tools/list 和 tools/call 接口,Agent 框架只需要实现一个 MCP Client 适配器,即可调用任何 MCP Server 的工具。LLM 的 Function Calling 格式转换在 Agent 框架内部完成,对于工具开发者透明。
③ 多角度追问:
- MCP 是否完全不依赖 OpenAI 的格式? MCP 的工具定义使用 JSON Schema,可以映射到 OpenAI 的
function.parameters,但不必限于它。 - LangChain4j 如何集成 MCP?
langchain4j-mcp模块提供McpToolProvider,自动将 MCP Server 的工具注册为 LangChain4j 的ToolSpecification,LLM 调用时通过tools/call执行。 - 如果 LLM 不支持 Function Calling,MCP 还有用吗? 有用,Agent 可以通过硬编码或规则引擎决定调用哪个工具,仍可通过 MCP 统一工具调用。
④ 加分回答:MCP 之于 Function Calling,如同 JPA 之于 Hibernate——JPA 是 ORM 标准,Hibernate 是实现;MCP 是工具协议标准,各 LLM 厂商的 Function Calling 是底层实现。Spring Data JPA 可以轻松切换底层实现,同理,Agent 框架通过 MCP 可以无缝切换 LLM 提供商。
Q7. MCP 中的 Sampling 是什么?它带来了什么可能性?
① 一句话回答:Sampling 允许 MCP Server 反向请求 Host(Client)调用 LLM 完成推理任务,实现 Agent 间的“委托推理”,从而构建更复杂的多 Agent 协作模式。
② 详细解释:例如,一个代码审查 Server 在执行静态分析后,希望由 LLM 生成自然语言摘要,它可以通过 Sampling 向 Client 发起请求,Client 调用 LLM 并将结果返回。这相当于 Server 拥有了“思考”的能力,而不需要自己集成 LLM。
③ 多角度追问:
- Sampling 会增加安全风险吗? 会,Server 可能滥用 Host 的 LLM 额度或提示注入。因此 Host 应实现权限控制、额度管理和用户确认。
- Sampling 是否支持流式? 协议允许,但实现较复杂。
- 与普通 Function Calling 有何不同? Function Calling 是 Host 主动调用 Tool,Sampling 是 Server 主动调用 Host 的推理。
④ 加分回答:这在 Java 中可以实现为回调接口 SamplingCallback。Spring Boot 应用可以通过 AOP 拦截 Sampling 请求,检查调用频率和来源,确保安全。
Q8. MCP 如何保障安全?在生产环境中应如何部署 MCP Server?
① 一句话回答:MCP 本身不定义安全机制,但推荐在 Transport 层使用 TLS 加密,并通过 API 网关进行身份认证和授权;Server 内部实现细粒度的权限控制和输入校验。
② 详细解释:Stdio 通信天然依赖操作系统安全边界;SSE/WebSocket 必须使用 TLS。身份认证通常通过在 HTTP Header 中传递 JWT 或 API Key 实现。Server 内部应为每个 Tool 和 Resource 定义访问控制列表(ACL)。此外,应对所有输入进行严格校验,防止注入。
③ 多角度追问:
- 如何防止恶意 MCP Server 窃取 Host 数据? Host 应只连接可信任的 Server,并对 Resources 暴露的数据进行最小化原则。
- MCP 协议本身是否支持加密? 不支持,加密依赖于 Transport 层(如 TLS)。
- 如何实现多租户隔离? 为每个租户启动独立的 Server 实例,或通过命名空间隔离资源和工具。
④ 加分回答:Kubernetes 部署时,可将每个 MCP Server 作为独立 Pod,通过 Service 暴露 SSE 端口。使用 Istio 做 mTLS 和 RBAC,配合 OPA 实现策略控制。这种模式与企业微服务安全架构完全一致。
Q9. 请对比 MCP 的 Resources、Tools 与 REST 的 GET、POST 的异同。
① 一句话回答:Resources 类似于 REST 的 GET(只读),Tools 类似于 REST 的 POST(执行动作),但 MCP 提供了内置的发现机制、订阅通知和统一的调用语义。
② 详细解释:Resources 通过 URI 标识数据,resources/read 相当于 GET;Tools 通过名称和参数执行操作,tools/call 相当于 POST。但 MCP 更强:resources/list 提供了动态资源目录;resources/subscribe 实现了变更推送,是 REST 通常不具备的。且 Tools 的参数使用 JSON Schema 强类型约束,比 REST 的松散参数更严格。
③ 多角度追问:
- REST 也可以使用 OpenAPI 描述参数 Schema,MCP 的优势在哪? MCP 的发现和调用是运行时一体化的,无需额外文档;LLM 可以动态理解工具并构造调用,而 REST 通常需要人类阅读文档。
- MCP 的 Tools 返回值是什么格式? 一个 content 数组,可以包含多种 MIME 类型的片段(文本、图片等),比 REST 的单一响应体更灵活。
- 能否在 MCP Server 上同时提供 REST 接口? 可以,但会破坏统一性。
④ 加分回答:你可以把 MCP 看作是一种专为 AI 优化的“动态 REST”,它的接口契约不是由人类手动编写,而是由 LLM 在运行时通过 tools/list 读取并遵循的。
Q10. (系统设计题)设计一个支持 MCP 的智能客服系统,要求能接入任意的 MCP Server 工具,例如订单查询 Server、物流查询 Server、退款处理 Server。请画出架构图与时序图,并说明如何集成 LangChain4j 和 Spring Boot。
架构图(Mermaid flowchart):
flowchart TD
classDef nodeStyle fill:#f1f5f9,stroke:#334155,stroke-width:1.5px,color:#1e293b
User["用户"] --> ChatUI["客服聊天界面"]
ChatUI --> Gateway["API 网关<br/>认证/限流"]
Gateway --> AgentService["客服 Agent 服务<br/>Spring Boot + LangChain4j"]
AgentService --> MCPClient1["MCP Client<br/>订单查询"]
AgentService --> MCPClient2["MCP Client<br/>物流查询"]
AgentService --> MCPClient3["MCP Client<br/>退款处理"]
MCPClient1 -->|"SSE"| OrderServer["订单查询 MCP Server"]
MCPClient2 -->|"SSE"| LogisticsServer["物流查询 MCP Server"]
MCPClient3 -->|"SSE"| RefundServer["退款处理 MCP Server"]
AgentService --> LLM["LLM 服务<br/>(OpenAI/Azure)"]
class User,ChatUI,Gateway,AgentService,MCPClient1,MCPClient2,MCPClient3,OrderServer,LogisticsServer,RefundServer,LLM nodeStyle
业务时序图(Mermaid sequenceDiagram):
sequenceDiagram
participant User
participant AgentService
participant MCPClient as MCP Client (订单)
participant MCPServer as 订单查询 Server
participant LLM
User->>AgentService: "帮我查订单 12345 的状态"
AgentService->>LLM: 发送 Prompt + 所有 MCP 工具定义
LLM-->>AgentService: function_call: get_order_status(orderId="12345")
AgentService->>MCPClient: tools/call ("get_order_status", {"orderId":"12345"})
MCPClient->>MCPServer: JSON-RPC tools/call
MCPServer-->>MCPClient: {"status": "已发货"}
MCPClient-->>AgentService: 工具结果
AgentService->>LLM: 追加工具结果,要求生成回复
LLM-->>AgentService: "您的订单 12345 已发货,预计明日到达。"
AgentService-->>User: 展示回复
组件职责:
- API 网关:统一认证(JWT)、限流、TLS 终结。
- Agent 服务:核心业务逻辑,使用 LangChain4j 进行对话管理,通过
McpToolProvider将三个 MCP Client 注册为工具。 - MCP Client:每个 Client 连接一个 MCP Server,负责 JSON-RPC 通信和工具定义拉取。启动时通过
initialize握手,并周期性或按需拉取工具列表。 - MCP Server:独立的微服务,分别处理订单、物流、退款业务,内部调用现有业务系统的 REST API 或数据库。
技术选型权衡:
- Transport 选择 SSE:因为 Server 需要独立部署,SSE 基于 HTTP,运维简单,且客服场景对实时性要求不是极致。如果未来需要 Server 推送异步事件(如物流状态自动更新),可以升级为 WebSocket。
- 工具注册策略:Agent 服务启动时,调用所有 Client 的
tools/list,汇总为List<ToolSpecification>并缓存。当用户提问时,Agent 将这些规范传递给 LLM。LLM 返回工具调用后,Agent 通过McpToolProvider调用对应的 Client 的tools/call。 - 安全:API 网关拦截所有请求,校验 JWT。MCP Client 与 Server 之间通过 mTLS 双向认证(在 Service Mesh 中)。Server 端检查 JWT 中的权限,确保用户只能查询自己的订单。
量化分析:假设三个 MCP Server 各有 3-5 个工具,总工具数 <20,LLM 一次推理时携带所有工具定义不会超出 token 限制。如果工具数增长到数百个,则需要引入工具检索(如 embedding 匹配)来动态筛选工具,这正是 MCP 的高级用法,但其协议不变。
加分回答:这种架构天然支持水平扩展:Agent 服务、MCP Server 都可以通过容器化部署,根据负载自动扩缩。MCP Client 与 Server 之间的连接采用长连接(SSE),避免了频繁握手开销。同时,由于 MCP 的标准化,将来如果需要新增一个“商品推荐 MCP Server”,只需在 Agent 服务的配置中添加一个新 Client,无需修改任何业务代码——这正是 MCP 作为“USB-C”接口的巨大价值。
(面试专题结束)
附录:MCP 核心概念速查表
| 概念 | 定义 | 发现方法 | 调用方法 | Java 类比 |
|---|---|---|---|---|
| Host | 用户交互的应用,管理 MCP Client 生命周期 | - | - | Spring Boot 应用 |
| Client | 协议栈,维护与 Server 的连接,消息编解码 | - | 发送 JSON-RPC 请求 | RPC Stub / Feign Client |
| Server | 能力提供者,暴露 Resources/Tools/Prompts | - | 响应请求 | 微服务实例 |
| Resources | URI 标识的只读数据源 | resources/list | resources/read | GET /resources/{uri} |
| Tools | 带 JSON Schema 的可执行函数 | tools/list | tools/call | POST /tools/{name} |
| Prompts | 可参数化的提示词模板 | prompts/list | prompts/get | 视图模板(Thymeleaf) |
| Sampling | Server 向 Client 请求 LLM 推理 | - | 反向请求 | 回调 / Feign 反向调用 |
| JSON-RPC 2.0 | 轻量级 RPC 消息格式 | - | Request/Response | HTTP/2 帧的 JSON 版 |
| Transport | 底层通信通道 (Stdio/SSE/WebSocket) | - | 可靠有序字节流 | Netty / Servlet |
延伸阅读:
- MCP 协议官方规范:modelcontextprotocol.io
- MCP GitHub 仓库及示例 Servers:github.com/modelcontex…
- JSON-RPC 2.0 规范:www.jsonrpc.org/specificati…
- Anthropic 官宣 MCP 博客:www.anthropic.com/news/model-…