1use crate::Error;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Request {
10 pub jsonrpc: String,
12 pub method: String,
14 #[serde(default = "serde_json::Value::default")]
16 pub params: serde_json::Value,
17 #[serde(default = "default_null")]
19 pub id: serde_json::Value,
20}
21
22fn default_null() -> serde_json::Value {
23 serde_json::Value::Null
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct Response {
29 pub jsonrpc: String,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub result: Option<serde_json::Value>,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub error: Option<Error>,
37 pub id: serde_json::Value,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct ProtocolVersion {
44 pub major: u32,
45 pub minor: u32,
46 pub patch: u32,
47}
48
49impl Default for ProtocolVersion {
50 fn default() -> Self {
51 Self {
52 major: 2024,
53 minor: 11,
54 patch: 5,
55 }
56 }
57}
58
59impl std::fmt::Display for ProtocolVersion {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 write!(f, "{:04}-{:02}-{:02}", self.major, self.minor, self.patch)
62 }
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct Implementation {
68 pub name: String,
69 pub version: String,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize, Default)]
74pub struct ServerCapabilities {
75 pub tools: Option<ToolsCapability>,
76 pub resources: Option<ResourcesCapability>,
77 pub prompts: Option<PromptsCapability>,
78 pub logging: Option<LoggingCapability>,
79 pub sampling: Option<SamplingCapability>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, Default)]
83pub struct ToolsCapability {
84 pub list_changed: Option<bool>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize, Default)]
88pub struct ResourcesCapability {
89 pub subscribe: Option<bool>,
90 pub list_changed: Option<bool>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, Default)]
94pub struct PromptsCapability {
95 pub list_changed: Option<bool>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, Default)]
99pub struct LoggingCapability {
100 pub level: Option<String>,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, Default)]
104pub struct SamplingCapability {}
105
106impl ServerCapabilities {
107 pub fn builder() -> ServerCapabilitiesBuilder {
108 ServerCapabilitiesBuilder::default()
109 }
110}
111
112#[derive(Default)]
113pub struct ServerCapabilitiesBuilder {
114 capabilities: ServerCapabilities,
115}
116
117impl ServerCapabilitiesBuilder {
118 pub fn enable_tools(mut self) -> Self {
119 self.capabilities.tools = Some(ToolsCapability {
120 list_changed: Some(true),
121 });
122 self
123 }
124
125 pub fn enable_resources(mut self) -> Self {
126 self.capabilities.resources = Some(ResourcesCapability {
127 subscribe: Some(true),
128 list_changed: Some(true),
129 });
130 self
131 }
132
133 pub fn enable_prompts(mut self) -> Self {
134 self.capabilities.prompts = Some(PromptsCapability {
135 list_changed: Some(true),
136 });
137 self
138 }
139
140 pub fn enable_logging(mut self) -> Self {
141 self.capabilities.logging = Some(LoggingCapability {
142 level: Some("info".to_string()),
143 });
144 self
145 }
146
147 pub fn enable_sampling(mut self) -> Self {
148 self.capabilities.sampling = Some(SamplingCapability {});
149 self
150 }
151
152 pub fn build(self) -> ServerCapabilities {
153 self.capabilities
154 }
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct ServerInfo {
160 pub protocol_version: ProtocolVersion,
161 pub capabilities: ServerCapabilities,
162 pub server_info: Implementation,
163 pub instructions: Option<String>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct Tool {
170 pub name: String,
171 pub description: String,
172 pub input_schema: serde_json::Value,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177#[serde(rename_all = "camelCase")]
178pub struct ListToolsResult {
179 pub tools: Vec<Tool>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub next_cursor: Option<String>,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct PaginatedRequestParam {
187 pub cursor: Option<String>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct CallToolRequestParam {
193 pub name: String,
194 pub arguments: Option<serde_json::Value>,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
199#[serde(tag = "type")]
200pub enum Content {
201 #[serde(rename = "text")]
202 Text { text: String },
203 #[serde(rename = "image")]
204 Image { data: String, mime_type: String },
205 #[serde(rename = "resource")]
206 Resource {
207 resource: String,
208 text: Option<String>,
209 },
210}
211
212impl Content {
213 pub fn text(text: impl Into<String>) -> Self {
214 Self::Text { text: text.into() }
215 }
216
217 pub fn image(data: impl Into<String>, mime_type: impl Into<String>) -> Self {
218 Self::Image {
219 data: data.into(),
220 mime_type: mime_type.into(),
221 }
222 }
223
224 pub fn resource(resource: impl Into<String>, text: Option<String>) -> Self {
225 Self::Resource {
226 resource: resource.into(),
227 text,
228 }
229 }
230
231 pub fn as_text(&self) -> Option<&Self> {
233 match self {
234 Self::Text { .. } => Some(self),
235 _ => None,
236 }
237 }
238}
239
240pub struct TextContent {
242 pub text: String,
243}
244
245impl Content {
246 pub fn as_text_content(&self) -> Option<TextContent> {
248 match self {
249 Self::Text { text } => Some(TextContent { text: text.clone() }),
250 _ => None,
251 }
252 }
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct CallToolResult {
258 pub content: Vec<Content>,
259 pub is_error: Option<bool>,
260}
261
262impl CallToolResult {
263 pub fn success(content: Vec<Content>) -> Self {
264 Self {
265 content,
266 is_error: Some(false),
267 }
268 }
269
270 pub fn error(content: Vec<Content>) -> Self {
271 Self {
272 content,
273 is_error: Some(true),
274 }
275 }
276
277 pub fn text(text: impl Into<String>) -> Self {
278 Self::success(vec![Content::text(text)])
279 }
280
281 pub fn error_text(text: impl Into<String>) -> Self {
282 Self::error(vec![Content::text(text)])
283 }
284}
285
286#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct Resource {
289 pub uri: String,
290 pub name: String,
291 pub description: Option<String>,
292 pub mime_type: Option<String>,
293 pub annotations: Option<Annotations>,
294 #[serde(skip_serializing_if = "Option::is_none")]
295 pub raw: Option<RawResource>,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize, Default)]
300pub struct Annotations {
301 pub audience: Option<Vec<String>>,
302 pub priority: Option<f32>,
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize)]
307pub struct ListResourcesResult {
308 pub resources: Vec<Resource>,
309 #[serde(skip_serializing_if = "Option::is_none")]
310 pub next_cursor: Option<String>,
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct ReadResourceRequestParam {
316 pub uri: String,
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct ResourceContents {
322 pub uri: String,
323 pub mime_type: Option<String>,
324 pub text: Option<String>,
325 pub blob: Option<String>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
330pub struct ReadResourceResult {
331 pub contents: Vec<ResourceContents>,
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize)]
336pub struct RawResource {
337 pub uri: String,
338 pub data: Vec<u8>,
339 pub mime_type: Option<String>,
340 pub name: Option<String>,
341 pub description: Option<String>,
342 pub size: Option<usize>,
343}
344
345impl PromptMessage {
346 pub fn new_text(role: PromptMessageRole, text: impl Into<String>) -> Self {
348 Self {
349 role,
350 content: PromptMessageContent::Text { text: text.into() },
351 }
352 }
353
354 pub fn new_image(
356 role: PromptMessageRole,
357 data: impl Into<String>,
358 mime_type: impl Into<String>,
359 ) -> Self {
360 Self {
361 role,
362 content: PromptMessageContent::Image {
363 data: data.into(),
364 mime_type: mime_type.into(),
365 },
366 }
367 }
368}
369
370impl CompleteResult {
371 pub fn simple(completion: impl Into<String>) -> Self {
373 Self {
374 completion: vec![CompletionInfo {
375 completion: completion.into(),
376 has_more: Some(false),
377 }],
378 }
379 }
380}
381
382#[derive(Debug, Clone, Serialize, Deserialize)]
384pub struct Prompt {
385 pub name: String,
386 pub description: Option<String>,
387 pub arguments: Option<Vec<PromptArgument>>,
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize)]
392pub struct PromptArgument {
393 pub name: String,
394 pub description: Option<String>,
395 pub required: Option<bool>,
396}
397
398#[derive(Debug, Clone, Serialize, Deserialize)]
400pub struct ListPromptsResult {
401 pub prompts: Vec<Prompt>,
402 #[serde(skip_serializing_if = "Option::is_none")]
403 pub next_cursor: Option<String>,
404}
405
406#[derive(Debug, Clone, Serialize, Deserialize)]
408pub struct GetPromptRequestParam {
409 pub name: String,
410 pub arguments: Option<HashMap<String, String>>,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
415#[serde(rename_all = "lowercase")]
416pub enum PromptMessageRole {
417 User,
418 Assistant,
419 System,
420}
421
422#[derive(Debug, Clone, Serialize, Deserialize)]
424#[serde(tag = "type")]
425pub enum PromptMessageContent {
426 #[serde(rename = "text")]
427 Text { text: String },
428 #[serde(rename = "image")]
429 Image { data: String, mime_type: String },
430}
431
432#[derive(Debug, Clone, Serialize, Deserialize)]
434pub struct PromptMessage {
435 pub role: PromptMessageRole,
436 pub content: PromptMessageContent,
437}
438
439#[derive(Debug, Clone, Serialize, Deserialize)]
441pub struct GetPromptResult {
442 pub description: Option<String>,
443 pub messages: Vec<PromptMessage>,
444}
445
446#[derive(Debug, Clone, Serialize, Deserialize)]
448pub struct InitializeRequestParam {
449 #[serde(rename = "protocolVersion")]
450 pub protocol_version: String,
451 pub capabilities: serde_json::Value,
452 #[serde(rename = "clientInfo")]
453 pub client_info: Implementation,
454}
455
456#[derive(Debug, Clone, Serialize, Deserialize)]
458pub struct InitializeResult {
459 #[serde(rename = "protocolVersion")]
460 pub protocol_version: String,
461 pub capabilities: ServerCapabilities,
462 #[serde(rename = "serverInfo")]
463 pub server_info: Implementation,
464 pub instructions: Option<String>,
465}
466
467#[derive(Debug, Clone, Serialize, Deserialize)]
469pub struct CompleteRequestParam {
470 pub ref_: String,
471 pub argument: serde_json::Value,
472}
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
476pub struct CompletionInfo {
477 pub completion: String,
478 pub has_more: Option<bool>,
479}
480
481#[derive(Debug, Clone, Serialize, Deserialize)]
483pub struct CompleteResult {
484 pub completion: Vec<CompletionInfo>,
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize)]
489pub struct SetLevelRequestParam {
490 pub level: String,
491}
492
493#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct ResourceTemplate {
496 #[serde(rename = "uriTemplate")]
497 pub uri_template: String,
498 pub name: String,
499 pub description: Option<String>,
500 #[serde(rename = "mimeType")]
501 pub mime_type: Option<String>,
502}
503
504#[derive(Debug, Clone, Serialize, Deserialize)]
506pub struct ListResourceTemplatesResult {
507 #[serde(rename = "resourceTemplates")]
508 pub resource_templates: Vec<ResourceTemplate>,
509 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
510 pub next_cursor: Option<String>,
511}
512
513#[derive(Debug, Clone, Serialize, Deserialize)]
515pub struct SubscribeRequestParam {
516 pub uri: String,
517}
518
519#[derive(Debug, Clone, Serialize, Deserialize)]
521pub struct UnsubscribeRequestParam {
522 pub uri: String,
523}