1use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::error::ErrorData;
6
7pub const JSONRPC_VERSION: &str = "2.0";
8pub const MCP_PROTOCOL_VERSION: &str = "2024-11-05";
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(untagged)]
13pub enum RequestId {
14 String(String),
15 Number(i64),
16}
17
18impl std::fmt::Display for RequestId {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 Self::String(s) => write!(f, "{s}"),
22 Self::Number(n) => write!(f, "{n}"),
23 }
24 }
25}
26
27impl From<i64> for RequestId {
28 fn from(n: i64) -> Self {
29 Self::Number(n)
30 }
31}
32
33impl From<String> for RequestId {
34 fn from(s: String) -> Self {
35 Self::String(s)
36 }
37}
38
39impl From<&str> for RequestId {
40 fn from(s: &str) -> Self {
41 Self::String(s.to_owned())
42 }
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct JsonRpcRequest {
48 pub jsonrpc: String,
49 pub id: RequestId,
50 pub method: String,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub params: Option<Value>,
53}
54
55impl JsonRpcRequest {
56 pub fn new(id: impl Into<RequestId>, method: impl Into<String>, params: Option<Value>) -> Self {
57 Self {
58 jsonrpc: JSONRPC_VERSION.to_owned(),
59 id: id.into(),
60 method: method.into(),
61 params,
62 }
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct JsonRpcResponse {
69 pub jsonrpc: String,
70 pub id: RequestId,
71 pub result: Value,
72}
73
74impl JsonRpcResponse {
75 pub fn new(id: RequestId, result: impl Serialize) -> Result<Self, serde_json::Error> {
76 Ok(Self {
77 jsonrpc: JSONRPC_VERSION.to_owned(),
78 id,
79 result: serde_json::to_value(result)?,
80 })
81 }
82
83 pub fn ok(id: RequestId) -> Self {
84 Self {
85 jsonrpc: JSONRPC_VERSION.to_owned(),
86 id,
87 result: Value::Object(Default::default()),
88 }
89 }
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct JsonRpcError {
95 pub jsonrpc: String,
96 pub id: RequestId,
97 pub error: ErrorData,
98}
99
100impl JsonRpcError {
101 pub fn new(id: RequestId, error: impl Into<ErrorData>) -> Self {
102 Self {
103 jsonrpc: JSONRPC_VERSION.to_owned(),
104 id,
105 error: error.into(),
106 }
107 }
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct JsonRpcNotification {
113 pub jsonrpc: String,
114 pub method: String,
115 #[serde(default, skip_serializing_if = "Option::is_none")]
116 pub params: Option<Value>,
117}
118
119impl JsonRpcNotification {
120 pub fn new(method: impl Into<String>, params: Option<Value>) -> Self {
121 Self {
122 jsonrpc: JSONRPC_VERSION.to_owned(),
123 method: method.into(),
124 params,
125 }
126 }
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
131#[serde(untagged)]
132pub enum JsonRpcMessage {
133 Request(JsonRpcRequest),
134 Response(JsonRpcResponse),
135 Error(JsonRpcError),
136 Notification(JsonRpcNotification),
137}
138
139impl JsonRpcMessage {
140 pub fn is_request(&self) -> bool {
141 matches!(self, Self::Request(_))
142 }
143
144 pub fn is_notification(&self) -> bool {
145 matches!(self, Self::Notification(_))
146 }
147
148 pub fn method(&self) -> Option<&str> {
149 match self {
150 Self::Request(r) => Some(&r.method),
151 Self::Notification(n) => Some(&n.method),
152 _ => None,
153 }
154 }
155
156 pub fn id(&self) -> Option<&RequestId> {
157 match self {
158 Self::Request(r) => Some(&r.id),
159 Self::Response(r) => Some(&r.id),
160 Self::Error(e) => Some(&e.id),
161 Self::Notification(_) => None,
162 }
163 }
164
165 pub fn into_request(self) -> Option<JsonRpcRequest> {
166 match self {
167 Self::Request(r) => Some(r),
168 _ => None,
169 }
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
175#[serde(untagged)]
176pub enum ProgressToken {
177 String(String),
178 Number(i64),
179}