以 arthas 为例,探索一下Spring AI 中 MCP Client端通信机制的实现。
Client调用流程
MCP 客户端调用服务器工具的流程如下:
1、建立连接 :与 MCP 服务器搭建通信链路。
2、查询工具 :获取服务器上所有外部工具的数量信息。
3、生成列表 :将查询到的外部工具整理成列表,并融入当前对话场景。
4、调用工具 :通过 Function calling 技术调用所需的外部工具。
sequenceDiagram
participant Client as MCP客户端 (如AI应用)
participant Server as MCP服务端
Note over Client,Server: 1. 发现阶段
Client->>Server: 请求 resources/list
Server-->>Client: 返回资源元信息列表
(URI, 名称, 描述, MIME类型等)
Note over Client,Server: 2. 读取阶段
Client->>Server: 请求 resources/read (指定URI)
Server-->>Client: 返回资源实际内容
Note over Client,Server: 可选:实时更新
Client->>Server: resources/subscribe (订阅特定URI)
Server-->>Client: notifications/resources/updated (内容变更时推送)
通信协议
MCP 中 Client 与 Server 间使用 JSON-RPC 2.0 作为通信消息格式。
JSON-RPC 2.0是一种基于JSON(JavaScript Object Notation)的远程过程调用(RPC)协议。
它是一种轻量级的、无状态的、跨语言的通信协议,常用于客户端与服务端之间的交互。
JSON-RPC 是 RPC(远程过程调用)的一种具体实现,RPC 是一种通信范式,其核心目标是屏蔽网络细节,使远程调用如同本地调用般简单,并可基于多种底层网络协议(如 TCP/HTTP)实现。常见的 RPC 框架有 gRPC、Dubbo 和 Thrift。
Request
1 | { |
jsonrpc : 必须为 "2.0"。
method: 调用的方法名(字符串)。
params: 参数(可省略),支持对象(命名参数)或数组(位置参数)。
id: 请求标识符。
Response
成功
1 | { |
失败
1 | { |
Spring AI中相应源码
1 | public record JSONRPCRequest( // @formatter:off |
1 | public record JSONRPCResponse( // @formatter:off |
🚀 三种通信方式
MCP(模型上下文协议)主要支持 3 种通信方式,每种方式适用于不同的场景:
| 方式 | 通信协议 | 适用场景 | 优势 | 限制 |
|---|---|---|---|---|
| 1. STDIO | 标准输入/输出 | 本地进程通信 | 简单、低延迟、无需网络 | 仅限本机、需管理进程生命周期 |
| 2. SSE | Server-Sent Events | 远程服务器通信 | 支持跨网络、自动重连 | 单向流(服务器→客户端) |
| 3. HTTP | JSON-RPC over HTTP | 远程调用、负载均衡 | 双向请求-响应、可扩展 | 需处理网络延迟 |
建立连接
根据MCP的3 种通信方式,Spring AI 中如何选择?
1 |
|
创建MCPTransport
在StreamableHttpWebFluxTransportAutoConfiguration中
创建WebClientStreamableHttpTransport

创建MCPClient
根据配置的MCP Client 类型,创建相应类型的MCPClient
1 | /** |
连接建立成功后,会发送一个method为initialize的初始化的消息
1 | Sending message for method initialize |
查询工具
建立完连接后,会发送 tools/list 请求
1 | Sending message JSONRPCRequest[jsonrpc=2.0, method=tools/list, id=5fc929e0-1, params=PaginatedRequest[cursor=null, meta=null]] |
会获取到完整的工具列表

生成列表
在Spring AI体系里面,MCP Client 获取的工具列表,会抽象成 ToolCallback
1 | SyncMcpToolCallbackProvider mcpProvider = mcpToolCallbackProvider.getIfAvailable(); |
调用工具
比如让查询一下JVM信息,会调用 jvm 命令,让服务端发送 tools/call 命令
1 | Sending message JSONRPCRequest[jsonrpc=2.0, method=tools/call, id=5fc929e0-2, params=CallToolRequest[name=jvm, arguments={}, meta={user_id=user-001, _AGENT_=老}]] |