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 #[must_use]
119 pub fn enable_tools(mut self) -> Self {
120 self.capabilities.tools = Some(ToolsCapability {
121 list_changed: Some(true),
122 });
123 self
124 }
125
126 #[must_use]
127 pub fn enable_resources(mut self) -> Self {
128 self.capabilities.resources = Some(ResourcesCapability {
129 subscribe: Some(true),
130 list_changed: Some(true),
131 });
132 self
133 }
134
135 #[must_use]
136 pub fn enable_prompts(mut self) -> Self {
137 self.capabilities.prompts = Some(PromptsCapability {
138 list_changed: Some(true),
139 });
140 self
141 }
142
143 #[must_use]
144 pub fn enable_logging(mut self) -> Self {
145 self.capabilities.logging = Some(LoggingCapability {
146 level: Some("info".to_string()),
147 });
148 self
149 }
150
151 #[must_use]
152 pub fn enable_sampling(mut self) -> Self {
153 self.capabilities.sampling = Some(SamplingCapability {});
154 self
155 }
156
157 pub fn build(self) -> ServerCapabilities {
158 self.capabilities
159 }
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct ServerInfo {
165 pub protocol_version: ProtocolVersion,
166 pub capabilities: ServerCapabilities,
167 pub server_info: Implementation,
168 pub instructions: Option<String>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct Tool {
175 pub name: String,
176 pub description: String,
177 pub input_schema: serde_json::Value,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub struct ListToolsResult {
184 pub tools: Vec<Tool>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub next_cursor: Option<String>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct PaginatedRequestParam {
192 pub cursor: Option<String>,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct CallToolRequestParam {
198 pub name: String,
199 pub arguments: Option<serde_json::Value>,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
204#[serde(tag = "type")]
205pub enum Content {
206 #[serde(rename = "text")]
207 Text { text: String },
208 #[serde(rename = "image")]
209 Image { data: String, mime_type: String },
210 #[serde(rename = "resource")]
211 Resource {
212 resource: String,
213 text: Option<String>,
214 },
215}
216
217impl Content {
218 pub fn text(text: impl Into<String>) -> Self {
219 Self::Text { text: text.into() }
220 }
221
222 pub fn image(data: impl Into<String>, mime_type: impl Into<String>) -> Self {
223 Self::Image {
224 data: data.into(),
225 mime_type: mime_type.into(),
226 }
227 }
228
229 pub fn resource(resource: impl Into<String>, text: Option<String>) -> Self {
230 Self::Resource {
231 resource: resource.into(),
232 text,
233 }
234 }
235
236 pub fn as_text(&self) -> Option<&Self> {
238 match self {
239 Self::Text { .. } => Some(self),
240 _ => None,
241 }
242 }
243}
244
245pub struct TextContent {
247 pub text: String,
248}
249
250impl Content {
251 pub fn as_text_content(&self) -> Option<TextContent> {
253 match self {
254 Self::Text { text } => Some(TextContent { text: text.clone() }),
255 _ => None,
256 }
257 }
258}
259
260#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct CallToolResult {
263 pub content: Vec<Content>,
264 pub is_error: Option<bool>,
265}
266
267impl CallToolResult {
268 pub fn success(content: Vec<Content>) -> Self {
269 Self {
270 content,
271 is_error: Some(false),
272 }
273 }
274
275 pub fn error(content: Vec<Content>) -> Self {
276 Self {
277 content,
278 is_error: Some(true),
279 }
280 }
281
282 pub fn text(text: impl Into<String>) -> Self {
283 Self::success(vec![Content::text(text)])
284 }
285
286 pub fn error_text(text: impl Into<String>) -> Self {
287 Self::error(vec![Content::text(text)])
288 }
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct Resource {
294 pub uri: String,
295 pub name: String,
296 pub description: Option<String>,
297 pub mime_type: Option<String>,
298 pub annotations: Option<Annotations>,
299 #[serde(skip_serializing_if = "Option::is_none")]
300 pub raw: Option<RawResource>,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize, Default)]
305pub struct Annotations {
306 pub audience: Option<Vec<String>>,
307 pub priority: Option<f32>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
312pub struct ListResourcesResult {
313 pub resources: Vec<Resource>,
314 #[serde(skip_serializing_if = "Option::is_none")]
315 pub next_cursor: Option<String>,
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
320pub struct ReadResourceRequestParam {
321 pub uri: String,
322}
323
324#[derive(Debug, Clone, Serialize, Deserialize)]
326pub struct ResourceContents {
327 pub uri: String,
328 pub mime_type: Option<String>,
329 pub text: Option<String>,
330 pub blob: Option<String>,
331}
332
333#[derive(Debug, Clone, Serialize, Deserialize)]
335pub struct ReadResourceResult {
336 pub contents: Vec<ResourceContents>,
337}
338
339#[derive(Debug, Clone, Serialize, Deserialize)]
341pub struct RawResource {
342 pub uri: String,
343 pub data: Vec<u8>,
344 pub mime_type: Option<String>,
345 pub name: Option<String>,
346 pub description: Option<String>,
347 pub size: Option<usize>,
348}
349
350impl PromptMessage {
351 pub fn new_text(role: PromptMessageRole, text: impl Into<String>) -> Self {
353 Self {
354 role,
355 content: PromptMessageContent::Text { text: text.into() },
356 }
357 }
358
359 pub fn new_image(
361 role: PromptMessageRole,
362 data: impl Into<String>,
363 mime_type: impl Into<String>,
364 ) -> Self {
365 Self {
366 role,
367 content: PromptMessageContent::Image {
368 data: data.into(),
369 mime_type: mime_type.into(),
370 },
371 }
372 }
373}
374
375impl CompleteResult {
376 pub fn simple(completion: impl Into<String>) -> Self {
378 Self {
379 completion: vec![CompletionInfo {
380 completion: completion.into(),
381 has_more: Some(false),
382 }],
383 }
384 }
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize)]
389pub struct Prompt {
390 pub name: String,
391 pub description: Option<String>,
392 pub arguments: Option<Vec<PromptArgument>>,
393}
394
395#[derive(Debug, Clone, Serialize, Deserialize)]
397pub struct PromptArgument {
398 pub name: String,
399 pub description: Option<String>,
400 pub required: Option<bool>,
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize)]
405pub struct ListPromptsResult {
406 pub prompts: Vec<Prompt>,
407 #[serde(skip_serializing_if = "Option::is_none")]
408 pub next_cursor: Option<String>,
409}
410
411#[derive(Debug, Clone, Serialize, Deserialize)]
413pub struct GetPromptRequestParam {
414 pub name: String,
415 pub arguments: Option<HashMap<String, String>>,
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize)]
420#[serde(rename_all = "lowercase")]
421pub enum PromptMessageRole {
422 User,
423 Assistant,
424 System,
425}
426
427#[derive(Debug, Clone, Serialize, Deserialize)]
429#[serde(tag = "type")]
430pub enum PromptMessageContent {
431 #[serde(rename = "text")]
432 Text { text: String },
433 #[serde(rename = "image")]
434 Image { data: String, mime_type: String },
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
439pub struct PromptMessage {
440 pub role: PromptMessageRole,
441 pub content: PromptMessageContent,
442}
443
444#[derive(Debug, Clone, Serialize, Deserialize)]
446pub struct GetPromptResult {
447 pub description: Option<String>,
448 pub messages: Vec<PromptMessage>,
449}
450
451#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct InitializeRequestParam {
454 #[serde(rename = "protocolVersion")]
455 pub protocol_version: String,
456 pub capabilities: serde_json::Value,
457 #[serde(rename = "clientInfo")]
458 pub client_info: Implementation,
459}
460
461#[derive(Debug, Clone, Serialize, Deserialize)]
463pub struct InitializeResult {
464 #[serde(rename = "protocolVersion")]
465 pub protocol_version: String,
466 pub capabilities: ServerCapabilities,
467 #[serde(rename = "serverInfo")]
468 pub server_info: Implementation,
469 pub instructions: Option<String>,
470}
471
472#[derive(Debug, Clone, Serialize, Deserialize)]
474pub struct CompleteRequestParam {
475 pub ref_: String,
476 pub argument: serde_json::Value,
477}
478
479#[derive(Debug, Clone, Serialize, Deserialize)]
481pub struct CompletionInfo {
482 pub completion: String,
483 pub has_more: Option<bool>,
484}
485
486#[derive(Debug, Clone, Serialize, Deserialize)]
488pub struct CompleteResult {
489 pub completion: Vec<CompletionInfo>,
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize)]
494pub struct SetLevelRequestParam {
495 pub level: String,
496}
497
498#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct ResourceTemplate {
501 #[serde(rename = "uriTemplate")]
502 pub uri_template: String,
503 pub name: String,
504 pub description: Option<String>,
505 #[serde(rename = "mimeType")]
506 pub mime_type: Option<String>,
507}
508
509#[derive(Debug, Clone, Serialize, Deserialize)]
511pub struct ListResourceTemplatesResult {
512 #[serde(rename = "resourceTemplates")]
513 pub resource_templates: Vec<ResourceTemplate>,
514 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
515 pub next_cursor: Option<String>,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize)]
520pub struct SubscribeRequestParam {
521 pub uri: String,
522}
523
524#[derive(Debug, Clone, Serialize, Deserialize)]
526pub struct UnsubscribeRequestParam {
527 pub uri: String,
528}