1use serde::{Deserialize, Serialize};
21use serde_json::Value;
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct JsonRpcRequest {
26 pub jsonrpc: String,
28 pub id: Option<Value>,
30 pub method: String,
32 #[serde(default)]
34 pub params: Option<Value>,
35}
36
37impl JsonRpcRequest {
38 pub fn validate(&self) -> Result<(), String> {
68 if self.jsonrpc != "2.0" {
70 return Err(format!(
71 "Invalid JSON-RPC version: expected '2.0', got '{}'",
72 self.jsonrpc
73 ));
74 }
75
76 if let Some(id) = &self.id {
78 match id {
79 Value::String(_) | Value::Number(_) | Value::Null => {}
80 _ => return Err("Invalid request id: must be string, number, or null".to_string()),
81 }
82 }
83
84 if self.method.is_empty() {
86 return Err("Method name cannot be empty".to_string());
87 }
88 if self.method.contains(char::is_whitespace) {
89 return Err("Method name cannot contain whitespace".to_string());
90 }
91
92 if let Some(params) = &self.params {
94 if !params.is_object() && !params.is_array() {
95 return Err("Params must be an object or array".to_string());
96 }
97 }
98
99 Ok(())
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct JsonRpcResponse {
106 pub jsonrpc: String,
108 #[serde(skip_serializing_if = "Option::is_none")]
110 pub id: Option<Value>,
111 #[serde(skip_serializing_if = "Option::is_none")]
113 pub result: Option<Value>,
114 #[serde(skip_serializing_if = "Option::is_none")]
116 pub error: Option<JsonRpcError>,
117}
118
119impl JsonRpcResponse {
120 #[must_use]
122 pub fn success(id: Option<Value>, result: Value) -> Self {
123 Self {
124 jsonrpc: "2.0".to_string(),
125 id,
126 result: Some(result),
127 error: None,
128 }
129 }
130
131 #[must_use]
133 pub fn error(id: Option<Value>, code: i32, message: String, data: Option<Value>) -> Self {
134 Self {
135 jsonrpc: "2.0".to_string(),
136 id,
137 result: None,
138 error: Some(JsonRpcError {
139 code,
140 message,
141 data,
142 }),
143 }
144 }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct JsonRpcError {
150 pub code: i32,
152 pub message: String,
154 #[serde(skip_serializing_if = "Option::is_none")]
156 pub data: Option<Value>,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct ServerCapabilities {
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub tools: Option<ToolsCapability>,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub resources: Option<ResourcesCapability>,
170 #[serde(skip_serializing_if = "Option::is_none")]
172 pub prompts: Option<PromptsCapability>,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct ToolsCapability {
178 #[serde(rename = "listChanged", skip_serializing_if = "Option::is_none")]
180 pub list_changed: Option<bool>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct ResourcesCapability {
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub subscribe: Option<bool>,
189 #[serde(rename = "listChanged", skip_serializing_if = "Option::is_none")]
191 pub list_changed: Option<bool>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct PromptsCapability {
197 #[serde(rename = "listChanged", skip_serializing_if = "Option::is_none")]
199 pub list_changed: Option<bool>,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
204pub struct InitializeParams {
205 #[serde(rename = "protocolVersion")]
207 pub protocol_version: String,
208 pub capabilities: ClientCapabilities,
210 #[serde(rename = "clientInfo")]
212 pub client_info: ClientInfo,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize, Default)]
217pub struct ClientCapabilities {
218 #[serde(skip_serializing_if = "Option::is_none")]
220 pub roots: Option<RootsCapability>,
221 #[serde(skip_serializing_if = "Option::is_none")]
223 pub sampling: Option<Value>,
224}
225
226#[derive(Debug, Clone, Serialize, Deserialize)]
228pub struct RootsCapability {
229 #[serde(rename = "listChanged", skip_serializing_if = "Option::is_none")]
231 pub list_changed: Option<bool>,
232}
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct ClientInfo {
237 pub name: String,
239 pub version: String,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct InitializeResult {
246 #[serde(rename = "protocolVersion")]
248 pub protocol_version: String,
249 pub capabilities: ServerCapabilities,
251 #[serde(rename = "serverInfo")]
253 pub server_info: ServerInfo,
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct ServerInfo {
259 pub name: String,
261 pub version: String,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct Tool {
268 pub name: String,
270 pub description: String,
272 #[serde(rename = "inputSchema")]
274 pub input_schema: Value,
275}
276
277#[derive(Debug, Clone, Serialize, Deserialize)]
279pub struct CallToolParams {
280 pub name: String,
282 #[serde(default)]
284 pub arguments: Option<Value>,
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct CallToolResult {
290 pub content: Vec<Content>,
292 #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
294 pub is_error: Option<bool>,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
299#[serde(tag = "type")]
300pub enum Content {
301 #[serde(rename = "text")]
303 Text {
304 text: String,
306 },
307 #[serde(rename = "resource")]
309 Resource {
310 resource: ResourceContent,
312 },
313}
314
315#[derive(Debug, Clone, Serialize, Deserialize)]
317pub struct ResourceContent {
318 pub uri: String,
320 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
322 pub mime_type: Option<String>,
323 #[serde(skip_serializing_if = "Option::is_none")]
325 pub text: Option<String>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
330pub struct Resource {
331 pub uri: String,
333 pub name: String,
335 #[serde(skip_serializing_if = "Option::is_none")]
337 pub description: Option<String>,
338 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
340 pub mime_type: Option<String>,
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
345pub struct ListToolsResult {
346 pub tools: Vec<Tool>,
348}
349
350#[derive(Debug, Clone, Serialize, Deserialize)]
352pub struct ListResourcesResult {
353 pub resources: Vec<Resource>,
355}
356
357#[derive(Debug, Clone, Serialize, Deserialize)]
359pub struct ReadResourceParams {
360 pub uri: String,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct ReadResourceResult {
367 pub contents: Vec<ResourceContent>,
369}