1use crate::Error;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8pub mod mime_types {
10 pub const HTML_MCP: &str = "text/html+mcp";
12
13 pub const HTML: &str = "text/html";
15
16 pub const JSON: &str = "application/json";
18
19 pub const TEXT: &str = "text/plain";
21
22 pub const OCTET_STREAM: &str = "application/octet-stream";
24}
25
26pub mod uri_schemes {
28 pub const UI: &str = "ui://";
30
31 pub const FILE: &str = "file://";
33
34 pub const HTTP: &str = "http://";
36
37 pub const HTTPS: &str = "https://";
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct Meta {
44 #[serde(rename = "progressToken", skip_serializing_if = "Option::is_none")]
46 pub progress_token: Option<String>,
47}
48
49#[derive(Debug, Clone, Eq, PartialEq, Hash)]
51pub enum NumberOrString {
52 Number(i64),
53 String(Arc<str>),
54}
55
56impl NumberOrString {
57 pub fn into_json_value(self) -> serde_json::Value {
58 match self {
59 NumberOrString::Number(n) => serde_json::Value::Number(serde_json::Number::from(n)),
60 NumberOrString::String(s) => serde_json::Value::String(s.to_string()),
61 }
62 }
63
64 pub fn from_json_value(value: serde_json::Value) -> Option<Self> {
65 match value {
66 serde_json::Value::Number(n) => n.as_i64().map(NumberOrString::Number),
67 serde_json::Value::String(s) => Some(NumberOrString::String(Arc::from(s.as_str()))),
68 _ => None,
69 }
70 }
71}
72
73impl std::fmt::Display for NumberOrString {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 match self {
76 NumberOrString::Number(n) => write!(f, "{n}"),
77 NumberOrString::String(s) => write!(f, "{s}"),
78 }
79 }
80}
81
82impl Serialize for NumberOrString {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: serde::Serializer,
86 {
87 match self {
88 NumberOrString::Number(n) => serializer.serialize_i64(*n),
89 NumberOrString::String(s) => serializer.serialize_str(s),
90 }
91 }
92}
93
94impl<'de> Deserialize<'de> for NumberOrString {
95 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96 where
97 D: serde::Deserializer<'de>,
98 {
99 struct NumberOrStringVisitor;
100
101 impl<'de> serde::de::Visitor<'de> for NumberOrStringVisitor {
102 type Value = NumberOrString;
103
104 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
105 formatter.write_str("a number or string")
106 }
107
108 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
109 where
110 E: serde::de::Error,
111 {
112 Ok(NumberOrString::Number(value))
113 }
114
115 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
116 where
117 E: serde::de::Error,
118 {
119 Ok(NumberOrString::Number(value as i64))
120 }
121
122 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
123 where
124 E: serde::de::Error,
125 {
126 Ok(NumberOrString::String(Arc::from(value)))
127 }
128
129 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
130 where
131 E: serde::de::Error,
132 {
133 Ok(NumberOrString::String(Arc::from(value.as_str())))
134 }
135 }
136
137 deserializer.deserialize_any(NumberOrStringVisitor)
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct Request {
144 pub jsonrpc: String,
146 pub method: String,
148 #[serde(default = "serde_json::Value::default")]
150 pub params: serde_json::Value,
151 #[serde(skip_serializing_if = "Option::is_none")]
153 pub id: Option<NumberOrString>,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct Response {
159 pub jsonrpc: String,
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub result: Option<serde_json::Value>,
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub error: Option<Error>,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub id: Option<NumberOrString>,
170}
171
172#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Serialize, Deserialize)]
174pub struct ProtocolVersion(std::borrow::Cow<'static, str>);
175
176impl Default for ProtocolVersion {
177 fn default() -> Self {
178 Self::LATEST
179 }
180}
181
182impl std::fmt::Display for ProtocolVersion {
183 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
184 self.0.fmt(f)
185 }
186}
187
188impl ProtocolVersion {
189 pub const V_2025_06_18: Self = Self(std::borrow::Cow::Borrowed("2025-06-18"));
190 pub const V_2025_03_26: Self = Self(std::borrow::Cow::Borrowed("2025-03-26"));
191 pub const V_2024_11_05: Self = Self(std::borrow::Cow::Borrowed("2024-11-05"));
192 pub const LATEST: Self = Self::V_2025_06_18;
193
194 pub fn new(version: impl Into<std::borrow::Cow<'static, str>>) -> Self {
195 Self(version.into())
196 }
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct Implementation {
202 pub name: String,
203 pub version: String,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize, Default)]
208pub struct ServerCapabilities {
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub tools: Option<ToolsCapability>,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub resources: Option<ResourcesCapability>,
213 #[serde(skip_serializing_if = "Option::is_none")]
214 pub prompts: Option<PromptsCapability>,
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub logging: Option<LoggingCapability>,
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub sampling: Option<SamplingCapability>,
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub elicitation: Option<ElicitationCapability>,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize, Default)]
224pub struct ToolsCapability {
225 #[serde(skip_serializing_if = "Option::is_none")]
226 pub list_changed: Option<bool>,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize, Default)]
230pub struct ResourcesCapability {
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub subscribe: Option<bool>,
233 #[serde(skip_serializing_if = "Option::is_none")]
234 pub list_changed: Option<bool>,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize, Default)]
238pub struct PromptsCapability {
239 #[serde(skip_serializing_if = "Option::is_none")]
240 pub list_changed: Option<bool>,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize, Default)]
244pub struct LoggingCapability {
245 #[serde(skip_serializing_if = "Option::is_none")]
246 pub level: Option<String>,
247}
248
249#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
251#[serde(rename_all = "lowercase")]
252pub enum LogLevel {
253 Emergency,
254 Alert,
255 Critical,
256 Error,
257 Warning,
258 Notice,
259 Info,
260 Debug,
261}
262
263impl LogLevel {
264 pub fn as_str(&self) -> &'static str {
265 match self {
266 LogLevel::Emergency => "emergency",
267 LogLevel::Alert => "alert",
268 LogLevel::Critical => "critical",
269 LogLevel::Error => "error",
270 LogLevel::Warning => "warning",
271 LogLevel::Notice => "notice",
272 LogLevel::Info => "info",
273 LogLevel::Debug => "debug",
274 }
275 }
276}
277
278impl std::str::FromStr for LogLevel {
279 type Err = String;
280
281 fn from_str(s: &str) -> Result<Self, Self::Err> {
282 match s.to_lowercase().as_str() {
283 "emergency" => Ok(LogLevel::Emergency),
284 "alert" => Ok(LogLevel::Alert),
285 "critical" => Ok(LogLevel::Critical),
286 "error" => Ok(LogLevel::Error),
287 "warning" => Ok(LogLevel::Warning),
288 "notice" => Ok(LogLevel::Notice),
289 "info" => Ok(LogLevel::Info),
290 "debug" => Ok(LogLevel::Debug),
291 _ => Err(format!("Invalid log level: {s}")),
292 }
293 }
294}
295
296impl std::fmt::Display for LogLevel {
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298 write!(f, "{}", self.as_str())
299 }
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize, Default)]
303pub struct SamplingCapability {}
304
305#[derive(Debug, Clone, Serialize, Deserialize, Default)]
306pub struct ElicitationCapability {}
307
308impl ServerCapabilities {
309 pub fn builder() -> ServerCapabilitiesBuilder {
310 ServerCapabilitiesBuilder::default()
311 }
312}
313
314#[derive(Default)]
315pub struct ServerCapabilitiesBuilder {
316 capabilities: ServerCapabilities,
317}
318
319impl ServerCapabilitiesBuilder {
320 #[must_use]
321 pub fn enable_tools(mut self) -> Self {
322 self.capabilities.tools = Some(ToolsCapability {
323 list_changed: Some(true),
324 });
325 self
326 }
327
328 #[must_use]
329 pub fn enable_resources(mut self) -> Self {
330 self.capabilities.resources = Some(ResourcesCapability {
331 subscribe: Some(true),
332 list_changed: Some(true),
333 });
334 self
335 }
336
337 #[must_use]
338 pub fn enable_prompts(mut self) -> Self {
339 self.capabilities.prompts = Some(PromptsCapability {
340 list_changed: Some(true),
341 });
342 self
343 }
344
345 #[must_use]
346 pub fn enable_logging(mut self) -> Self {
347 self.capabilities.logging = Some(LoggingCapability {
348 level: Some("info".to_string()),
349 });
350 self
351 }
352
353 #[must_use]
354 pub fn enable_sampling(mut self) -> Self {
355 self.capabilities.sampling = Some(SamplingCapability {});
356 self
357 }
358
359 #[must_use]
360 pub fn enable_elicitation(mut self) -> Self {
361 self.capabilities.elicitation = Some(ElicitationCapability {});
362 self
363 }
364
365 pub fn build(self) -> ServerCapabilities {
366 self.capabilities
367 }
368}
369
370#[derive(Debug, Clone, Serialize, Deserialize)]
372pub struct ServerInfo {
373 pub protocol_version: ProtocolVersion,
374 pub capabilities: ServerCapabilities,
375 pub server_info: Implementation,
376 pub instructions: Option<String>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
381#[serde(rename_all = "camelCase")]
382pub struct Tool {
383 pub name: String,
384 #[serde(skip_serializing_if = "Option::is_none")]
385 pub title: Option<String>,
386 pub description: String,
387 pub input_schema: serde_json::Value,
388 #[serde(skip_serializing_if = "Option::is_none")]
389 pub output_schema: Option<serde_json::Value>,
390 #[serde(skip_serializing_if = "Option::is_none")]
391 pub annotations: Option<ToolAnnotations>,
392 #[serde(skip_serializing_if = "Option::is_none")]
393 pub icons: Option<Vec<Icon>>,
394 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
396 pub _meta: Option<ToolMeta>,
397}
398
399#[derive(Debug, Clone, Serialize, Deserialize, Default)]
401pub struct ToolAnnotations {
402 #[serde(skip_serializing_if = "Option::is_none")]
403 pub read_only_hint: Option<bool>,
404 #[serde(skip_serializing_if = "Option::is_none")]
405 pub destructive_hint: Option<bool>,
406 #[serde(skip_serializing_if = "Option::is_none")]
407 pub idempotent_hint: Option<bool>,
408 #[serde(skip_serializing_if = "Option::is_none")]
409 pub open_world_hint: Option<bool>,
410}
411
412#[derive(Debug, Clone, Serialize, Deserialize, Default)]
417pub struct ToolMeta {
418 #[serde(rename = "ui/resourceUri", skip_serializing_if = "Option::is_none")]
426 pub ui_resource_uri: Option<String>,
427}
428
429impl ToolMeta {
430 pub fn with_ui_resource(uri: impl Into<String>) -> Self {
432 Self {
433 ui_resource_uri: Some(uri.into()),
434 }
435 }
436}
437
438#[derive(Debug, Clone, Serialize, Deserialize)]
440pub struct Icon {
441 pub uri: String,
442 #[serde(skip_serializing_if = "Option::is_none")]
443 pub mime_type: Option<String>,
444}
445
446#[derive(Debug, Clone, Serialize, Deserialize)]
448#[serde(rename_all = "camelCase")]
449pub struct ListToolsResult {
450 pub tools: Vec<Tool>,
451 #[serde(skip_serializing_if = "Option::is_none")]
452 pub next_cursor: Option<String>,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
457pub struct PaginatedRequestParam {
458 pub cursor: Option<String>,
459}
460
461#[derive(Debug, Clone, Serialize, Deserialize)]
463pub struct CallToolRequestParam {
464 pub name: String,
465 pub arguments: Option<serde_json::Value>,
466}
467
468#[derive(Debug, Clone, Serialize, Deserialize)]
470#[serde(tag = "type")]
471pub enum Content {
472 #[serde(rename = "text")]
473 Text {
474 text: String,
475 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
476 _meta: Option<Meta>,
477 },
478 #[serde(rename = "image")]
479 Image {
480 data: String,
481 mime_type: String,
482 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
483 _meta: Option<Meta>,
484 },
485 #[serde(rename = "resource")]
486 Resource {
487 #[serde(with = "serde_json_string_or_object")]
488 resource: String,
489 text: Option<String>,
490 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
491 _meta: Option<Meta>,
492 },
493}
494
495impl Content {
496 pub fn text(text: impl Into<String>) -> Self {
497 Self::Text {
498 text: text.into(),
499 _meta: None,
500 }
501 }
502
503 pub fn image(data: impl Into<String>, mime_type: impl Into<String>) -> Self {
504 Self::Image {
505 data: data.into(),
506 mime_type: mime_type.into(),
507 _meta: None,
508 }
509 }
510
511 pub fn resource(resource: impl Into<String>, text: Option<String>) -> Self {
512 Self::Resource {
513 resource: resource.into(),
514 text,
515 _meta: None,
516 }
517 }
518
519 pub fn ui_html(uri: impl Into<String>, html: impl Into<String>) -> Self {
547 let resource_json = serde_json::json!({
548 "uri": uri.into(),
549 "mimeType": "text/html",
550 "text": html.into()
551 });
552 Self::Resource {
553 resource: resource_json.to_string(),
554 text: None,
555 _meta: None,
556 }
557 }
558
559 pub fn ui_resource(
576 uri: impl Into<String>,
577 mime_type: impl Into<String>,
578 content: impl Into<String>,
579 ) -> Self {
580 let resource_json = serde_json::json!({
581 "uri": uri.into(),
582 "mimeType": mime_type.into(),
583 "text": content.into()
584 });
585 Self::Resource {
586 resource: resource_json.to_string(),
587 text: None,
588 _meta: None,
589 }
590 }
591
592 pub fn as_text(&self) -> Option<&Self> {
594 match self {
595 Self::Text { .. } => Some(self),
596 _ => None,
597 }
598 }
599}
600
601pub struct TextContent {
603 pub text: String,
604}
605
606impl Content {
607 pub fn as_text_content(&self) -> Option<TextContent> {
609 match self {
610 Self::Text { text, .. } => Some(TextContent { text: text.clone() }),
611 _ => None,
612 }
613 }
614}
615
616#[derive(Debug, Clone, Serialize, Deserialize)]
618#[serde(rename_all = "camelCase")]
619pub struct CallToolResult {
620 pub content: Vec<Content>,
621 pub is_error: Option<bool>,
622 #[serde(skip_serializing_if = "Option::is_none")]
623 pub structured_content: Option<serde_json::Value>,
624 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
625 pub _meta: Option<Meta>,
626}
627
628impl CallToolResult {
629 pub fn success(content: Vec<Content>) -> Self {
630 Self {
631 content,
632 is_error: Some(false),
633 structured_content: None,
634 _meta: None,
635 }
636 }
637
638 pub fn error(content: Vec<Content>) -> Self {
639 Self {
640 content,
641 is_error: Some(true),
642 structured_content: None,
643 _meta: None,
644 }
645 }
646
647 pub fn text(text: impl Into<String>) -> Self {
648 Self::success(vec![Content::text(text)])
649 }
650
651 pub fn error_text(text: impl Into<String>) -> Self {
652 Self::error(vec![Content::text(text)])
653 }
654
655 pub fn structured(content: Vec<Content>, structured_content: serde_json::Value) -> Self {
657 Self {
658 content,
659 is_error: Some(false),
660 structured_content: Some(structured_content),
661 _meta: None,
662 }
663 }
664
665 pub fn structured_error(content: Vec<Content>, structured_content: serde_json::Value) -> Self {
667 Self {
668 content,
669 is_error: Some(true),
670 structured_content: Some(structured_content),
671 _meta: None,
672 }
673 }
674
675 pub fn text_with_structured(
677 text: impl Into<String>,
678 structured_content: serde_json::Value,
679 ) -> Self {
680 Self::structured(vec![Content::text(text)], structured_content)
681 }
682
683 pub fn validate_structured_content(
689 &self,
690 output_schema: &serde_json::Value,
691 ) -> crate::Result<()> {
692 use crate::validation::Validator;
693
694 if let Some(structured_content) = &self.structured_content {
695 Validator::validate_structured_content(structured_content, output_schema)?;
696 }
697 Ok(())
698 }
699}
700
701#[derive(Debug, Clone, Serialize, Deserialize)]
703pub struct Resource {
704 pub uri: String,
705 pub name: String,
706 #[serde(skip_serializing_if = "Option::is_none")]
707 pub title: Option<String>,
708 pub description: Option<String>,
709 pub mime_type: Option<String>,
710 pub annotations: Option<Annotations>,
711 #[serde(skip_serializing_if = "Option::is_none")]
712 pub icons: Option<Vec<Icon>>,
713 #[serde(skip_serializing_if = "Option::is_none")]
714 pub raw: Option<RawResource>,
715 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
717 pub _meta: Option<ResourceMeta>,
718}
719
720#[derive(Debug, Clone, Serialize, Deserialize, Default)]
722pub struct ResourceMeta {
723 #[serde(rename = "ui", skip_serializing_if = "Option::is_none")]
725 pub ui: Option<UiResourceMeta>,
726}
727
728#[derive(Debug, Clone, Serialize, Deserialize, Default)]
730pub struct UiResourceMeta {
731 #[serde(skip_serializing_if = "Option::is_none")]
733 pub csp: Option<CspConfig>,
734
735 #[serde(skip_serializing_if = "Option::is_none")]
737 pub domain: Option<String>,
738
739 #[serde(rename = "prefersBorder", skip_serializing_if = "Option::is_none")]
741 pub prefers_border: Option<bool>,
742}
743
744#[derive(Debug, Clone, Serialize, Deserialize, Default)]
746pub struct CspConfig {
747 #[serde(rename = "connectDomains", skip_serializing_if = "Option::is_none")]
749 pub connect_domains: Option<Vec<String>>,
750
751 #[serde(rename = "resourceDomains", skip_serializing_if = "Option::is_none")]
753 pub resource_domains: Option<Vec<String>>,
754}
755
756#[derive(Debug, Clone, Serialize, Deserialize, Default)]
758pub struct Annotations {
759 pub audience: Option<Vec<String>>,
760 pub priority: Option<f32>,
761}
762
763impl Resource {
764 pub fn ui_resource(
781 uri: impl Into<String>,
782 name: impl Into<String>,
783 description: impl Into<String>,
784 ) -> Self {
785 Self {
786 uri: uri.into(),
787 name: name.into(),
788 title: None,
789 description: Some(description.into()),
790 mime_type: Some(mime_types::HTML_MCP.to_string()),
791 annotations: None,
792 icons: None,
793 raw: None,
794 _meta: None,
795 }
796 }
797
798 pub fn ui_resource_with_csp(
800 uri: impl Into<String>,
801 name: impl Into<String>,
802 description: impl Into<String>,
803 csp: CspConfig,
804 ) -> Self {
805 Self {
806 uri: uri.into(),
807 name: name.into(),
808 title: None,
809 description: Some(description.into()),
810 mime_type: Some(mime_types::HTML_MCP.to_string()),
811 annotations: None,
812 icons: None,
813 raw: None,
814 _meta: Some(ResourceMeta {
815 ui: Some(UiResourceMeta {
816 csp: Some(csp),
817 domain: None,
818 prefers_border: None,
819 }),
820 }),
821 }
822 }
823
824 pub fn is_ui_resource(&self) -> bool {
826 self.uri.starts_with(uri_schemes::UI)
827 }
828
829 pub fn uri_scheme(&self) -> Option<&str> {
831 self.uri.split_once("://").map(|(scheme, _)| scheme)
832 }
833}
834
835impl ResourceContents {
836 pub fn html_ui(uri: impl Into<String>, html: impl Into<String>) -> Self {
838 Self {
839 uri: uri.into(),
840 mime_type: Some(mime_types::HTML_MCP.to_string()),
841 text: Some(html.into()),
842 blob: None,
843 _meta: None,
844 }
845 }
846
847 pub fn json(uri: impl Into<String>, json: impl Into<String>) -> Self {
849 Self {
850 uri: uri.into(),
851 mime_type: Some(mime_types::JSON.to_string()),
852 text: Some(json.into()),
853 blob: None,
854 _meta: None,
855 }
856 }
857
858 pub fn text(uri: impl Into<String>, text: impl Into<String>) -> Self {
860 Self {
861 uri: uri.into(),
862 mime_type: Some(mime_types::TEXT.to_string()),
863 text: Some(text.into()),
864 blob: None,
865 _meta: None,
866 }
867 }
868}
869
870#[derive(Debug, Clone, Serialize, Deserialize)]
872pub struct ListResourcesResult {
873 pub resources: Vec<Resource>,
874 #[serde(skip_serializing_if = "Option::is_none")]
875 pub next_cursor: Option<String>,
876}
877
878#[derive(Debug, Clone, Serialize, Deserialize)]
880pub struct ReadResourceRequestParam {
881 pub uri: String,
882}
883
884#[derive(Debug, Clone, Serialize, Deserialize)]
886pub struct ResourceContents {
887 pub uri: String,
888 pub mime_type: Option<String>,
889 pub text: Option<String>,
890 pub blob: Option<String>,
891 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
892 pub _meta: Option<Meta>,
893}
894
895#[derive(Debug, Clone, Serialize, Deserialize)]
897pub struct ReadResourceResult {
898 pub contents: Vec<ResourceContents>,
899}
900
901#[derive(Debug, Clone, Serialize, Deserialize)]
903pub struct RawResource {
904 pub uri: String,
905 pub data: Vec<u8>,
906 pub mime_type: Option<String>,
907 pub name: Option<String>,
908 pub description: Option<String>,
909 pub size: Option<usize>,
910}
911
912impl PromptMessage {
913 pub fn new_text(role: PromptMessageRole, text: impl Into<String>) -> Self {
915 Self {
916 role,
917 content: PromptMessageContent::Text { text: text.into() },
918 }
919 }
920
921 pub fn new_image(
923 role: PromptMessageRole,
924 data: impl Into<String>,
925 mime_type: impl Into<String>,
926 ) -> Self {
927 Self {
928 role,
929 content: PromptMessageContent::Image {
930 data: data.into(),
931 mime_type: mime_type.into(),
932 },
933 }
934 }
935}
936
937impl CompleteResult {
938 pub fn simple(completion: impl Into<String>) -> Self {
940 Self {
941 completion: vec![CompletionInfo {
942 completion: completion.into(),
943 has_more: Some(false),
944 }],
945 }
946 }
947}
948
949#[derive(Debug, Clone, Serialize, Deserialize)]
951pub struct Prompt {
952 pub name: String,
953 #[serde(skip_serializing_if = "Option::is_none")]
954 pub title: Option<String>,
955 pub description: Option<String>,
956 pub arguments: Option<Vec<PromptArgument>>,
957 #[serde(skip_serializing_if = "Option::is_none")]
958 pub icons: Option<Vec<Icon>>,
959}
960
961#[derive(Debug, Clone, Serialize, Deserialize)]
963pub struct PromptArgument {
964 pub name: String,
965 pub description: Option<String>,
966 pub required: Option<bool>,
967}
968
969#[derive(Debug, Clone, Serialize, Deserialize)]
971pub struct ListPromptsResult {
972 pub prompts: Vec<Prompt>,
973 #[serde(skip_serializing_if = "Option::is_none")]
974 pub next_cursor: Option<String>,
975}
976
977#[derive(Debug, Clone, Serialize, Deserialize)]
979pub struct GetPromptRequestParam {
980 pub name: String,
981 pub arguments: Option<HashMap<String, String>>,
982}
983
984#[derive(Debug, Clone, Serialize, Deserialize)]
986#[serde(rename_all = "lowercase")]
987pub enum PromptMessageRole {
988 User,
989 Assistant,
990 System,
991}
992
993#[derive(Debug, Clone, Serialize, Deserialize)]
995#[serde(tag = "type")]
996pub enum PromptMessageContent {
997 #[serde(rename = "text")]
998 Text { text: String },
999 #[serde(rename = "image")]
1000 Image { data: String, mime_type: String },
1001}
1002
1003#[derive(Debug, Clone, Serialize, Deserialize)]
1005pub struct PromptMessage {
1006 pub role: PromptMessageRole,
1007 pub content: PromptMessageContent,
1008}
1009
1010#[derive(Debug, Clone, Serialize, Deserialize)]
1012pub struct GetPromptResult {
1013 pub description: Option<String>,
1014 pub messages: Vec<PromptMessage>,
1015}
1016
1017#[derive(Debug, Clone, Serialize, Deserialize)]
1019pub struct InitializeRequestParam {
1020 #[serde(rename = "protocolVersion")]
1021 pub protocol_version: String,
1022 pub capabilities: serde_json::Value,
1023 #[serde(rename = "clientInfo")]
1024 pub client_info: Implementation,
1025}
1026
1027#[derive(Debug, Clone, Serialize, Deserialize)]
1029pub struct InitializeResult {
1030 #[serde(rename = "protocolVersion")]
1031 pub protocol_version: String,
1032 pub capabilities: ServerCapabilities,
1033 #[serde(rename = "serverInfo")]
1034 pub server_info: Implementation,
1035 #[serde(skip_serializing_if = "Option::is_none")]
1036 pub instructions: Option<String>,
1037}
1038
1039#[derive(Debug, Clone, Serialize, Deserialize)]
1041#[serde(rename_all = "camelCase")]
1042pub struct CompletionContext {
1043 pub argument_names: Vec<String>,
1045 pub values: HashMap<String, serde_json::Value>,
1047}
1048
1049impl CompletionContext {
1050 pub fn new(argument_names: Vec<String>, values: HashMap<String, serde_json::Value>) -> Self {
1052 Self {
1053 argument_names,
1054 values,
1055 }
1056 }
1057
1058 pub fn argument_names_iter(&self) -> impl Iterator<Item = &String> {
1060 self.argument_names.iter()
1061 }
1062}
1063
1064#[derive(Debug, Clone, Serialize, Deserialize)]
1066pub struct CompleteRequestParam {
1067 pub ref_: String,
1068 pub argument: serde_json::Value,
1069 #[serde(skip_serializing_if = "Option::is_none")]
1071 pub context: Option<CompletionContext>,
1072}
1073
1074#[derive(Debug, Clone, Serialize, Deserialize)]
1076pub struct CompletionInfo {
1077 pub completion: String,
1078 pub has_more: Option<bool>,
1079}
1080
1081#[derive(Debug, Clone, Serialize, Deserialize)]
1083pub struct CompleteResult {
1084 pub completion: Vec<CompletionInfo>,
1085}
1086
1087#[derive(Debug, Clone, Serialize, Deserialize)]
1089pub struct SetLevelRequestParam {
1090 pub level: LogLevel,
1091}
1092
1093#[derive(Debug, Clone, Serialize, Deserialize)]
1095pub struct ResourceTemplate {
1096 #[serde(rename = "uriTemplate")]
1097 pub uri_template: String,
1098 pub name: String,
1099 pub description: Option<String>,
1100 #[serde(rename = "mimeType")]
1101 pub mime_type: Option<String>,
1102}
1103
1104#[derive(Debug, Clone, Serialize, Deserialize)]
1106pub struct ListResourceTemplatesResult {
1107 #[serde(rename = "resourceTemplates")]
1108 pub resource_templates: Vec<ResourceTemplate>,
1109 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
1110 pub next_cursor: Option<String>,
1111}
1112
1113#[derive(Debug, Clone, Serialize, Deserialize)]
1115pub struct SubscribeRequestParam {
1116 pub uri: String,
1117}
1118
1119#[derive(Debug, Clone, Serialize, Deserialize)]
1121pub struct UnsubscribeRequestParam {
1122 pub uri: String,
1123}
1124
1125#[derive(Debug, Clone, Serialize, Deserialize)]
1128pub struct ResourceUpdatedNotification {
1129 pub uri: String,
1131}
1132
1133#[derive(Debug, Clone, Serialize, Deserialize)]
1135pub struct ElicitationRequestParam {
1136 pub message: String,
1137 #[serde(rename = "requestedSchema")]
1138 pub requested_schema: serde_json::Value,
1139}
1140
1141#[derive(Debug, Clone, Serialize, Deserialize)]
1143#[serde(rename_all = "lowercase")]
1144pub enum ElicitationAction {
1145 Accept,
1146 Decline,
1147 Cancel,
1148}
1149
1150#[derive(Debug, Clone, Serialize, Deserialize)]
1152pub struct ElicitationResponse {
1153 pub action: ElicitationAction,
1154 #[serde(skip_serializing_if = "Option::is_none")]
1155 pub data: Option<serde_json::Value>,
1156}
1157
1158#[derive(Debug, Clone, Serialize, Deserialize)]
1160pub struct ElicitationResult {
1161 pub response: ElicitationResponse,
1162}
1163
1164impl ElicitationResult {
1165 pub fn accept(data: serde_json::Value) -> Self {
1167 Self {
1168 response: ElicitationResponse {
1169 action: ElicitationAction::Accept,
1170 data: Some(data),
1171 },
1172 }
1173 }
1174
1175 pub fn decline() -> Self {
1177 Self {
1178 response: ElicitationResponse {
1179 action: ElicitationAction::Decline,
1180 data: None,
1181 },
1182 }
1183 }
1184
1185 pub fn cancel() -> Self {
1187 Self {
1188 response: ElicitationResponse {
1189 action: ElicitationAction::Cancel,
1190 data: None,
1191 },
1192 }
1193 }
1194}
1195
1196mod serde_json_string_or_object {
1198 use serde::{Deserialize, Deserializer, Serialize, Serializer};
1199 use serde_json::Value;
1200
1201 pub fn serialize<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
1202 where
1203 S: Serializer,
1204 {
1205 match serde_json::from_str::<Value>(value) {
1207 Ok(json_value) => json_value.serialize(serializer),
1208 Err(_) => serializer.serialize_str(value), }
1210 }
1211
1212 pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
1213 where
1214 D: Deserializer<'de>,
1215 {
1216 let value = Value::deserialize(deserializer)?;
1218 Ok(value.to_string())
1219 }
1220}