1use crate::Error;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Meta {
11 #[serde(rename = "progressToken", skip_serializing_if = "Option::is_none")]
13 pub progress_token: Option<String>,
14}
15
16#[derive(Debug, Clone, Eq, PartialEq, Hash)]
18pub enum NumberOrString {
19 Number(i64),
20 String(Arc<str>),
21}
22
23impl NumberOrString {
24 pub fn into_json_value(self) -> serde_json::Value {
25 match self {
26 NumberOrString::Number(n) => serde_json::Value::Number(serde_json::Number::from(n)),
27 NumberOrString::String(s) => serde_json::Value::String(s.to_string()),
28 }
29 }
30
31 pub fn from_json_value(value: serde_json::Value) -> Option<Self> {
32 match value {
33 serde_json::Value::Number(n) => n.as_i64().map(NumberOrString::Number),
34 serde_json::Value::String(s) => Some(NumberOrString::String(Arc::from(s.as_str()))),
35 _ => None,
36 }
37 }
38}
39
40impl std::fmt::Display for NumberOrString {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 NumberOrString::Number(n) => write!(f, "{n}"),
44 NumberOrString::String(s) => write!(f, "{s}"),
45 }
46 }
47}
48
49impl Serialize for NumberOrString {
50 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51 where
52 S: serde::Serializer,
53 {
54 match self {
55 NumberOrString::Number(n) => serializer.serialize_i64(*n),
56 NumberOrString::String(s) => serializer.serialize_str(s),
57 }
58 }
59}
60
61impl<'de> Deserialize<'de> for NumberOrString {
62 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63 where
64 D: serde::Deserializer<'de>,
65 {
66 struct NumberOrStringVisitor;
67
68 impl<'de> serde::de::Visitor<'de> for NumberOrStringVisitor {
69 type Value = NumberOrString;
70
71 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
72 formatter.write_str("a number or string")
73 }
74
75 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
76 where
77 E: serde::de::Error,
78 {
79 Ok(NumberOrString::Number(value))
80 }
81
82 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
83 where
84 E: serde::de::Error,
85 {
86 Ok(NumberOrString::Number(value as i64))
87 }
88
89 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
90 where
91 E: serde::de::Error,
92 {
93 Ok(NumberOrString::String(Arc::from(value)))
94 }
95
96 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
97 where
98 E: serde::de::Error,
99 {
100 Ok(NumberOrString::String(Arc::from(value.as_str())))
101 }
102 }
103
104 deserializer.deserialize_any(NumberOrStringVisitor)
105 }
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct Request {
111 pub jsonrpc: String,
113 pub method: String,
115 #[serde(default = "serde_json::Value::default")]
117 pub params: serde_json::Value,
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub id: Option<NumberOrString>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct Response {
126 pub jsonrpc: String,
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub result: Option<serde_json::Value>,
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub error: Option<Error>,
134 #[serde(skip_serializing_if = "Option::is_none")]
136 pub id: Option<NumberOrString>,
137}
138
139#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Serialize, Deserialize)]
141pub struct ProtocolVersion(std::borrow::Cow<'static, str>);
142
143impl Default for ProtocolVersion {
144 fn default() -> Self {
145 Self::LATEST
146 }
147}
148
149impl std::fmt::Display for ProtocolVersion {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 self.0.fmt(f)
152 }
153}
154
155impl ProtocolVersion {
156 pub const V_2025_06_18: Self = Self(std::borrow::Cow::Borrowed("2025-06-18"));
157 pub const V_2025_03_26: Self = Self(std::borrow::Cow::Borrowed("2025-03-26"));
158 pub const V_2024_11_05: Self = Self(std::borrow::Cow::Borrowed("2024-11-05"));
159 pub const LATEST: Self = Self::V_2025_06_18;
160
161 pub fn new(version: impl Into<std::borrow::Cow<'static, str>>) -> Self {
162 Self(version.into())
163 }
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct Implementation {
169 pub name: String,
170 pub version: String,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, Default)]
175pub struct ServerCapabilities {
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub tools: Option<ToolsCapability>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub resources: Option<ResourcesCapability>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub prompts: Option<PromptsCapability>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub logging: Option<LoggingCapability>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub sampling: Option<SamplingCapability>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub elicitation: Option<ElicitationCapability>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize, Default)]
191pub struct ToolsCapability {
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub list_changed: Option<bool>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, Default)]
197pub struct ResourcesCapability {
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub subscribe: Option<bool>,
200 #[serde(skip_serializing_if = "Option::is_none")]
201 pub list_changed: Option<bool>,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize, Default)]
205pub struct PromptsCapability {
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub list_changed: Option<bool>,
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize, Default)]
211pub struct LoggingCapability {
212 #[serde(skip_serializing_if = "Option::is_none")]
213 pub level: Option<String>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize, Default)]
217pub struct SamplingCapability {}
218
219#[derive(Debug, Clone, Serialize, Deserialize, Default)]
220pub struct ElicitationCapability {}
221
222impl ServerCapabilities {
223 pub fn builder() -> ServerCapabilitiesBuilder {
224 ServerCapabilitiesBuilder::default()
225 }
226}
227
228#[derive(Default)]
229pub struct ServerCapabilitiesBuilder {
230 capabilities: ServerCapabilities,
231}
232
233impl ServerCapabilitiesBuilder {
234 #[must_use]
235 pub fn enable_tools(mut self) -> Self {
236 self.capabilities.tools = Some(ToolsCapability {
237 list_changed: Some(true),
238 });
239 self
240 }
241
242 #[must_use]
243 pub fn enable_resources(mut self) -> Self {
244 self.capabilities.resources = Some(ResourcesCapability {
245 subscribe: Some(true),
246 list_changed: Some(true),
247 });
248 self
249 }
250
251 #[must_use]
252 pub fn enable_prompts(mut self) -> Self {
253 self.capabilities.prompts = Some(PromptsCapability {
254 list_changed: Some(true),
255 });
256 self
257 }
258
259 #[must_use]
260 pub fn enable_logging(mut self) -> Self {
261 self.capabilities.logging = Some(LoggingCapability {
262 level: Some("info".to_string()),
263 });
264 self
265 }
266
267 #[must_use]
268 pub fn enable_sampling(mut self) -> Self {
269 self.capabilities.sampling = Some(SamplingCapability {});
270 self
271 }
272
273 #[must_use]
274 pub fn enable_elicitation(mut self) -> Self {
275 self.capabilities.elicitation = Some(ElicitationCapability {});
276 self
277 }
278
279 pub fn build(self) -> ServerCapabilities {
280 self.capabilities
281 }
282}
283
284#[derive(Debug, Clone, Serialize, Deserialize)]
286pub struct ServerInfo {
287 pub protocol_version: ProtocolVersion,
288 pub capabilities: ServerCapabilities,
289 pub server_info: Implementation,
290 pub instructions: Option<String>,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct Tool {
297 pub name: String,
298 #[serde(skip_serializing_if = "Option::is_none")]
299 pub title: Option<String>,
300 pub description: String,
301 pub input_schema: serde_json::Value,
302 #[serde(skip_serializing_if = "Option::is_none")]
303 pub output_schema: Option<serde_json::Value>,
304 #[serde(skip_serializing_if = "Option::is_none")]
305 pub annotations: Option<ToolAnnotations>,
306 #[serde(skip_serializing_if = "Option::is_none")]
307 pub icons: Option<Vec<Icon>>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize, Default)]
312pub struct ToolAnnotations {
313 #[serde(skip_serializing_if = "Option::is_none")]
314 pub read_only_hint: Option<bool>,
315 #[serde(skip_serializing_if = "Option::is_none")]
316 pub destructive_hint: Option<bool>,
317 #[serde(skip_serializing_if = "Option::is_none")]
318 pub idempotent_hint: Option<bool>,
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub open_world_hint: Option<bool>,
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct Icon {
326 pub uri: String,
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub mime_type: Option<String>,
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize)]
333#[serde(rename_all = "camelCase")]
334pub struct ListToolsResult {
335 pub tools: Vec<Tool>,
336 #[serde(skip_serializing_if = "Option::is_none")]
337 pub next_cursor: Option<String>,
338}
339
340#[derive(Debug, Clone, Serialize, Deserialize)]
342pub struct PaginatedRequestParam {
343 pub cursor: Option<String>,
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize)]
348pub struct CallToolRequestParam {
349 pub name: String,
350 pub arguments: Option<serde_json::Value>,
351}
352
353#[derive(Debug, Clone, Serialize, Deserialize)]
355#[serde(tag = "type")]
356pub enum Content {
357 #[serde(rename = "text")]
358 Text {
359 text: String,
360 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
361 _meta: Option<Meta>,
362 },
363 #[serde(rename = "image")]
364 Image {
365 data: String,
366 mime_type: String,
367 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
368 _meta: Option<Meta>,
369 },
370 #[serde(rename = "resource")]
371 Resource {
372 resource: String,
373 text: Option<String>,
374 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
375 _meta: Option<Meta>,
376 },
377}
378
379impl Content {
380 pub fn text(text: impl Into<String>) -> Self {
381 Self::Text {
382 text: text.into(),
383 _meta: None,
384 }
385 }
386
387 pub fn image(data: impl Into<String>, mime_type: impl Into<String>) -> Self {
388 Self::Image {
389 data: data.into(),
390 mime_type: mime_type.into(),
391 _meta: None,
392 }
393 }
394
395 pub fn resource(resource: impl Into<String>, text: Option<String>) -> Self {
396 Self::Resource {
397 resource: resource.into(),
398 text,
399 _meta: None,
400 }
401 }
402
403 pub fn as_text(&self) -> Option<&Self> {
405 match self {
406 Self::Text { .. } => Some(self),
407 _ => None,
408 }
409 }
410}
411
412pub struct TextContent {
414 pub text: String,
415}
416
417impl Content {
418 pub fn as_text_content(&self) -> Option<TextContent> {
420 match self {
421 Self::Text { text, .. } => Some(TextContent { text: text.clone() }),
422 _ => None,
423 }
424 }
425}
426
427#[derive(Debug, Clone, Serialize, Deserialize)]
429#[serde(rename_all = "camelCase")]
430pub struct CallToolResult {
431 pub content: Vec<Content>,
432 pub is_error: Option<bool>,
433 #[serde(skip_serializing_if = "Option::is_none")]
434 pub structured_content: Option<serde_json::Value>,
435 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
436 pub _meta: Option<Meta>,
437}
438
439impl CallToolResult {
440 pub fn success(content: Vec<Content>) -> Self {
441 Self {
442 content,
443 is_error: Some(false),
444 structured_content: None,
445 _meta: None,
446 }
447 }
448
449 pub fn error(content: Vec<Content>) -> Self {
450 Self {
451 content,
452 is_error: Some(true),
453 structured_content: None,
454 _meta: None,
455 }
456 }
457
458 pub fn text(text: impl Into<String>) -> Self {
459 Self::success(vec![Content::text(text)])
460 }
461
462 pub fn error_text(text: impl Into<String>) -> Self {
463 Self::error(vec![Content::text(text)])
464 }
465
466 pub fn structured(content: Vec<Content>, structured_content: serde_json::Value) -> Self {
468 Self {
469 content,
470 is_error: Some(false),
471 structured_content: Some(structured_content),
472 _meta: None,
473 }
474 }
475
476 pub fn structured_error(content: Vec<Content>, structured_content: serde_json::Value) -> Self {
478 Self {
479 content,
480 is_error: Some(true),
481 structured_content: Some(structured_content),
482 _meta: None,
483 }
484 }
485
486 pub fn text_with_structured(
488 text: impl Into<String>,
489 structured_content: serde_json::Value,
490 ) -> Self {
491 Self::structured(vec![Content::text(text)], structured_content)
492 }
493
494 pub fn validate_structured_content(
500 &self,
501 output_schema: &serde_json::Value,
502 ) -> crate::Result<()> {
503 use crate::validation::Validator;
504
505 if let Some(structured_content) = &self.structured_content {
506 Validator::validate_structured_content(structured_content, output_schema)?;
507 }
508 Ok(())
509 }
510}
511
512#[derive(Debug, Clone, Serialize, Deserialize)]
514pub struct Resource {
515 pub uri: String,
516 pub name: String,
517 #[serde(skip_serializing_if = "Option::is_none")]
518 pub title: Option<String>,
519 pub description: Option<String>,
520 pub mime_type: Option<String>,
521 pub annotations: Option<Annotations>,
522 #[serde(skip_serializing_if = "Option::is_none")]
523 pub icons: Option<Vec<Icon>>,
524 #[serde(skip_serializing_if = "Option::is_none")]
525 pub raw: Option<RawResource>,
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize, Default)]
530pub struct Annotations {
531 pub audience: Option<Vec<String>>,
532 pub priority: Option<f32>,
533}
534
535#[derive(Debug, Clone, Serialize, Deserialize)]
537pub struct ListResourcesResult {
538 pub resources: Vec<Resource>,
539 #[serde(skip_serializing_if = "Option::is_none")]
540 pub next_cursor: Option<String>,
541}
542
543#[derive(Debug, Clone, Serialize, Deserialize)]
545pub struct ReadResourceRequestParam {
546 pub uri: String,
547}
548
549#[derive(Debug, Clone, Serialize, Deserialize)]
551pub struct ResourceContents {
552 pub uri: String,
553 pub mime_type: Option<String>,
554 pub text: Option<String>,
555 pub blob: Option<String>,
556 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
557 pub _meta: Option<Meta>,
558}
559
560#[derive(Debug, Clone, Serialize, Deserialize)]
562pub struct ReadResourceResult {
563 pub contents: Vec<ResourceContents>,
564}
565
566#[derive(Debug, Clone, Serialize, Deserialize)]
568pub struct RawResource {
569 pub uri: String,
570 pub data: Vec<u8>,
571 pub mime_type: Option<String>,
572 pub name: Option<String>,
573 pub description: Option<String>,
574 pub size: Option<usize>,
575}
576
577impl PromptMessage {
578 pub fn new_text(role: PromptMessageRole, text: impl Into<String>) -> Self {
580 Self {
581 role,
582 content: PromptMessageContent::Text { text: text.into() },
583 }
584 }
585
586 pub fn new_image(
588 role: PromptMessageRole,
589 data: impl Into<String>,
590 mime_type: impl Into<String>,
591 ) -> Self {
592 Self {
593 role,
594 content: PromptMessageContent::Image {
595 data: data.into(),
596 mime_type: mime_type.into(),
597 },
598 }
599 }
600}
601
602impl CompleteResult {
603 pub fn simple(completion: impl Into<String>) -> Self {
605 Self {
606 completion: vec![CompletionInfo {
607 completion: completion.into(),
608 has_more: Some(false),
609 }],
610 }
611 }
612}
613
614#[derive(Debug, Clone, Serialize, Deserialize)]
616pub struct Prompt {
617 pub name: String,
618 #[serde(skip_serializing_if = "Option::is_none")]
619 pub title: Option<String>,
620 pub description: Option<String>,
621 pub arguments: Option<Vec<PromptArgument>>,
622 #[serde(skip_serializing_if = "Option::is_none")]
623 pub icons: Option<Vec<Icon>>,
624}
625
626#[derive(Debug, Clone, Serialize, Deserialize)]
628pub struct PromptArgument {
629 pub name: String,
630 pub description: Option<String>,
631 pub required: Option<bool>,
632}
633
634#[derive(Debug, Clone, Serialize, Deserialize)]
636pub struct ListPromptsResult {
637 pub prompts: Vec<Prompt>,
638 #[serde(skip_serializing_if = "Option::is_none")]
639 pub next_cursor: Option<String>,
640}
641
642#[derive(Debug, Clone, Serialize, Deserialize)]
644pub struct GetPromptRequestParam {
645 pub name: String,
646 pub arguments: Option<HashMap<String, String>>,
647}
648
649#[derive(Debug, Clone, Serialize, Deserialize)]
651#[serde(rename_all = "lowercase")]
652pub enum PromptMessageRole {
653 User,
654 Assistant,
655 System,
656}
657
658#[derive(Debug, Clone, Serialize, Deserialize)]
660#[serde(tag = "type")]
661pub enum PromptMessageContent {
662 #[serde(rename = "text")]
663 Text { text: String },
664 #[serde(rename = "image")]
665 Image { data: String, mime_type: String },
666}
667
668#[derive(Debug, Clone, Serialize, Deserialize)]
670pub struct PromptMessage {
671 pub role: PromptMessageRole,
672 pub content: PromptMessageContent,
673}
674
675#[derive(Debug, Clone, Serialize, Deserialize)]
677pub struct GetPromptResult {
678 pub description: Option<String>,
679 pub messages: Vec<PromptMessage>,
680}
681
682#[derive(Debug, Clone, Serialize, Deserialize)]
684pub struct InitializeRequestParam {
685 #[serde(rename = "protocolVersion")]
686 pub protocol_version: String,
687 pub capabilities: serde_json::Value,
688 #[serde(rename = "clientInfo")]
689 pub client_info: Implementation,
690}
691
692#[derive(Debug, Clone, Serialize, Deserialize)]
694pub struct InitializeResult {
695 #[serde(rename = "protocolVersion")]
696 pub protocol_version: String,
697 pub capabilities: ServerCapabilities,
698 #[serde(rename = "serverInfo")]
699 pub server_info: Implementation,
700 #[serde(skip_serializing_if = "Option::is_none")]
701 pub instructions: Option<String>,
702}
703
704#[derive(Debug, Clone, Serialize, Deserialize)]
706#[serde(rename_all = "camelCase")]
707pub struct CompletionContext {
708 pub argument_names: Vec<String>,
710 pub values: HashMap<String, serde_json::Value>,
712}
713
714impl CompletionContext {
715 pub fn new(argument_names: Vec<String>, values: HashMap<String, serde_json::Value>) -> Self {
717 Self {
718 argument_names,
719 values,
720 }
721 }
722
723 pub fn argument_names_iter(&self) -> impl Iterator<Item = &String> {
725 self.argument_names.iter()
726 }
727}
728
729#[derive(Debug, Clone, Serialize, Deserialize)]
731pub struct CompleteRequestParam {
732 pub ref_: String,
733 pub argument: serde_json::Value,
734 #[serde(skip_serializing_if = "Option::is_none")]
736 pub context: Option<CompletionContext>,
737}
738
739#[derive(Debug, Clone, Serialize, Deserialize)]
741pub struct CompletionInfo {
742 pub completion: String,
743 pub has_more: Option<bool>,
744}
745
746#[derive(Debug, Clone, Serialize, Deserialize)]
748pub struct CompleteResult {
749 pub completion: Vec<CompletionInfo>,
750}
751
752#[derive(Debug, Clone, Serialize, Deserialize)]
754pub struct SetLevelRequestParam {
755 pub level: String,
756}
757
758#[derive(Debug, Clone, Serialize, Deserialize)]
760pub struct ResourceTemplate {
761 #[serde(rename = "uriTemplate")]
762 pub uri_template: String,
763 pub name: String,
764 pub description: Option<String>,
765 #[serde(rename = "mimeType")]
766 pub mime_type: Option<String>,
767}
768
769#[derive(Debug, Clone, Serialize, Deserialize)]
771pub struct ListResourceTemplatesResult {
772 #[serde(rename = "resourceTemplates")]
773 pub resource_templates: Vec<ResourceTemplate>,
774 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
775 pub next_cursor: Option<String>,
776}
777
778#[derive(Debug, Clone, Serialize, Deserialize)]
780pub struct SubscribeRequestParam {
781 pub uri: String,
782}
783
784#[derive(Debug, Clone, Serialize, Deserialize)]
786pub struct UnsubscribeRequestParam {
787 pub uri: String,
788}
789
790#[derive(Debug, Clone, Serialize, Deserialize)]
792pub struct ElicitationRequestParam {
793 pub message: String,
794 #[serde(rename = "requestedSchema")]
795 pub requested_schema: serde_json::Value,
796}
797
798#[derive(Debug, Clone, Serialize, Deserialize)]
800#[serde(rename_all = "lowercase")]
801pub enum ElicitationAction {
802 Accept,
803 Decline,
804 Cancel,
805}
806
807#[derive(Debug, Clone, Serialize, Deserialize)]
809pub struct ElicitationResponse {
810 pub action: ElicitationAction,
811 #[serde(skip_serializing_if = "Option::is_none")]
812 pub data: Option<serde_json::Value>,
813}
814
815#[derive(Debug, Clone, Serialize, Deserialize)]
817pub struct ElicitationResult {
818 pub response: ElicitationResponse,
819}
820
821impl ElicitationResult {
822 pub fn accept(data: serde_json::Value) -> Self {
824 Self {
825 response: ElicitationResponse {
826 action: ElicitationAction::Accept,
827 data: Some(data),
828 },
829 }
830 }
831
832 pub fn decline() -> Self {
834 Self {
835 response: ElicitationResponse {
836 action: ElicitationAction::Decline,
837 data: None,
838 },
839 }
840 }
841
842 pub fn cancel() -> Self {
844 Self {
845 response: ElicitationResponse {
846 action: ElicitationAction::Cancel,
847 data: None,
848 },
849 }
850 }
851}