McpSchemaVO 详解:MCP协议消息结构定义
📋 文件作用
McpSchemaVO.java 是一个值对象(Value Object),定义了 MCP(Model Context Protocol)协议的消息结构,用于:
- 序列化:将Java对象转换为JSON字符串
- 反序列化:将JSON字符串转换为Java对象
🏗️ 核心结构
1. 密封接口(Sealed Interface)
1 2 3
| public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCResponse { String jsonrpc(); }
|
作用:
- 定义所有MCP消息的公共接口
- 限制只有
JSONRPCRequest 和 JSONRPCResponse 可以实现该接口
- 确保类型安全,防止非法实现
sealed关键字的优势:
1 2 3 4 5 6 7 8 9 10 11 12
| public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCResponse { String jsonrpc(); }
public class IllegalMessage implements JSONRPCMessage { @Override public String jsonrpc() { return "2.0"; } }
|
2. 请求对象(JSONRPCRequest)
1 2 3 4 5 6 7 8 9
| @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record JSONRPCRequest( @JsonProperty("jsonrpc") String jsonrpc, @JsonProperty("method") String method, @JsonProperty("id") Object id, @JsonProperty("params") Object params ) implements JSONRPCMessage { }
|
作用:定义MCP请求消息的结构
字段说明:
| 字段 |
类型 |
说明 |
示例 |
jsonrpc |
String |
协议版本 |
"2.0" |
method |
String |
请求方法名 |
"initialize", "tools/list", "tools/call" |
id |
Object |
请求ID(用于匹配响应) |
"1", "2", "abc-123" |
params |
Object |
请求参数 |
{}, {"query":"Java"} |
实际请求示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "jsonrpc": "2.0", "method": "initialize", "id": "1", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "Java SDK MCP Client", "version": "1.0.0" } } }
|
转换为Java对象:
1 2 3 4 5 6 7 8 9 10 11 12 13
| JSONRPCRequest request = new JSONRPCRequest( "2.0", "initialize", "1", Map.of( "protocolVersion", "2024-11-05", "capabilities", Map.of(), "clientInfo", Map.of( "name", "Java SDK MCP Client", "version", "1.0.0" ) ) );
|
3. 响应对象(JSONRPCResponse)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record JSONRPCResponse( @JsonProperty("jsonrpc") String jsonrpc, @JsonProperty("id") Object id, @JsonProperty("result") Object result, @JsonProperty("error") JSONRPCError error ) implements JSONRPCMessage { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record JSONRPCError( @JsonProperty("code") int code, @JsonProperty("message") String message, @JsonProperty("data") Object data ) { } }
|
作用:定义MCP响应消息的结构
字段说明:
| 字段 |
类型 |
说明 |
示例 |
jsonrpc |
String |
协议版本 |
"2.0" |
id |
Object |
请求ID(与请求对应) |
"1", "2" |
result |
Object |
成功时的响应结果 |
{...} |
error |
JSONRPCError |
失败时的错误信息 |
{...} |
注意:result 和 error 是互斥的,成功时有 result,失败时有 error。
成功响应示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "jsonrpc": "2.0", "id": "1", "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {}, "resources": {} }, "serverInfo": { "name": "MCP Weather Proxy Server", "version": "1.0.0" } } }
|
失败响应示例:
1 2 3 4 5 6 7 8 9
| { "jsonrpc": "2.0", "id": "1", "error": { "code": -32601, "message": "Method not found", "data": "tools/unknown" } }
|
4. 错误对象(JSONRPCError)
1 2 3 4 5 6
| public record JSONRPCError( @JsonProperty("code") int code, @JsonProperty("message") String message, @JsonProperty("data") Object data ) { }
|
作用:定义错误信息的结构
字段说明:
| 字段 |
类型 |
说明 |
示例 |
code |
int |
错误码 |
-32601, -32700 |
message |
String |
错误描述 |
"Method not found" |
data |
Object |
额外的错误数据 |
"tools/unknown" |
常见错误码:
| 错误码 |
说明 |
-32700 |
Parse error(JSON解析错误) |
-32600 |
Invalid Request(无效请求) |
-32601 |
Method not found(方法不存在) |
-32602 |
Invalid params(无效参数) |
-32603 |
Internal error(内部错误) |
🔧 反序列化方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static JSONRPCMessage deserializeJsonRpcMessage(String jsonText) throws IOException {
log.debug("Received JSON message: {}", jsonText);
var map = objectMapper.readValue(jsonText, MAP_TYPE_REF);
if (map.containsKey("method") && map.containsKey("id")) { return objectMapper.convertValue(map, JSONRPCRequest.class); } else if (map.containsKey("result") || map.containsKey("error")) { return objectMapper.convertValue(map, JSONRPCResponse.class); }
throw new IllegalArgumentException("Cannot deserialize JSONRPCMessage: " + jsonText); }
|
作用:自动识别消息类型并反序列化
判断逻辑:
1 2 3 4 5 6 7 8 9
| JSON消息 │ ├── 包含 "method" 和 "id"? │ ├── 是 → JSONRPCRequest(请求) │ └── 否 ↓ │ ├── 包含 "result" 或 "error"? │ ├── 是 → JSONRPCResponse(响应) │ └── 否 → 抛出异常
|
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| String jsonRequest = """ { "jsonrpc": "2.0", "method": "initialize", "id": "1", "params": {} } """;
JSONRPCMessage message = McpSchemaVO.deserializeJsonRpcMessage(jsonRequest);
if (message instanceof JSONRPCRequest request) { System.out.println("这是请求"); System.out.println("方法: " + request.method()); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| String jsonResponse = """ { "jsonrpc": "2.0", "id": "1", "result": { "protocolVersion": "2024-11-05" } } """;
JSONRPCMessage message = McpSchemaVO.deserializeJsonRpcMessage(jsonResponse);
if (message instanceof JSONRPCResponse response) { System.out.println("这是响应"); System.out.println("结果: " + response.result()); }
|
💡 Jackson注解的作用
1. @JsonProperty
1
| @JsonProperty("jsonrpc") String jsonrpc
|
作用:指定JSON字段名与Java字段名的映射
示例:
1 2 3 4 5 6 7
| public record MyRecord(String jsonrpc) {}
public record MyRecord(@JsonProperty("jsonrpc") String version) {}
|
2. @JsonInclude
1 2 3
| @JsonInclude(JsonInclude.Include.NON_ABSENT) public record JSONRPCRequest(...) { }
|
作用:控制哪些字段包含在序列化结果中
选项说明:
| 选项 |
说明 |
ALWAYS |
总是包含 |
NON_NULL |
不包含null值 |
NON_ABSENT |
不包含Optional.absent()或未设置的值 |
NON_EMPTY |
不包含空值(null、空字符串、空集合) |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| JSONRPCRequest request = new JSONRPCRequest( "2.0", "initialize", null, null );
{ "jsonrpc": "2.0", "method": "initialize" }
|
3. @JsonIgnoreProperties
1 2 3
| @JsonIgnoreProperties(ignoreUnknown = true) public record JSONRPCRequest(...) { }
|
作用:忽略JSON中未知的属性
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| String json = """ { "jsonrpc": "2.0", "method": "initialize", "id": "1", "params": {}, "extraField": "value" // 未定义的字段 } """;
JSONRPCRequest request = objectMapper.readValue(json, JSONRPCRequest.class);
JSONRPCRequest request = objectMapper.readValue(json, JSONRPCRequest.class);
|
🎯 实际应用场景
场景1:接收客户端请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @PostMapping(value = "{gatewayId}/mcp/sse") public Mono<ResponseEntity<Object>> handleMessage(@RequestBody String messageBody) { McpSchemaVO.JSONRPCMessage jsonrpcMessage = McpSchemaVO.deserializeJsonRpcMessage(messageBody); if (jsonrpcMessage instanceof McpSchemaVO.JSONRPCRequest request) { String method = request.method(); Object params = request.params(); return handleRequest(method, params); } return Mono.just(ResponseEntity.ok().build()); }
|
场景2:发送响应给客户端
1 2 3 4 5 6 7 8 9 10 11 12
| public McpSchemaVO.JSONRPCResponse createResponse(Object requestId, Object result) { return new McpSchemaVO.JSONRPCResponse( "2.0", requestId, result, null ); }
String jsonResponse = objectMapper.writeValueAsString(response);
|
场景3:处理错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public McpSchemaVO.JSONRPCResponse createErrorResponse(Object requestId, int code, String message) { return new McpSchemaVO.JSONRPCResponse( "2.0", requestId, null, new McpSchemaVO.JSONRPCResponse.JSONRPCError( code, message, null ) ); }
String errorResponse = objectMapper.writeValueAsString(response);
|
📊 完整的数据流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 客户端 服务端 │ │ │── JSON请求 ──────────────────────▶│ │ { │ │ "jsonrpc":"2.0", │ │ "method":"initialize", │ │ "id":"1", │ │ "params":{...} │ │ } │ │ │ │ │ deserializeJsonRpcMessage() │ │ ↓ │ │ JSONRPCRequest对象 │ │ │ │ 处理业务逻辑 │ │ │ │ ↓ │ │ JSONRPCResponse对象 │ │ │◀──── JSON响应 ────────────────────│ │ { │ │ "jsonrpc":"2.0", │ │ "id":"1", │ │ "result":{...} │ │ } │
|
🎓 设计模式
1. 值对象模式(Value Object)
1 2 3 4 5
| public final class McpSchemaVO { public record JSONRPCRequest(...) implements JSONRPCMessage {} public record JSONRPCResponse(...) implements JSONRPCMessage {} }
|
特点:
- 不可变(immutable)
- 无标识(no identity)
- 可替换(replaceable)
2. 密封接口模式(Sealed Interface)
1 2 3
| public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCResponse { String jsonrpc(); }
|
特点:
- 限制实现类
- 编译时类型检查
- 支持模式匹配(Java 17+)
3. 记录模式(Record)
1 2 3 4 5 6
| public record JSONRPCRequest( @JsonProperty("jsonrpc") String jsonrpc, @JsonProperty("method") String method, @JsonProperty("id") Object id, @JsonProperty("params") Object params ) implements JSONRPCMessage {}
|
特点:
- 自动生成构造器
- 自动生成getter
- 自动生成equals/hashCode/toString
- 不可变
📝 总结
McpSchemaVO 的核心作用
| 作用 |
说明 |
| 协议定义 |
定义MCP协议的消息结构 |
| 类型安全 |
使用密封接口和record确保类型安全 |
| 序列化 |
将Java对象转换为JSON字符串 |
| 反序列化 |
将JSON字符串转换为Java对象 |
| 协议兼容 |
兼容JSON-RPC 2.0协议标准 |
核心组件
| 组件 |
作用 |
关键方法 |
JSONRPCMessage |
消息接口 |
jsonrpc() |
JSONRPCRequest |
请求对象 |
method(), params() |
JSONRPCResponse |
响应对象 |
result(), error() |
JSONRPCError |
错误对象 |
code(), message() |
deserializeJsonRpcMessage() |
反序列化 |
自动识别消息类型 |
使用流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 1. 接收JSON字符串 ↓ 2. 调用 deserializeJsonRpcMessage() ↓ 3. 判断是请求还是响应 ↓ 4. 转换为对应的Java对象 ↓ 5. 处理业务逻辑 ↓ 6. 创建响应对象 ↓ 7. 序列化为JSON字符串 ↓ 8. 发送给客户端
|
这就是 McpSchemaVO.java 的完整作用:定义MCP协议的消息结构,提供类型安全的序列化和反序列化能力!
AI MCP Gateway-定义MCP协议的消息结构