码农戏码

新生代农民工的自我修养

0%

Agent开发-Arthas MCP Client通信机制

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是一种基于JSONJavaScript Object Notation)的远程过程调用(RPC)协议。

它是一种轻量级的、无状态的、跨语言的通信协议,常用于客户端与服务端之间的交互。

JSON-RPC 是 RPC(远程过程调用)的一种具体实现,RPC 是一种通信范式,其核心目标是屏蔽网络细节,使远程调用如同本地调用般简单,并可基于多种底层网络协议(如 TCP/HTTP)实现。常见的 RPC 框架有 gRPC、Dubbo 和 Thrift。

Request

1
2
3
4
5
6
{
"jsonrpc": "2.0",
"method": "方法名",
"params": {"参数名": "值"} | ["值 1", "值 2"], // 对象或数组
"id": "唯一ID" // 可选(通知请求可省略)
}

jsonrpc : 必须为 "2.0"

method: 调用的方法名(字符串)。

params: 参数(可省略),支持对象(命名参数)或数组(位置参数)。

id: 请求标识符。

Response

成功

1
2
3
4
5
{
"jsonrpc": "2.0",
"result": "返回值",
"id": "对应请求 ID"
}

失败

1
2
3
4
5
6
7
8
9
{
"jsonrpc": "2.0",
"error": {
"code": -32601,
"message": "Method not found",
"data": "额外错误信息" // 可选
},
"id": "对应请求 ID" // 若请求无 ID,则为 null
}

Spring AI中相应源码

1
2
3
4
5
6
public record JSONRPCRequest( // @formatter:off  
@JsonProperty("jsonrpc") String jsonrpc,
@JsonProperty("method") String method,
@JsonProperty("id") Object id,
@JsonProperty("params") Object params) implements JSONRPCMessage {
}
1
2
3
4
5
public record JSONRPCResponse( // @formatter:off  
@JsonProperty("jsonrpc") String jsonrpc,
@JsonProperty("id") Object id,
@JsonProperty("result") Object result,
@JsonProperty("error") JSONRPCError error) implements JSONRPCMessage {

🚀 三种通信方式

MCP(模型上下文协议)主要支持 3 种通信方式,每种方式适用于不同的场景:

方式 通信协议 适用场景 优势 限制
1. STDIO 标准输入/输出 本地进程通信 简单、低延迟、无需网络 仅限本机、需管理进程生命周期
2. SSE Server-Sent Events 远程服务器通信 支持跨网络、自动重连 单向流(服务器→客户端)
3. HTTP JSON-RPC over HTTP 远程调用、负载均衡 双向请求-响应、可扩展 需处理网络延迟

建立连接

根据MCP的3 种通信方式,Spring AI 中如何选择?

1
2
3
4
5
6
7
8
9
10
11

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>


<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>

创建MCPTransport

StreamableHttpWebFluxTransportAutoConfiguration
创建WebClientStreamableHttpTransport

创建MCPClient

根据配置的MCP Client 类型,创建相应类型的MCPClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Client types supported by the MCP client.
*/
public enum ClientType {

/**
* Synchronous (McpSyncClient) client
*/
SYNC,

/**
* Asynchronous (McpAsyncClient) client
*/
ASYNC

}

连接建立成功后,会发送一个method为initialize的初始化的消息

1
2
3
Sending message for method initialize

Sending message JSONRPCRequest[jsonrpc=2.0, method=initialize, id=faf05893-0, params=InitializeRequest[protocolVersion=2025-06-18, capabilities=ClientCapabilities[experimental=null, roots=null, sampling=null, elicitation=null], clientInfo=Implementation[name=north-agent - arthas-mcp, title=arthas-mcp, version=1.0.0], meta=null]]

查询工具

建立完连接后,会发送 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
2
3
4
SyncMcpToolCallbackProvider mcpProvider = mcpToolCallbackProvider.getIfAvailable();  
List<ToolCallback> arthasCallbacks = mcpProvider == null
? List.of()
: List.of(mcpProvider.getToolCallbacks());

调用工具

比如让查询一下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_=老}]]