1use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use serde_json::Value;
8use std::fmt;
9
10use crate::types::RequestId;
11
12pub const JSONRPC_VERSION: &str = "2.0";
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct JsonRpcVersion;
18
19impl Serialize for JsonRpcVersion {
20 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21 where
22 S: Serializer,
23 {
24 serializer.serialize_str(JSONRPC_VERSION)
25 }
26}
27
28impl<'de> Deserialize<'de> for JsonRpcVersion {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'de>,
32 {
33 let version = String::deserialize(deserializer)?;
34 if version == JSONRPC_VERSION {
35 Ok(JsonRpcVersion)
36 } else {
37 Err(serde::de::Error::custom(format!(
38 "Invalid JSON-RPC version: expected '{JSONRPC_VERSION}', got '{version}'"
39 )))
40 }
41 }
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct JsonRpcRequest {
47 pub jsonrpc: JsonRpcVersion,
49 pub method: String,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub params: Option<Value>,
54 pub id: RequestId,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(untagged)]
61pub enum JsonRpcResponsePayload {
62 Success {
64 result: Value,
66 },
67 Error {
69 error: JsonRpcError,
71 },
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct JsonRpcResponse {
77 pub jsonrpc: JsonRpcVersion,
79 #[serde(flatten)]
81 pub payload: JsonRpcResponsePayload,
82 pub id: ResponseId,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88#[serde(transparent)]
89pub struct ResponseId(pub Option<RequestId>);
90
91impl ResponseId {
92 pub fn from_request(id: RequestId) -> Self {
94 Self(Some(id))
95 }
96
97 pub fn null() -> Self {
99 Self(None)
100 }
101
102 pub fn as_request_id(&self) -> Option<&RequestId> {
104 self.0.as_ref()
105 }
106
107 pub fn is_null(&self) -> bool {
109 self.0.is_none()
110 }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct JsonRpcNotification {
116 pub jsonrpc: JsonRpcVersion,
118 pub method: String,
120 #[serde(skip_serializing_if = "Option::is_none")]
122 pub params: Option<Value>,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
127pub struct JsonRpcError {
128 pub code: i32,
130 pub message: String,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub data: Option<Value>,
135}
136
137impl JsonRpcError {
138 pub fn new(code: i32, message: impl Into<String>) -> Self {
140 Self {
141 code,
142 message: message.into(),
143 data: None,
144 }
145 }
146
147 pub fn with_data(code: i32, message: impl Into<String>, data: Value) -> Self {
149 Self {
150 code,
151 message: message.into(),
152 data: Some(data),
153 }
154 }
155
156 pub fn parse_error() -> Self {
158 Self::new(-32700, "Parse error")
159 }
160
161 pub fn parse_error_with_details(details: impl Into<String>) -> Self {
163 Self::with_data(
164 -32700,
165 "Parse error",
166 serde_json::json!({ "details": details.into() }),
167 )
168 }
169
170 pub fn invalid_request() -> Self {
172 Self::new(-32600, "Invalid Request")
173 }
174
175 pub fn invalid_request_with_reason(reason: impl Into<String>) -> Self {
177 Self::with_data(
178 -32600,
179 "Invalid Request",
180 serde_json::json!({ "reason": reason.into() }),
181 )
182 }
183
184 pub fn method_not_found(method: &str) -> Self {
186 Self::new(-32601, format!("Method not found: {method}"))
187 }
188
189 pub fn invalid_params(details: &str) -> Self {
191 Self::new(-32602, format!("Invalid params: {details}"))
192 }
193
194 pub fn internal_error(details: &str) -> Self {
196 Self::new(-32603, format!("Internal error: {details}"))
197 }
198
199 pub fn is_parse_error(&self) -> bool {
201 self.code == -32700
202 }
203
204 pub fn is_invalid_request(&self) -> bool {
206 self.code == -32600
207 }
208
209 pub fn code(&self) -> i32 {
211 self.code
212 }
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
223#[serde(transparent)]
224#[deprecated(
225 since = "2.2.3",
226 note = "JSON-RPC batching removed from MCP 2025-06-18 spec (PR #416). This type exists only for defensive handling and will be removed."
227)]
228pub struct JsonRpcBatch<T> {
229 pub items: Vec<T>,
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
235pub enum JsonRpcErrorCode {
236 ParseError,
238 InvalidRequest,
240 MethodNotFound,
242 InvalidParams,
244 InternalError,
246 ApplicationError(i32),
248}
249
250impl JsonRpcErrorCode {
251 pub fn code(&self) -> i32 {
253 match self {
254 Self::ParseError => -32700,
255 Self::InvalidRequest => -32600,
256 Self::MethodNotFound => -32601,
257 Self::InvalidParams => -32602,
258 Self::InternalError => -32603,
259 Self::ApplicationError(code) => *code,
260 }
261 }
262
263 pub fn message(&self) -> &'static str {
265 match self {
266 Self::ParseError => "Parse error",
267 Self::InvalidRequest => "Invalid Request",
268 Self::MethodNotFound => "Method not found",
269 Self::InvalidParams => "Invalid params",
270 Self::InternalError => "Internal error",
271 Self::ApplicationError(_) => "Application error",
272 }
273 }
274}
275
276impl fmt::Display for JsonRpcErrorCode {
277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278 write!(f, "{} ({})", self.message(), self.code())
279 }
280}
281
282impl From<JsonRpcErrorCode> for JsonRpcError {
283 fn from(code: JsonRpcErrorCode) -> Self {
284 Self {
285 code: code.code(),
286 message: code.message().to_string(),
287 data: None,
288 }
289 }
290}
291
292impl From<i32> for JsonRpcErrorCode {
293 fn from(code: i32) -> Self {
294 match code {
295 -32700 => Self::ParseError,
296 -32600 => Self::InvalidRequest,
297 -32601 => Self::MethodNotFound,
298 -32602 => Self::InvalidParams,
299 -32603 => Self::InternalError,
300 other => Self::ApplicationError(other),
301 }
302 }
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize)]
311#[serde(untagged)]
312pub enum JsonRpcMessage {
313 Request(JsonRpcRequest),
315 Response(JsonRpcResponse),
317 Notification(JsonRpcNotification),
319 #[deprecated(since = "2.2.3", note = "Batching removed from MCP spec")]
324 #[allow(deprecated)] RequestBatch(JsonRpcBatch<JsonRpcRequest>),
326 #[deprecated(since = "2.2.3", note = "Batching removed from MCP spec")]
331 #[allow(deprecated)] ResponseBatch(JsonRpcBatch<JsonRpcResponse>),
333 #[deprecated(since = "2.2.3", note = "Batching removed from MCP spec")]
338 #[allow(deprecated)] MessageBatch(JsonRpcBatch<JsonRpcMessage>),
340}
341
342impl JsonRpcRequest {
343 pub fn new(method: String, params: Option<Value>, id: RequestId) -> Self {
345 Self {
346 jsonrpc: JsonRpcVersion,
347 method,
348 params,
349 id,
350 }
351 }
352
353 pub fn without_params(method: String, id: RequestId) -> Self {
355 Self::new(method, None, id)
356 }
357
358 pub fn with_params<P: Serialize>(
360 method: String,
361 params: P,
362 id: RequestId,
363 ) -> Result<Self, serde_json::Error> {
364 let params_value = serde_json::to_value(params)?;
365 Ok(Self::new(method, Some(params_value), id))
366 }
367}
368
369impl JsonRpcResponse {
370 pub fn success(result: Value, id: RequestId) -> Self {
372 Self {
373 jsonrpc: JsonRpcVersion,
374 payload: JsonRpcResponsePayload::Success { result },
375 id: ResponseId::from_request(id),
376 }
377 }
378
379 pub fn error_response(error: JsonRpcError, id: RequestId) -> Self {
381 Self {
382 jsonrpc: JsonRpcVersion,
383 payload: JsonRpcResponsePayload::Error { error },
384 id: ResponseId::from_request(id),
385 }
386 }
387
388 pub fn parse_error(message: Option<String>) -> Self {
390 let error = JsonRpcError {
391 code: JsonRpcErrorCode::ParseError.code(),
392 message: message.unwrap_or_else(|| JsonRpcErrorCode::ParseError.message().to_string()),
393 data: None,
394 };
395 Self {
396 jsonrpc: JsonRpcVersion,
397 payload: JsonRpcResponsePayload::Error { error },
398 id: ResponseId::null(),
399 }
400 }
401
402 pub fn is_success(&self) -> bool {
404 matches!(self.payload, JsonRpcResponsePayload::Success { .. })
405 }
406
407 pub fn is_error(&self) -> bool {
409 matches!(self.payload, JsonRpcResponsePayload::Error { .. })
410 }
411
412 pub fn result(&self) -> Option<&Value> {
414 match &self.payload {
415 JsonRpcResponsePayload::Success { result } => Some(result),
416 JsonRpcResponsePayload::Error { .. } => None,
417 }
418 }
419
420 pub fn error(&self) -> Option<&JsonRpcError> {
422 match &self.payload {
423 JsonRpcResponsePayload::Success { .. } => None,
424 JsonRpcResponsePayload::Error { error } => Some(error),
425 }
426 }
427
428 pub fn request_id(&self) -> Option<&RequestId> {
430 self.id.as_request_id()
431 }
432
433 pub fn is_parse_error(&self) -> bool {
435 self.id.is_null()
436 }
437
438 pub fn result_mut(&mut self) -> Option<&mut Value> {
440 match &mut self.payload {
441 JsonRpcResponsePayload::Success { result } => Some(result),
442 JsonRpcResponsePayload::Error { .. } => None,
443 }
444 }
445
446 pub fn error_mut(&mut self) -> Option<&mut JsonRpcError> {
448 match &mut self.payload {
449 JsonRpcResponsePayload::Success { .. } => None,
450 JsonRpcResponsePayload::Error { error } => Some(error),
451 }
452 }
453
454 pub fn set_result(&mut self, result: Value) {
456 self.payload = JsonRpcResponsePayload::Success { result };
457 }
458
459 pub fn set_error(&mut self, error: JsonRpcError) {
461 self.payload = JsonRpcResponsePayload::Error { error };
462 }
463}
464
465impl JsonRpcNotification {
466 pub fn new(method: String, params: Option<Value>) -> Self {
468 Self {
469 jsonrpc: JsonRpcVersion,
470 method,
471 params,
472 }
473 }
474
475 pub fn without_params(method: String) -> Self {
477 Self::new(method, None)
478 }
479
480 pub fn with_params<P: Serialize>(method: String, params: P) -> Result<Self, serde_json::Error> {
482 let params_value = serde_json::to_value(params)?;
483 Ok(Self::new(method, Some(params_value)))
484 }
485}
486
487#[allow(deprecated)]
490impl<T> JsonRpcBatch<T> {
491 pub fn new(items: Vec<T>) -> Self {
493 Self { items }
494 }
495
496 pub fn empty() -> Self {
498 Self::new(Vec::new())
499 }
500
501 pub fn push(&mut self, item: T) {
503 self.items.push(item);
504 }
505
506 pub fn len(&self) -> usize {
508 self.items.len()
509 }
510
511 pub fn is_empty(&self) -> bool {
513 self.items.is_empty()
514 }
515
516 pub fn iter(&self) -> impl Iterator<Item = &T> {
518 self.items.iter()
519 }
520}
521
522#[allow(deprecated)]
523impl<T> IntoIterator for JsonRpcBatch<T> {
524 type Item = T;
525 type IntoIter = std::vec::IntoIter<T>;
526
527 fn into_iter(self) -> Self::IntoIter {
528 self.items.into_iter()
529 }
530}
531
532#[allow(deprecated)]
533impl<T> From<Vec<T>> for JsonRpcBatch<T> {
534 fn from(items: Vec<T>) -> Self {
535 Self::new(items)
536 }
537}
538
539pub mod utils {
541 use super::*;
542
543 pub fn parse_message(json: &str) -> Result<JsonRpcMessage, serde_json::Error> {
545 serde_json::from_str(json)
546 }
547
548 pub fn serialize_message(message: &JsonRpcMessage) -> Result<String, serde_json::Error> {
550 serde_json::to_string(message)
551 }
552
553 pub fn is_batch(json: &str) -> bool {
555 json.trim_start().starts_with('[')
556 }
557
558 pub fn extract_method(json: &str) -> Option<String> {
560 if let Ok(value) = serde_json::from_str::<serde_json::Value>(json)
562 && let Some(method) = value.get("method")
563 {
564 return method.as_str().map(String::from);
565 }
566 None
567 }
568}
569
570pub mod http {
592 use serde::{Deserialize, Serialize};
593 use serde_json::Value;
594
595 #[derive(Debug, Clone, Serialize, Deserialize)]
600 pub struct HttpJsonRpcRequest {
601 pub jsonrpc: String,
603 #[serde(default)]
605 pub id: Option<Value>,
606 pub method: String,
608 #[serde(default)]
610 pub params: Option<Value>,
611 }
612
613 impl HttpJsonRpcRequest {
614 pub fn is_valid(&self) -> bool {
616 self.jsonrpc == "2.0" && !self.method.is_empty()
617 }
618
619 pub fn is_notification(&self) -> bool {
621 self.id.is_none()
622 }
623
624 pub fn id_string(&self) -> Option<String> {
626 self.id.as_ref().map(|v| match v {
627 Value::String(s) => s.clone(),
628 Value::Number(n) => n.to_string(),
629 _ => v.to_string(),
630 })
631 }
632 }
633
634 #[derive(Debug, Clone, Serialize, Deserialize)]
639 pub struct HttpJsonRpcResponse {
640 pub jsonrpc: String,
642 #[serde(default)]
644 pub id: Option<Value>,
645 #[serde(skip_serializing_if = "Option::is_none")]
647 pub result: Option<Value>,
648 #[serde(skip_serializing_if = "Option::is_none")]
650 pub error: Option<super::JsonRpcError>,
651 }
652
653 impl HttpJsonRpcResponse {
654 pub fn success(id: Option<Value>, result: Value) -> Self {
656 Self {
657 jsonrpc: "2.0".to_string(),
658 id,
659 result: Some(result),
660 error: None,
661 }
662 }
663
664 pub fn error(id: Option<Value>, error: super::JsonRpcError) -> Self {
666 Self {
667 jsonrpc: "2.0".to_string(),
668 id,
669 result: None,
670 error: Some(error),
671 }
672 }
673
674 pub fn error_from_code(id: Option<Value>, code: i32, message: impl Into<String>) -> Self {
676 Self::error(id, super::JsonRpcError::new(code, message))
677 }
678
679 pub fn invalid_request(id: Option<Value>, reason: impl Into<String>) -> Self {
681 Self::error(id, super::JsonRpcError::invalid_request_with_reason(reason))
682 }
683
684 pub fn parse_error(details: Option<String>) -> Self {
686 Self::error(
687 None,
688 details
689 .map(super::JsonRpcError::parse_error_with_details)
690 .unwrap_or_else(super::JsonRpcError::parse_error),
691 )
692 }
693
694 pub fn internal_error(id: Option<Value>, details: &str) -> Self {
696 Self::error(id, super::JsonRpcError::internal_error(details))
697 }
698
699 pub fn method_not_found(id: Option<Value>, method: &str) -> Self {
701 Self::error(id, super::JsonRpcError::method_not_found(method))
702 }
703
704 pub fn is_error(&self) -> bool {
706 self.error.is_some()
707 }
708
709 pub fn is_success(&self) -> bool {
711 self.result.is_some() && self.error.is_none()
712 }
713 }
714
715 #[cfg(test)]
716 mod tests {
717 use super::*;
718
719 #[test]
720 fn test_http_request_parsing() {
721 let json = r#"{"jsonrpc":"2.0","method":"test","id":1,"params":{"key":"value"}}"#;
722 let request: HttpJsonRpcRequest = serde_json::from_str(json).unwrap();
723 assert!(request.is_valid());
724 assert!(!request.is_notification());
725 assert_eq!(request.method, "test");
726 }
727
728 #[test]
729 fn test_http_request_invalid_version() {
730 let json = r#"{"jsonrpc":"1.0","method":"test","id":1}"#;
731 let request: HttpJsonRpcRequest = serde_json::from_str(json).unwrap();
732 assert!(!request.is_valid());
733 }
734
735 #[test]
736 fn test_http_response_success() {
737 let response = HttpJsonRpcResponse::success(
738 Some(Value::Number(1.into())),
739 serde_json::json!({"result": "ok"}),
740 );
741 assert!(response.is_success());
742 assert!(!response.is_error());
743 }
744
745 #[test]
746 fn test_http_response_error() {
747 let response = HttpJsonRpcResponse::invalid_request(
748 Some(Value::String("req-1".into())),
749 "jsonrpc must be 2.0",
750 );
751 assert!(!response.is_success());
752 assert!(response.is_error());
753 }
754
755 #[test]
756 fn test_http_response_serialization() {
757 let response = HttpJsonRpcResponse::success(
758 Some(Value::Number(1.into())),
759 serde_json::json!({"data": "test"}),
760 );
761 let json = serde_json::to_string(&response).unwrap();
762 assert!(json.contains(r#""jsonrpc":"2.0""#));
763 assert!(json.contains(r#""result""#));
764 assert!(!json.contains(r#""error""#));
765 }
766 }
767}
768
769#[cfg(test)]
770#[allow(deprecated)] mod tests {
772 use super::*;
773 use serde_json::json;
774
775 #[test]
776 fn test_jsonrpc_version() {
777 let version = JsonRpcVersion;
778 let json = serde_json::to_string(&version).unwrap();
779 assert_eq!(json, "\"2.0\"");
780
781 let parsed: JsonRpcVersion = serde_json::from_str(&json).unwrap();
782 assert_eq!(parsed, version);
783 }
784
785 #[test]
786 fn test_request_creation() {
787 let request = JsonRpcRequest::new(
788 "test_method".to_string(),
789 Some(json!({"key": "value"})),
790 RequestId::String("test-id".to_string()),
791 );
792
793 assert_eq!(request.method, "test_method");
794 assert!(request.params.is_some());
795 }
796
797 #[test]
798 fn test_response_creation() {
799 let response = JsonRpcResponse::success(
800 json!({"result": "success"}),
801 RequestId::String("test-id".to_string()),
802 );
803
804 assert!(response.is_success());
805 assert!(!response.is_error());
806 assert!(response.result().is_some());
807 assert!(response.error().is_none());
808 assert!(!response.is_parse_error());
809 }
810
811 #[test]
812 fn test_error_response() {
813 let error = JsonRpcError::from(JsonRpcErrorCode::MethodNotFound);
814 let response =
815 JsonRpcResponse::error_response(error, RequestId::String("test-id".to_string()));
816
817 assert!(!response.is_success());
818 assert!(response.is_error());
819 assert!(response.result().is_none());
820 assert!(response.error().is_some());
821 assert!(!response.is_parse_error());
822 }
823
824 #[test]
825 fn test_parse_error_response() {
826 let response = JsonRpcResponse::parse_error(Some("Invalid JSON".to_string()));
827
828 assert!(!response.is_success());
829 assert!(response.is_error());
830 assert!(response.result().is_none());
831 assert!(response.error().is_some());
832 assert!(response.is_parse_error());
833 assert!(response.request_id().is_none());
834
835 let error = response.error().unwrap();
837 assert_eq!(error.code, JsonRpcErrorCode::ParseError.code());
838 assert_eq!(error.message, "Invalid JSON");
839 }
840
841 #[test]
842 fn test_notification() {
843 let notification = JsonRpcNotification::without_params("test_notification".to_string());
844 assert_eq!(notification.method, "test_notification");
845 assert!(notification.params.is_none());
846 }
847
848 #[test]
849 fn test_batch() {
850 let mut batch = JsonRpcBatch::<JsonRpcRequest>::empty();
851 assert!(batch.is_empty());
852
853 batch.push(JsonRpcRequest::without_params(
854 "method1".to_string(),
855 RequestId::String("1".to_string()),
856 ));
857 batch.push(JsonRpcRequest::without_params(
858 "method2".to_string(),
859 RequestId::String("2".to_string()),
860 ));
861
862 assert_eq!(batch.len(), 2);
863 assert!(!batch.is_empty());
864 }
865
866 #[test]
867 fn test_serialization() {
868 let request = JsonRpcRequest::new(
869 "test_method".to_string(),
870 Some(json!({"param": "value"})),
871 RequestId::String("123".to_string()),
872 );
873
874 let json = serde_json::to_string(&request).unwrap();
875 let parsed: JsonRpcRequest = serde_json::from_str(&json).unwrap();
876
877 assert_eq!(parsed.method, request.method);
878 assert_eq!(parsed.params, request.params);
879 }
880
881 #[test]
882 fn test_utils() {
883 let json = r#"{"jsonrpc":"2.0","method":"test","id":"123"}"#;
884
885 assert!(!utils::is_batch(json));
886 assert_eq!(utils::extract_method(json), Some("test".to_string()));
887
888 let batch_json = r#"[{"jsonrpc":"2.0","method":"test","id":"123"}]"#;
889 assert!(utils::is_batch(batch_json));
890 }
891
892 #[test]
893 fn test_error_codes() {
894 let parse_error = JsonRpcErrorCode::ParseError;
895 assert_eq!(parse_error.code(), -32700);
896 assert_eq!(parse_error.message(), "Parse error");
897
898 let app_error = JsonRpcErrorCode::ApplicationError(-32001);
899 assert_eq!(app_error.code(), -32001);
900 }
901}