1use std::collections::HashMap;
36use std::fmt;
37
38use serde::{Deserialize, Serialize};
40use serde_json::{self, json};
41
42use crate::protocol::errors::{ProtocolError, ProtocolResult};
44use crate::protocol::{JsonRpcRequest, RequestId};
45use crate::protocol::constants::methods;
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
72pub struct ProtocolVersion(String);
73
74impl ProtocolVersion {
75 pub const CURRENT: &'static str = "2025-06-18";
77
78 pub fn new(version: impl Into<String>) -> ProtocolResult<Self> {
85 let version = version.into();
86 if Self::is_valid_version(&version) {
87 Ok(Self(version))
88 } else {
89 Err(ProtocolError::InvalidProtocolVersion(version))
90 }
91 }
92
93 pub fn current() -> Self {
97 Self(Self::CURRENT.to_string())
98 }
99
100 pub fn as_str(&self) -> &str {
102 &self.0
103 }
104
105 pub fn is_compatible_with(&self, other: &Self) -> bool {
110 self.0 == other.0
111 }
112
113 fn is_valid_version(version: &str) -> bool {
114 if version.len() != 10 {
116 return false;
117 }
118
119 let chars: Vec<char> = version.chars().collect();
120
121 chars.get(4) == Some(&'-') &&
123 chars.get(7) == Some(&'-') &&
124 chars[0..4].iter().all(|c| c.is_ascii_digit()) &&
125 chars[5..7].iter().all(|c| c.is_ascii_digit()) &&
126 chars[8..10].iter().all(|c| c.is_ascii_digit())
127 }
128}
129
130impl Default for ProtocolVersion {
131 fn default() -> Self {
132 Self::current()
133 }
134}
135
136impl fmt::Display for ProtocolVersion {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 write!(f, "{}", self.0)
139 }
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
166pub struct Uri(String);
167
168impl Uri {
169 pub fn new(uri: impl Into<String>) -> ProtocolResult<Self> {
175 let uri = uri.into();
176 if Self::is_valid_uri(&uri) {
177 Ok(Self(uri))
178 } else {
179 Err(ProtocolError::InvalidUri(uri))
180 }
181 }
182
183 pub fn new_unchecked(uri: impl Into<String>) -> Self {
188 Self(uri.into())
189 }
190
191 pub fn as_str(&self) -> &str {
193 &self.0
194 }
195
196 pub fn scheme(&self) -> Option<&str> {
198 self.0.split(':').next()
199 }
200
201 pub fn is_file_uri(&self) -> bool {
203 self.scheme() == Some("file")
204 }
205
206 pub fn is_http_uri(&self) -> bool {
208 matches!(self.scheme(), Some("http") | Some("https"))
209 }
210
211 fn is_valid_uri(uri: &str) -> bool {
212 !uri.is_empty() && uri.contains(':') && !uri.starts_with(':')
214 }
215}
216
217impl fmt::Display for Uri {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 write!(f, "{}", self.0)
220 }
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
245pub struct MimeType(String);
246
247impl MimeType {
248 pub fn new(mime_type: impl Into<String>) -> ProtocolResult<Self> {
254 let mime_type = mime_type.into();
255 if Self::is_valid_mime_type(&mime_type) {
256 Ok(Self(mime_type))
257 } else {
258 Err(ProtocolError::InvalidMimeType(mime_type))
259 }
260 }
261
262 pub fn as_str(&self) -> &str {
264 &self.0
265 }
266
267 pub fn main_type(&self) -> &str {
269 self.0.split('/').next().unwrap_or("")
270 }
271
272 pub fn sub_type(&self) -> &str {
274 self.0.split('/').nth(1).unwrap_or("")
275 }
276
277 pub fn is_text(&self) -> bool {
279 self.main_type() == "text"
280 }
281
282 pub fn is_image(&self) -> bool {
284 self.main_type() == "image"
285 }
286
287 fn is_valid_mime_type(mime_type: &str) -> bool {
288 if !mime_type.contains('/') || mime_type.starts_with('/') || mime_type.ends_with('/') {
290 return false;
291 }
292
293 let parts: Vec<&str> = mime_type.split('/').collect();
294 parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty()
295 }
296}
297
298impl fmt::Display for MimeType {
299 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300 write!(f, "{}", self.0)
301 }
302}
303
304#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
324pub struct Base64Data(String);
325
326impl Base64Data {
327 pub fn new(data: impl Into<String>) -> ProtocolResult<Self> {
333 let data = data.into();
334 if Self::is_valid_base64(&data) {
335 Ok(Self(data))
336 } else {
337 Err(ProtocolError::InvalidBase64Data)
338 }
339 }
340
341 pub fn as_str(&self) -> &str {
343 &self.0
344 }
345
346 pub fn len(&self) -> usize {
348 self.0.len()
349 }
350
351 pub fn is_empty(&self) -> bool {
353 self.0.is_empty()
354 }
355
356 fn is_valid_base64(data: &str) -> bool {
357 if data.is_empty() {
359 return false;
360 }
361
362 data.chars().all(|c| {
364 c.is_ascii_alphanumeric() || c == '+' || c == '/' || c == '='
365 }) &&
366 !data.trim_end_matches('=').contains('=')
368 }
369}
370
371impl fmt::Display for Base64Data {
372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 write!(f, "{}", self.0)
374 }
375}
376
377#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
393pub struct ClientInfo {
394 pub name: String,
396 pub version: String,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
416pub struct ServerInfo {
417 pub name: String,
419 pub version: String,
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
432#[serde(tag = "type")]
433pub enum Content {
434 #[serde(rename = "text")]
436 Text {
437 text: String,
439 #[serde(skip_serializing_if = "Option::is_none")]
441 uri: Option<Uri>,
442 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
444 mime_type: Option<MimeType>,
445 },
446
447 #[serde(rename = "image")]
449 Image {
450 #[serde(rename = "data")]
452 data: Base64Data,
453 #[serde(rename = "mimeType")]
455 mime_type: MimeType,
456 #[serde(skip_serializing_if = "Option::is_none")]
458 uri: Option<Uri>,
459 },
460
461 #[serde(rename = "resource")]
463 Resource {
464 #[serde(rename = "uri")]
466 resource: Uri,
467 text: Option<String>,
469 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
471 mime_type: Option<MimeType>,
472 },
473}
474
475impl Content {
476 pub fn text(text: impl Into<String>) -> Self {
478 Self::Text {
479 text: text.into(),
480 uri: None,
481 mime_type: None,
482 }
483 }
484
485 pub fn text_with_uri(text: impl Into<String>, uri: impl Into<String>) -> Result<Self, String> {
487 let uri_str = uri.into();
488 let uri = Uri::new_unchecked(uri_str);
489 Ok(Self::Text {
490 text: text.into(),
491 uri: Some(uri),
492 mime_type: None,
493 })
494 }
495
496 pub fn as_text(&self) -> Option<&str> {
498 match self {
499 Content::Text { text, .. } => Some(text),
500 Content::Resource { text: Some(text), .. } => Some(text),
501 _ => None,
502 }
503 }
504}
505
506#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
508pub struct Tool {
509 pub name: String,
510 pub description: Option<String>,
511 #[serde(rename = "inputSchema")]
512 pub input_schema: serde_json::Value,
513}
514
515#[derive(Debug, Clone, Serialize, Deserialize, Default)]
518pub struct ClientCapabilities {
519 pub experimental: Option<serde_json::Value>,
520 pub sampling: Option<SamplingCapabilities>,
521 pub roots: Option<RootsCapabilities>,
522}
523
524#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
526pub struct ServerCapabilities {
527 pub experimental: Option<serde_json::Value>,
528 pub logging: Option<LoggingCapabilities>,
529 pub prompts: Option<PromptCapabilities>,
530 pub resources: Option<ResourceCapabilities>,
531 pub tools: Option<ToolCapabilities>,
532}
533
534impl Default for ServerCapabilities {
535 fn default() -> Self {
536 Self {
537 experimental: Some(json!({})), logging: None,
539 prompts: None,
540 resources: None,
541 tools: None,
542 }
543 }
544}
545
546#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
548pub struct SamplingCapabilities {}
549
550#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
552pub struct RootsCapabilities {
553 pub list_changed: Option<bool>,
554}
555
556#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
558#[derive(Default)]
559pub struct LoggingCapabilities {}
560
561
562#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
564pub struct PromptCapabilities {
565 pub list_changed: Option<bool>,
566}
567
568impl Default for PromptCapabilities {
569 fn default() -> Self {
570 Self {
571 list_changed: Some(false),
572 }
573 }
574}
575
576#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
578pub struct ResourceCapabilities {
579 pub subscribe: Option<bool>,
580 pub list_changed: Option<bool>,
581}
582
583impl Default for ResourceCapabilities {
584 fn default() -> Self {
585 Self {
586 subscribe: Some(false),
587 list_changed: Some(false),
588 }
589 }
590}
591
592#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
594pub struct ToolCapabilities {
595 pub list_changed: Option<bool>,
596}
597
598impl Default for ToolCapabilities {
599 fn default() -> Self {
600 Self {
601 list_changed: Some(false),
602 }
603 }
604}
605
606#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
608pub struct Prompt {
609 pub name: String,
611 pub title: Option<String>,
613 pub description: Option<String>,
615 pub arguments: Vec<PromptArgument>,
617}
618
619#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
621pub struct PromptArgument {
622 pub name: String,
624 pub description: Option<String>,
626 pub required: bool,
628}
629
630impl PromptArgument {
631 pub fn required(name: impl Into<String>, description: Option<impl Into<String>>) -> Self {
633 Self {
634 name: name.into(),
635 description: description.map(|d| d.into()),
636 required: true,
637 }
638 }
639
640 pub fn optional(name: impl Into<String>, description: Option<impl Into<String>>) -> Self {
642 Self {
643 name: name.into(),
644 description: description.map(|d| d.into()),
645 required: false,
646 }
647 }
648}
649
650#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
652pub struct PromptMessage {
653 pub role: String,
655 pub content: Content,
657}
658
659impl PromptMessage {
660 pub fn user(content: Content) -> Self {
662 Self {
663 role: "user".to_string(),
664 content,
665 }
666 }
667
668 pub fn assistant(content: Content) -> Self {
670 Self {
671 role: "assistant".to_string(),
672 content,
673 }
674 }
675
676 pub fn system(content: Content) -> Self {
678 Self {
679 role: "system".to_string(),
680 content,
681 }
682 }
683}
684
685#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
687pub struct Resource {
688 pub uri: Uri,
690 pub name: String,
692 pub description: Option<String>,
694 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
696 pub mime_type: Option<MimeType>,
697}
698
699#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
701#[serde(rename_all = "lowercase")]
702pub enum LogLevel {
703 Debug,
704 Info,
705 Warning,
706 Error,
707 Critical,
708}
709
710impl LogLevel {
711 pub fn as_str(&self) -> &'static str {
713 match self {
714 LogLevel::Debug => "debug",
715 LogLevel::Info => "info",
716 LogLevel::Warning => "warning",
717 LogLevel::Error => "error",
718 LogLevel::Critical => "critical",
719 }
720 }
721}
722
723#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
725pub struct LoggingConfig {
726 pub level: LogLevel,
728}
729
730impl Default for LoggingConfig {
731 fn default() -> Self {
732 Self {
733 level: LogLevel::Info,
734 }
735 }
736}
737
738impl LoggingConfig {
739 pub fn new(level: LogLevel) -> Self {
741 Self { level }
742 }
743
744 pub fn min_level(&self) -> &LogLevel {
746 &self.level
747 }
748}
749
750#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
752pub struct InitializeRequest {
753 #[serde(rename = "protocolVersion")]
755 pub protocol_version: ProtocolVersion,
756 pub capabilities: serde_json::Value,
758 #[serde(rename = "clientInfo")]
760 pub client_info: ClientInfo,
761}
762
763#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
765pub struct InitializeResponse {
766 #[serde(rename = "protocolVersion")]
768 pub protocol_version: ProtocolVersion,
769 pub capabilities: serde_json::Value,
771 #[serde(rename = "serverInfo")]
773 pub server_info: ServerInfo,
774}
775
776impl InitializeResponse {
777 pub fn new(
779 capabilities: serde_json::Value,
780 server_info: ServerInfo,
781 _instructions: Option<String>, ) -> Self {
783 Self {
784 protocol_version: ProtocolVersion::current(),
785 capabilities,
786 server_info,
787 }
788 }
789}
790
791#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
793pub struct SetLoggingRequest {
794 pub level: LogLevel,
796}
797
798impl SetLoggingRequest {
799 pub fn new(level: LogLevel) -> Self {
801 Self { level }
802 }
803}
804
805#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
807pub struct GetPromptRequest {
808 pub name: String,
810 pub arguments: std::collections::HashMap<String, String>,
812}
813
814#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
816pub struct ReadResourceRequest {
817 pub uri: Uri,
819}
820
821#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
823pub struct SubscribeResourceRequest {
824 pub uri: Uri,
826}
827
828#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
830pub struct UnsubscribeResourceRequest {
831 pub uri: Uri,
833}
834
835#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
837pub struct CallToolRequest {
838 pub name: String,
840 pub arguments: serde_json::Value,
842}
843
844#[derive(Debug, Clone, Serialize, Deserialize)]
846pub struct ListResourcesRequest {
847 pub cursor: Option<String>,
848}
849
850impl Default for ListResourcesRequest {
851 fn default() -> Self {
852 Self::new()
853 }
854}
855
856impl ListResourcesRequest {
857 pub fn new() -> Self {
859 Self { cursor: None }
860 }
861
862 pub fn with_cursor(cursor: impl Into<String>) -> Self {
864 Self { cursor: Some(cursor.into()) }
865 }
866
867 pub fn to_jsonrpc_request(&self, id: RequestId) -> Result<JsonRpcRequest, ProtocolError> {
869 let params = serde_json::to_value(self)
870 .map_err(|e| ProtocolError::Serialization { message: format!("Failed to serialize ListResourcesRequest: {e}") })?;
871
872 Ok(JsonRpcRequest {
873 jsonrpc: "2.0".to_string(),
874 method: methods::RESOURCES_LIST.to_string(),
875 params: Some(params),
876 id,
877 })
878 }
879}
880
881#[derive(Debug, Clone, Serialize, Deserialize)]
883pub struct ListResourcesResponse {
884 pub resources: Vec<Resource>,
885 pub next_cursor: Option<String>,
886}
887
888#[derive(Debug, Clone, Serialize, Deserialize)]
890pub struct ListPromptsRequest {
891 pub cursor: Option<String>,
892}
893
894impl Default for ListPromptsRequest {
895 fn default() -> Self {
896 Self::new()
897 }
898}
899
900impl ListPromptsRequest {
901 pub fn new() -> Self {
903 Self { cursor: None }
904 }
905
906 pub fn with_cursor(cursor: impl Into<String>) -> Self {
908 Self { cursor: Some(cursor.into()) }
909 }
910
911 pub fn to_jsonrpc_request(&self, id: RequestId) -> Result<JsonRpcRequest, ProtocolError> {
913 let params = serde_json::to_value(self)
914 .map_err(|e| ProtocolError::Serialization { message: format!("Failed to serialize ListPromptsRequest: {e}") })?;
915
916 Ok(JsonRpcRequest {
917 jsonrpc: "2.0".to_string(),
918 method: methods::PROMPTS_LIST.to_string(),
919 params: Some(params),
920 id,
921 })
922 }
923}
924
925#[derive(Debug, Clone, Serialize, Deserialize)]
927pub struct ListPromptsResponse {
928 pub prompts: Vec<Prompt>,
929 pub next_cursor: Option<String>,
930}
931
932#[derive(Debug, Clone, Serialize, Deserialize)]
934pub struct ListToolsRequest {
935 pub cursor: Option<String>,
936}
937
938impl Default for ListToolsRequest {
939 fn default() -> Self {
940 Self::new()
941 }
942}
943
944impl ListToolsRequest {
945 pub fn new() -> Self {
947 Self { cursor: None }
948 }
949
950 pub fn with_cursor(cursor: impl Into<String>) -> Self {
952 Self { cursor: Some(cursor.into()) }
953 }
954
955 pub fn to_jsonrpc_request(&self, id: RequestId) -> Result<JsonRpcRequest, ProtocolError> {
957 let params = serde_json::to_value(self)
958 .map_err(|e| ProtocolError::Serialization { message: format!("Failed to serialize ListToolsRequest: {e}") })?;
959
960 Ok(JsonRpcRequest {
961 jsonrpc: "2.0".to_string(),
962 method: methods::TOOLS_LIST.to_string(),
963 params: Some(params),
964 id,
965 })
966 }
967}
968
969#[derive(Debug, Clone, Serialize, Deserialize)]
971pub struct ListToolsResponse {
972 pub tools: Vec<Tool>,
973 pub next_cursor: Option<String>,
974}
975
976#[derive(Debug, Clone, Serialize, Deserialize)]
978pub struct CallToolResponse {
979 pub content: Vec<Content>,
980 pub is_error: Option<bool>,
981}
982
983#[derive(Debug, Clone, Serialize, Deserialize)]
985pub struct GetPromptResponse {
986 pub description: Option<String>,
987 pub messages: Vec<PromptMessage>,
988}
989
990#[derive(Debug, Clone, Serialize, Deserialize)]
992pub struct ReadResourceResponse {
993 pub contents: Vec<Content>,
994}
995
996#[derive(Debug, Clone, Serialize, Deserialize)]
998pub struct SetLoggingResponse {
999 pub success: bool,
1000 pub message: Option<String>,
1001}
1002
1003#[derive(Debug, Clone, Serialize, Deserialize)]
1005pub struct ListResourceTemplatesResponse {
1006 pub resource_templates: Vec<ResourceTemplate>,
1007 pub next_cursor: Option<String>,
1008}
1009
1010#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1012pub struct ResourceTemplate {
1013 pub uri_template: String,
1014 pub name: String,
1015 pub description: Option<String>,
1016 pub mime_type: Option<String>,
1017}
1018
1019impl InitializeRequest {
1021 pub fn with_version(
1023 protocol_version: ProtocolVersion,
1024 capabilities: serde_json::Value,
1025 client_info: ClientInfo,
1026 ) -> Self {
1027 Self {
1028 protocol_version,
1029 capabilities,
1030 client_info,
1031 }
1032 }
1033
1034 pub fn to_jsonrpc_request(&self, id: RequestId) -> Result<JsonRpcRequest, ProtocolError> {
1036 let params = serde_json::to_value(self)
1037 .map_err(|e| ProtocolError::Serialization { message: format!("Failed to serialize InitializeRequest: {e}") })?;
1038
1039 Ok(JsonRpcRequest {
1040 jsonrpc: "2.0".to_string(),
1041 method: methods::INITIALIZE.to_string(),
1042 params: Some(params),
1043 id,
1044 })
1045 }
1046}
1047
1048impl ReadResourceRequest {
1049 pub fn new(uri: String) -> Result<Self, crate::protocol::TransportError> {
1051 Ok(Self { uri: Uri::new_unchecked(uri) })
1052 }
1053}
1054
1055impl SubscribeResourceRequest {
1056 pub fn new(uri: String) -> Result<Self, crate::protocol::TransportError> {
1058 Ok(Self { uri: Uri::new_unchecked(uri) })
1059 }
1060}
1061
1062impl CallToolRequest {
1063 pub fn new(name: String, arguments: serde_json::Value) -> Self {
1065 Self { name, arguments }
1066 }
1067}
1068
1069impl GetPromptRequest {
1070 pub fn new(name: String, arguments: HashMap<String, String>) -> Self {
1072 Self { name, arguments }
1073 }
1074}
1075
1076impl CallToolResponse {
1078 pub fn success(content: Vec<Content>) -> Self {
1080 Self {
1081 content,
1082 is_error: Some(false),
1083 }
1084 }
1085
1086 pub fn error_text(error: String) -> Self {
1088 Self {
1089 content: vec![Content::text(error)],
1090 is_error: Some(true),
1091 }
1092 }
1093}
1094
1095#[derive(Debug, Clone, PartialEq)]
1128pub struct ServerConfig {
1129 pub server_info: ServerInfo,
1131 pub capabilities: ServerCapabilities,
1133 pub protocol_version: ProtocolVersion,
1135 pub instructions: Option<String>,
1137}
1138
1139impl Default for ServerConfig {
1140 fn default() -> Self {
1141 Self {
1142 server_info: ServerInfo {
1143 name: "airsprotocols-mcp-server".to_string(),
1144 version: env!("CARGO_PKG_VERSION").to_string(),
1145 },
1146 capabilities: ServerCapabilities::default(),
1147 protocol_version: ProtocolVersion::current(),
1148 instructions: Some(
1149 "MCP server with configurable capabilities. Use appropriate authentication method."
1150 .to_string(),
1151 ),
1152 }
1153 }
1154}
1155
1156#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1162pub struct CallToolResult {
1163 pub content: Vec<Content>,
1165 #[serde(default)]
1167 pub is_error: bool,
1168}
1169
1170impl CallToolResult {
1171 pub fn success(content: Vec<Content>) -> Self {
1173 Self {
1174 content,
1175 is_error: false,
1176 }
1177 }
1178
1179 pub fn error(content: Vec<Content>) -> Self {
1181 Self {
1182 content,
1183 is_error: true,
1184 }
1185 }
1186}
1187
1188#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1190pub struct ReadResourceResult {
1191 pub contents: Vec<Content>,
1193}
1194
1195impl ReadResourceResult {
1196 pub fn new(contents: Vec<Content>) -> Self {
1198 Self { contents }
1199 }
1200}
1201
1202#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1204pub struct GetPromptResult {
1205 pub description: Option<String>,
1207 pub messages: Vec<PromptMessage>,
1209}
1210
1211impl GetPromptResult {
1212 pub fn new(description: Option<String>, messages: Vec<PromptMessage>) -> Self {
1214 Self { description, messages }
1215 }
1216}
1217
1218#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1220pub struct ListResourcesResult {
1221 pub resources: Vec<Resource>,
1223 pub next_cursor: Option<String>,
1225}
1226
1227impl ListResourcesResult {
1228 pub fn new(resources: Vec<Resource>) -> Self {
1230 Self {
1231 resources,
1232 next_cursor: None,
1233 }
1234 }
1235
1236 pub fn with_cursor(resources: Vec<Resource>, next_cursor: Option<String>) -> Self {
1238 Self {
1239 resources,
1240 next_cursor,
1241 }
1242 }
1243}
1244
1245#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1247pub struct ListToolsResult {
1248 pub tools: Vec<Tool>,
1250 pub next_cursor: Option<String>,
1252}
1253
1254impl ListToolsResult {
1255 pub fn new(tools: Vec<Tool>) -> Self {
1257 Self {
1258 tools,
1259 next_cursor: None,
1260 }
1261 }
1262
1263 pub fn with_cursor(tools: Vec<Tool>, next_cursor: Option<String>) -> Self {
1265 Self {
1266 tools,
1267 next_cursor,
1268 }
1269 }
1270}
1271
1272#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1274pub struct ListPromptsResult {
1275 pub prompts: Vec<Prompt>,
1277 pub next_cursor: Option<String>,
1279}
1280
1281impl ListPromptsResult {
1282 pub fn new(prompts: Vec<Prompt>) -> Self {
1284 Self {
1285 prompts,
1286 next_cursor: None,
1287 }
1288 }
1289
1290 pub fn with_cursor(prompts: Vec<Prompt>, next_cursor: Option<String>) -> Self {
1292 Self {
1293 prompts,
1294 next_cursor,
1295 }
1296 }
1297}
1298
1299#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1301pub struct ListResourceTemplatesResult {
1302 pub resource_templates: Vec<ResourceTemplate>,
1304 pub next_cursor: Option<String>,
1306}
1307
1308impl ListResourceTemplatesResult {
1309 pub fn new(resource_templates: Vec<ResourceTemplate>) -> Self {
1311 Self {
1312 resource_templates,
1313 next_cursor: None,
1314 }
1315 }
1316
1317 pub fn with_cursor(resource_templates: Vec<ResourceTemplate>, next_cursor: Option<String>) -> Self {
1319 Self {
1320 resource_templates,
1321 next_cursor,
1322 }
1323 }
1324}
1325
1326