1use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct JsonRpcRequest {
13 pub jsonrpc: String,
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub id: Option<serde_json::Value>,
18 pub method: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub params: Option<serde_json::Value>,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct JsonRpcResponse {
28 pub jsonrpc: String,
30 pub id: Option<serde_json::Value>,
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub result: Option<serde_json::Value>,
35 #[serde(skip_serializing_if = "Option::is_none")]
37 pub error: Option<JsonRpcError>,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct JsonRpcError {
43 pub code: i32,
45 pub message: String,
47 #[serde(skip_serializing_if = "Option::is_none")]
49 pub data: Option<serde_json::Value>,
50}
51
52impl JsonRpcRequest {
53 pub fn new(
55 method: &str,
56 params: Option<serde_json::Value>,
57 id: Option<serde_json::Value>,
58 ) -> Self {
59 Self {
60 jsonrpc: "2.0".to_string(),
61 method: method.to_string(),
62 params,
63 id,
64 }
65 }
66
67 pub fn notification(method: &str, params: Option<serde_json::Value>) -> Self {
69 Self::new(method, params, None)
70 }
71
72 pub fn with_id(method: &str, params: Option<serde_json::Value>, id: &str) -> Self {
74 Self::new(
75 method,
76 params,
77 Some(serde_json::Value::String(id.to_string())),
78 )
79 }
80}
81
82impl JsonRpcResponse {
83 pub fn success(id: Option<serde_json::Value>, result: serde_json::Value) -> Self {
85 Self {
86 jsonrpc: "2.0".to_string(),
87 id,
88 result: Some(result),
89 error: None,
90 }
91 }
92
93 pub fn error(id: Option<serde_json::Value>, error: JsonRpcError) -> Self {
95 Self {
96 jsonrpc: "2.0".to_string(),
97 id,
98 result: None,
99 error: Some(error),
100 }
101 }
102}
103
104impl JsonRpcError {
105 pub fn method_not_found(message: &str) -> Self {
107 Self {
108 code: -32601,
109 message: message.to_string(),
110 data: None,
111 }
112 }
113
114 pub fn invalid_params(message: &str) -> Self {
116 Self {
117 code: -32602,
118 message: message.to_string(),
119 data: None,
120 }
121 }
122
123 pub fn internal_error(message: &str) -> Self {
125 Self {
126 code: -32603,
127 message: message.to_string(),
128 data: None,
129 }
130 }
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
137#[serde(rename_all = "camelCase")]
138pub struct InitializeRequest {
139 #[serde(alias = "protocol_version")]
141 pub protocol_version: String,
142 pub capabilities: ClientCapabilities,
144 #[serde(alias = "client_info")]
146 pub client_info: ClientInfo,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase")]
152pub struct InitializeResult {
153 #[serde(alias = "protocol_version")]
155 pub protocol_version: String,
156 pub capabilities: ServerCapabilities,
158 #[serde(alias = "server_info")]
160 pub server_info: ServerInfo,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct ClientInfo {
167 pub name: String,
169 pub version: String,
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub description: Option<String>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(rename_all = "camelCase")]
179pub struct ServerInfo {
180 pub name: String,
182 pub version: String,
184 #[serde(skip_serializing_if = "Option::is_none")]
186 pub description: Option<String>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize, Default)]
191#[serde(rename_all = "camelCase")]
192pub struct ClientCapabilities {
193 #[serde(skip_serializing_if = "Option::is_none")]
195 pub tools: Option<ToolCapabilities>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, Default)]
200#[serde(rename_all = "camelCase")]
201pub struct ServerCapabilities {
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub tools: Option<ToolCapabilities>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
209#[serde(rename_all = "camelCase")]
210pub struct ToolCapabilities {
211 pub supported: bool,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct ListToolsResult {
220 pub tools: Vec<Tool>,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
226#[serde(rename_all = "camelCase")]
227pub struct Tool {
228 pub name: String,
230 pub description: String,
232 #[serde(alias = "input_schema")]
234 pub input_schema: serde_json::Value,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct CallToolRequest {
240 pub name: String,
242 #[serde(skip_serializing_if = "Option::is_none")]
244 pub arguments: Option<serde_json::Value>,
245 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
247 pub meta: Option<serde_json::Value>,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize)]
252#[serde(rename_all = "camelCase")]
253pub struct CallToolResult {
254 pub content: Vec<Content>,
256 #[serde(skip_serializing_if = "Option::is_none")]
258 #[serde(alias = "is_error")]
259 pub is_error: Option<bool>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
264#[serde(tag = "type")]
265pub enum Content {
266 #[serde(rename = "text")]
267 Text {
268 text: String,
270 },
271}
272
273#[derive(Debug, Clone)]
275pub struct BearerToken {
276 pub access_token: String,
278 pub token_type: String,
280}
281
282impl BearerToken {
283 pub fn new(access_token: &str) -> Self {
285 Self {
286 access_token: access_token.to_string(),
287 token_type: "Bearer".to_string(),
288 }
289 }
290
291 pub fn to_authorization_header(&self) -> String {
293 format!("{} {}", self.token_type, self.access_token)
294 }
295}
296
297impl Tool {
298 pub fn simple(name: &str, description: &str, parameters: &[&str]) -> Self {
300 let mut properties = serde_json::Map::new();
301 for param in parameters {
302 properties.insert(
303 param.to_string(),
304 serde_json::json!({
305 "type": "string",
306 "description": format!("Parameter: {}", param)
307 }),
308 );
309 }
310
311 let schema = serde_json::json!({
312 "type": "object",
313 "properties": properties,
314 "required": parameters
315 });
316
317 Self {
318 name: name.to_string(),
319 description: description.to_string(),
320 input_schema: schema,
321 }
322 }
323}
324
325impl Content {
326 pub fn text(text: &str) -> Self {
328 Content::Text {
329 text: text.to_string(),
330 }
331 }
332}