mcp_ectors/messages/mcp/
protocol.rs1
2use mcp_spec::protocol::{ErrorData, JsonRpcError, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse};
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6
7
8
9
10
11#[derive(Debug, Serialize, Deserialize)]
12struct JsonRpcRaw {
13 jsonrpc: String,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 id: Option<u64>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 method: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 params: Option<Value>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 result: Option<Value>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 error: Option<ErrorData>,
24}
25
26
27impl TryFrom<JsonRpcRaw> for JsonRpcMessage {
28 type Error = String;
29
30 fn try_from(raw: JsonRpcRaw) -> Result<Self, <Self as TryFrom<JsonRpcRaw>>::Error> {
31 if raw.error.is_some() {
33 return Ok(JsonRpcMessage::Error(JsonRpcError {
34 jsonrpc: raw.jsonrpc,
35 id: raw.id,
36 error: raw.error.unwrap(),
37 }));
38 }
39
40 if raw.result.is_some() {
42 return Ok(JsonRpcMessage::Response(JsonRpcResponse {
43 jsonrpc: raw.jsonrpc,
44 id: raw.id,
45 result: raw.result,
46 error: None,
47 }));
48 }
49
50 if let Some(method) = raw.method {
52 if raw.id.is_none() {
53 return Ok(JsonRpcMessage::Notification(JsonRpcNotification {
54 jsonrpc: raw.jsonrpc,
55 method,
56 params: raw.params,
57 }));
58 }
59
60 return Ok(JsonRpcMessage::Request(JsonRpcRequest {
61 jsonrpc: raw.jsonrpc,
62 id: raw.id,
63 method,
64 params: raw.params,
65 }));
66 }
67
68 if raw.id.is_none() && raw.result.is_none() && raw.error.is_none() {
70 return Ok(JsonRpcMessage::Nil);
71 }
72
73 Err(format!(
75 "Invalid JSON-RPC message format: id={:?}, method={:?}, result={:?}, error={:?}",
76 raw.id, raw.method, raw.result, raw.error
77 ))
78 }
79}
80
81pub const PARSE_ERROR: i32 = -32700;
83pub const INVALID_REQUEST: i32 = -32600;
84pub const METHOD_NOT_FOUND: i32 = -32601;
85pub const INVALID_PARAMS: i32 = -32602;
86pub const INTERNAL_ERROR: i32 = -32603;
87#[derive(Debug, Serialize, Deserialize)]
131pub struct EmptyResult {}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use serde_json::json;
137
138 #[test]
139 fn test_notification_conversion() {
140 let raw = JsonRpcRaw {
141 jsonrpc: "2.0".to_string(),
142 id: None,
143 method: Some("notify".to_string()),
144 params: Some(json!({"key": "value"})),
145 result: None,
146 error: None,
147 };
148
149 let message = JsonRpcMessage::try_from(raw).unwrap();
150 match message {
151 JsonRpcMessage::Notification(n) => {
152 assert_eq!(n.jsonrpc, "2.0");
153 assert_eq!(n.method, "notify");
154 assert_eq!(n.params.unwrap(), json!({"key": "value"}));
155 }
156 _ => panic!("Expected Notification"),
157 }
158 }
159
160 #[test]
161 fn test_request_conversion() {
162 let raw = JsonRpcRaw {
163 jsonrpc: "2.0".to_string(),
164 id: Some(1),
165 method: Some("request".to_string()),
166 params: Some(json!({"key": "value"})),
167 result: None,
168 error: None,
169 };
170
171 let message = JsonRpcMessage::try_from(raw).unwrap();
172 match message {
173 JsonRpcMessage::Request(r) => {
174 assert_eq!(r.jsonrpc, "2.0");
175 assert_eq!(r.id, Some(1));
176 assert_eq!(r.method, "request");
177 assert_eq!(r.params.unwrap(), json!({"key": "value"}));
178 }
179 _ => panic!("Expected Request"),
180 }
181 }
182}