1use crate::protocol::types::*;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16pub struct InitializeParams {
17 #[serde(rename = "protocolVersion")]
19 pub protocol_version: String,
20 pub capabilities: ClientCapabilities,
22 #[serde(rename = "clientInfo")]
24 pub client_info: Implementation,
25 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
27 pub meta: Option<HashMap<String, serde_json::Value>>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
32pub struct CallToolParams {
33 pub name: String,
35 #[serde(skip_serializing_if = "Option::is_none")]
37 pub arguments: Option<HashMap<String, serde_json::Value>>,
38 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
40 pub meta: Option<HashMap<String, serde_json::Value>>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
45pub struct ReadResourceParams {
46 pub uri: String,
48 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
50 pub meta: Option<HashMap<String, serde_json::Value>>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
55pub struct SubscribeResourceParams {
56 pub uri: String,
58 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
60 pub meta: Option<HashMap<String, serde_json::Value>>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
65pub struct UnsubscribeResourceParams {
66 pub uri: String,
68 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
70 pub meta: Option<HashMap<String, serde_json::Value>>,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
75pub struct GetPromptParams {
76 pub name: String,
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub arguments: Option<HashMap<String, String>>,
81 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
83 pub meta: Option<HashMap<String, serde_json::Value>>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
88pub struct ListParams {
89 #[serde(skip_serializing_if = "Option::is_none")]
91 pub cursor: Option<String>,
92 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
94 pub meta: Option<HashMap<String, serde_json::Value>>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
99pub struct ListToolsParams {
100 #[serde(skip_serializing_if = "Option::is_none")]
102 pub cursor: Option<String>,
103 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
105 pub meta: Option<HashMap<String, serde_json::Value>>,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
110pub struct ListResourcesParams {
111 #[serde(skip_serializing_if = "Option::is_none")]
113 pub cursor: Option<String>,
114 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
116 pub meta: Option<HashMap<String, serde_json::Value>>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
121pub struct ListPromptsParams {
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub cursor: Option<String>,
125 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
127 pub meta: Option<HashMap<String, serde_json::Value>>,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
132pub struct PingParams {
133 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
135 pub meta: Option<HashMap<String, serde_json::Value>>,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
140pub struct ListResourceTemplatesParams {
141 #[serde(skip_serializing_if = "Option::is_none")]
143 pub cursor: Option<String>,
144 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
146 pub meta: Option<HashMap<String, serde_json::Value>>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
151pub struct ListRootsParams {
152 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
154 pub meta: Option<HashMap<String, serde_json::Value>>,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
159pub struct CompleteParams {
160 #[serde(rename = "ref")]
162 pub reference: CompletionReference,
163 pub argument: CompletionArgument,
165 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
167 pub meta: Option<HashMap<String, serde_json::Value>>,
168}
169
170#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
172#[serde(tag = "type")]
173pub enum CompletionReference {
174 #[serde(rename = "ref/prompt")]
175 Prompt { name: String },
176 #[serde(rename = "ref/resource")]
177 Resource { uri: String },
178 #[serde(rename = "ref/tool")]
179 Tool { name: String },
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
184pub struct CompletionArgument {
185 pub name: String,
187 pub value: String,
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
193pub struct CreateMessageParams {
194 pub messages: Vec<SamplingMessage>,
196 #[serde(rename = "maxTokens")]
198 pub max_tokens: u32,
199 #[serde(rename = "systemPrompt", skip_serializing_if = "Option::is_none")]
201 pub system_prompt: Option<String>,
202 #[serde(rename = "includeContext", skip_serializing_if = "Option::is_none")]
204 pub include_context: Option<String>,
205 #[serde(skip_serializing_if = "Option::is_none")]
207 pub temperature: Option<f32>,
208 #[serde(rename = "stopSequences", skip_serializing_if = "Option::is_none")]
210 pub stop_sequences: Option<Vec<String>>,
211 #[serde(rename = "modelPreferences", skip_serializing_if = "Option::is_none")]
213 pub model_preferences: Option<ModelPreferences>,
214 #[serde(skip_serializing_if = "Option::is_none")]
216 pub tools: Option<Vec<Tool>>,
217 #[serde(rename = "toolChoice", skip_serializing_if = "Option::is_none")]
219 pub tool_choice: Option<SamplingToolChoice>,
220 #[serde(skip_serializing_if = "Option::is_none")]
222 pub metadata: Option<HashMap<String, serde_json::Value>>,
223 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
225 pub meta: Option<HashMap<String, serde_json::Value>>,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
230pub struct SetLoggingLevelParams {
231 pub level: LoggingLevel,
233 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
235 pub meta: Option<HashMap<String, serde_json::Value>>,
236}
237
238#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
240pub struct ElicitParams {
241 pub message: String,
243 #[serde(skip_serializing_if = "Option::is_none")]
245 pub mode: Option<ElicitationMode>,
246 #[serde(skip_serializing_if = "Option::is_none")]
248 pub url: Option<String>,
249 #[serde(rename = "requestedSchema", skip_serializing_if = "Option::is_none")]
251 pub requested_schema: Option<ElicitationSchema>,
252 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
254 pub meta: Option<HashMap<String, serde_json::Value>>,
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
259#[serde(rename_all = "lowercase")]
260pub enum ElicitationMode {
261 Form,
262 Url,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
271pub struct InitializeResult {
272 #[serde(rename = "protocolVersion")]
274 pub protocol_version: String,
275 pub capabilities: ServerCapabilities,
277 #[serde(rename = "serverInfo")]
279 pub server_info: Implementation,
280 #[serde(skip_serializing_if = "Option::is_none")]
282 pub instructions: Option<String>,
283 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
285 pub meta: Option<HashMap<String, serde_json::Value>>,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
290pub struct ListToolsResult {
291 pub tools: Vec<Tool>,
293 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
295 pub next_cursor: Option<String>,
296 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
298 pub meta: Option<HashMap<String, serde_json::Value>>,
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
303pub struct ListResourcesResult {
304 pub resources: Vec<Resource>,
306 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
308 pub next_cursor: Option<String>,
309 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
311 pub meta: Option<HashMap<String, serde_json::Value>>,
312}
313
314#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
316pub struct ListResourceTemplatesResult {
317 #[serde(rename = "resourceTemplates")]
319 pub resource_templates: Vec<ResourceTemplate>,
320 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
322 pub next_cursor: Option<String>,
323 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
325 pub meta: Option<HashMap<String, serde_json::Value>>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
330pub struct ReadResourceResult {
331 pub contents: Vec<ResourceContents>,
333 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
335 pub meta: Option<HashMap<String, serde_json::Value>>,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
340pub struct ListPromptsResult {
341 pub prompts: Vec<Prompt>,
343 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
345 pub next_cursor: Option<String>,
346 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
348 pub meta: Option<HashMap<String, serde_json::Value>>,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
353pub struct CompleteResult {
354 pub completion: CompletionData,
356 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
358 pub meta: Option<HashMap<String, serde_json::Value>>,
359}
360
361#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
363pub struct CompletionData {
364 pub values: Vec<String>,
366 #[serde(skip_serializing_if = "Option::is_none")]
368 pub total: Option<u32>,
369 #[serde(rename = "hasMore", skip_serializing_if = "Option::is_none")]
371 pub has_more: Option<bool>,
372}
373
374#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
376pub struct ListRootsResult {
377 pub roots: Vec<Root>,
379 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
381 pub meta: Option<HashMap<String, serde_json::Value>>,
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
386pub struct PingResult {
387 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
389 pub meta: Option<HashMap<String, serde_json::Value>>,
390}
391
392#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
394pub struct SetLoggingLevelResult {
395 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
397 pub meta: Option<HashMap<String, serde_json::Value>>,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
402pub struct ElicitResult {
403 pub action: ElicitationAction,
405 #[serde(skip_serializing_if = "Option::is_none")]
407 pub content: Option<HashMap<String, serde_json::Value>>,
408 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
410 pub meta: Option<HashMap<String, serde_json::Value>>,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
415pub struct SubscribeResourceResult {
416 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
418 pub meta: Option<HashMap<String, serde_json::Value>>,
419}
420
421#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
423pub struct UnsubscribeResourceResult {
424 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
426 pub meta: Option<HashMap<String, serde_json::Value>>,
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
431pub struct Root {
432 pub uri: String,
434 #[serde(skip_serializing_if = "Option::is_none")]
436 pub name: Option<String>,
437}
438
439#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
445pub struct ProgressParams {
446 #[serde(rename = "progressToken")]
448 pub progress_token: ProgressToken,
449 pub progress: f32,
451 #[serde(skip_serializing_if = "Option::is_none")]
453 pub total: Option<f32>,
454 #[serde(skip_serializing_if = "Option::is_none")]
456 pub message: Option<String>,
457}
458
459#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
461pub struct ResourceUpdatedParams {
462 pub uri: String,
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
468pub struct CancelledParams {
469 #[serde(rename = "requestId")]
471 pub request_id: RequestId,
472 #[serde(skip_serializing_if = "Option::is_none")]
474 pub reason: Option<String>,
475}
476
477#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
479pub struct InitializedParams {
480 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
482 pub meta: Option<HashMap<String, serde_json::Value>>,
483}
484
485#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
487pub struct LoggingMessageParams {
488 pub level: LoggingLevel,
490 #[serde(skip_serializing_if = "Option::is_none")]
492 pub logger: Option<String>,
493 pub data: serde_json::Value,
495}
496
497#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
499pub struct ToolListChangedParams {
500 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
502 pub meta: Option<HashMap<String, serde_json::Value>>,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
507pub struct ResourceListChangedParams {
508 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
510 pub meta: Option<HashMap<String, serde_json::Value>>,
511}
512
513#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
515pub struct PromptListChangedParams {
516 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
518 pub meta: Option<HashMap<String, serde_json::Value>>,
519}
520
521#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
523pub struct ElicitationCompleteParams {
524 pub result: ElicitResult,
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
530pub struct TaskSendParams {
531 #[serde(rename = "taskId")]
533 pub task_id: String,
534 pub task: serde_json::Value,
536 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
538 pub meta: Option<HashMap<String, serde_json::Value>>,
539}
540
541#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
543pub struct TaskCancelParams {
544 #[serde(rename = "taskId")]
546 pub task_id: String,
547 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
549 pub meta: Option<HashMap<String, serde_json::Value>>,
550}
551
552#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
554pub struct TaskStatusUpdateParams {
555 #[serde(rename = "taskId")]
557 pub task_id: String,
558 pub status: String,
560 #[serde(skip_serializing_if = "Option::is_none")]
562 pub detail: Option<serde_json::Value>,
563}
564
565#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
567pub struct ProgressNotificationParams {
568 #[serde(rename = "progressToken")]
570 pub progress_token: ProgressToken,
571 pub progress: f32,
573 #[serde(skip_serializing_if = "Option::is_none")]
575 pub total: Option<f32>,
576 #[serde(skip_serializing_if = "Option::is_none")]
578 pub message: Option<String>,
579}
580
581#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
583pub struct LoggingMessageNotificationParams {
584 pub level: LoggingLevel,
586 #[serde(skip_serializing_if = "Option::is_none")]
588 pub logger: Option<String>,
589 pub data: serde_json::Value,
591}
592
593impl CallToolParams {
598 pub fn new(name: String) -> Self {
599 Self {
600 name,
601 arguments: None,
602 meta: None,
603 }
604 }
605
606 pub fn new_with_arguments(name: String, arguments: HashMap<String, serde_json::Value>) -> Self {
607 Self {
608 name,
609 arguments: Some(arguments),
610 meta: None,
611 }
612 }
613
614 pub fn with_arguments(mut self, arguments: HashMap<String, serde_json::Value>) -> Self {
615 self.arguments = Some(arguments);
616 self
617 }
618}
619
620impl ReadResourceParams {
621 pub fn new(uri: String) -> Self {
622 Self { uri, meta: None }
623 }
624}
625
626impl GetPromptParams {
627 pub fn new(name: String) -> Self {
628 Self {
629 name,
630 arguments: None,
631 meta: None,
632 }
633 }
634
635 pub fn new_with_arguments(name: String, arguments: HashMap<String, String>) -> Self {
636 Self {
637 name,
638 arguments: Some(arguments),
639 meta: None,
640 }
641 }
642
643 pub fn with_arguments(mut self, arguments: HashMap<String, String>) -> Self {
644 self.arguments = Some(arguments);
645 self
646 }
647}
648
649impl InitializeParams {
650 pub fn new(
651 protocol_version: String,
652 capabilities: ClientCapabilities,
653 client_info: Implementation,
654 ) -> Self {
655 Self {
656 protocol_version,
657 capabilities,
658 client_info,
659 meta: None,
660 }
661 }
662}
663
664impl InitializeResult {
665 pub fn new(
666 protocol_version: String,
667 capabilities: ServerCapabilities,
668 server_info: Implementation,
669 ) -> Self {
670 Self {
671 protocol_version,
672 capabilities,
673 server_info,
674 instructions: None,
675 meta: None,
676 }
677 }
678}
679
680impl CreateMessageParams {
681 pub fn new(messages: Vec<SamplingMessage>, max_tokens: u32) -> Self {
683 Self {
684 messages,
685 max_tokens,
686 system_prompt: None,
687 include_context: None,
688 temperature: None,
689 stop_sequences: None,
690 model_preferences: None,
691 tools: None,
692 tool_choice: None,
693 metadata: None,
694 meta: None,
695 }
696 }
697
698 pub fn with_system_prompt<S: Into<String>>(mut self, system_prompt: S) -> Self {
700 self.system_prompt = Some(system_prompt.into());
701 self
702 }
703
704 pub fn with_include_context<S: Into<String>>(mut self, include_context: S) -> Self {
706 self.include_context = Some(include_context.into());
707 self
708 }
709
710 pub fn with_temperature(mut self, temperature: f32) -> Self {
712 self.temperature = Some(temperature);
713 self
714 }
715
716 pub fn with_stop_sequences(mut self, stop_sequences: Vec<String>) -> Self {
718 self.stop_sequences = Some(stop_sequences);
719 self
720 }
721
722 pub fn with_model_preferences(mut self, model_preferences: ModelPreferences) -> Self {
724 self.model_preferences = Some(model_preferences);
725 self
726 }
727
728 pub fn with_tools(mut self, tools: Vec<Tool>) -> Self {
730 self.tools = Some(tools);
731 self
732 }
733
734 pub fn add_tool(mut self, tool: Tool) -> Self {
736 self.tools.get_or_insert_with(Vec::new).push(tool);
737 self
738 }
739
740 pub fn with_tool_choice(mut self, tool_choice: SamplingToolChoice) -> Self {
742 self.tool_choice = Some(tool_choice);
743 self
744 }
745
746 pub fn with_metadata(mut self, metadata: HashMap<String, serde_json::Value>) -> Self {
748 self.metadata = Some(metadata);
749 self
750 }
751
752 pub fn with_meta(mut self, meta: HashMap<String, serde_json::Value>) -> Self {
754 self.meta = Some(meta);
755 self
756 }
757}
758
759impl ElicitParams {
760 pub fn new<S: Into<String>>(message: S) -> Self {
762 Self {
763 message: message.into(),
764 mode: None,
765 url: None,
766 requested_schema: None,
767 meta: None,
768 }
769 }
770
771 pub fn form<S: Into<String>>(message: S, requested_schema: ElicitationSchema) -> Self {
773 Self {
774 message: message.into(),
775 mode: Some(ElicitationMode::Form),
776 url: None,
777 requested_schema: Some(requested_schema),
778 meta: None,
779 }
780 }
781
782 pub fn url<M: Into<String>, U: Into<String>>(message: M, url: U) -> Self {
784 Self {
785 message: message.into(),
786 mode: Some(ElicitationMode::Url),
787 url: Some(url.into()),
788 requested_schema: None,
789 meta: None,
790 }
791 }
792
793 pub fn with_mode(mut self, mode: ElicitationMode) -> Self {
795 self.mode = Some(mode);
796 self
797 }
798
799 pub fn with_url<S: Into<String>>(mut self, url: S) -> Self {
801 self.url = Some(url.into());
802 self
803 }
804
805 pub fn with_requested_schema(mut self, requested_schema: ElicitationSchema) -> Self {
807 self.requested_schema = Some(requested_schema);
808 self
809 }
810
811 pub fn with_meta(mut self, meta: HashMap<String, serde_json::Value>) -> Self {
813 self.meta = Some(meta);
814 self
815 }
816}
817
818impl ElicitResult {
819 pub fn accepted(content: HashMap<String, serde_json::Value>) -> Self {
821 Self {
822 action: ElicitationAction::Accept,
823 content: Some(content),
824 meta: None,
825 }
826 }
827
828 pub fn declined() -> Self {
830 Self {
831 action: ElicitationAction::Decline,
832 content: None,
833 meta: None,
834 }
835 }
836
837 pub fn cancelled() -> Self {
839 Self {
840 action: ElicitationAction::Cancel,
841 content: None,
842 meta: None,
843 }
844 }
845
846 pub fn with_meta(mut self, meta: HashMap<String, serde_json::Value>) -> Self {
848 self.meta = Some(meta);
849 self
850 }
851}
852
853impl ElicitationCompleteParams {
854 pub fn new(result: ElicitResult) -> Self {
856 Self { result }
857 }
858}
859
860impl TaskSendParams {
861 pub fn new<S: Into<String>>(task_id: S, task: serde_json::Value) -> Self {
863 Self {
864 task_id: task_id.into(),
865 task,
866 meta: None,
867 }
868 }
869
870 pub fn with_meta(mut self, meta: HashMap<String, serde_json::Value>) -> Self {
872 self.meta = Some(meta);
873 self
874 }
875}
876
877impl TaskCancelParams {
878 pub fn new<S: Into<String>>(task_id: S) -> Self {
880 Self {
881 task_id: task_id.into(),
882 meta: None,
883 }
884 }
885
886 pub fn with_meta(mut self, meta: HashMap<String, serde_json::Value>) -> Self {
888 self.meta = Some(meta);
889 self
890 }
891}
892
893impl TaskStatusUpdateParams {
894 pub fn new<T: Into<String>, S: Into<String>>(task_id: T, status: S) -> Self {
896 Self {
897 task_id: task_id.into(),
898 status: status.into(),
899 detail: None,
900 }
901 }
902
903 pub fn with_detail(mut self, detail: serde_json::Value) -> Self {
905 self.detail = Some(detail);
906 self
907 }
908}
909
910impl Root {
911 pub fn new(uri: String) -> Self {
912 Self { uri, name: None }
913 }
914
915 pub fn with_name(mut self, name: String) -> Self {
916 self.name = Some(name);
917 self
918 }
919}
920
921#[cfg(test)]
926mod tests {
927 use super::*;
928 use serde_json::json;
929 use std::collections::HashMap;
930
931 #[test]
932 fn test_initialize_params_serialization() {
933 let params = InitializeParams {
934 protocol_version: "2025-11-25".to_string(),
935 capabilities: ClientCapabilities::default(),
936 client_info: Implementation {
937 name: "test-client".to_string(),
938 version: "1.0.0".to_string(),
939 description: None,
940 title: Some("Test Client".to_string()),
941 website_url: None,
942 icons: None,
943 },
944 meta: None,
945 };
946
947 let json = serde_json::to_value(¶ms).unwrap();
948 assert_eq!(json["protocolVersion"], "2025-11-25");
949 assert_eq!(json["clientInfo"]["name"], "test-client");
950
951 let deserialized: InitializeParams = serde_json::from_value(json).unwrap();
953 assert_eq!(deserialized.protocol_version, "2025-11-25");
954 }
955
956 #[test]
957 fn test_initialize_result_serialization() {
958 let result = InitializeResult {
959 protocol_version: "2025-11-25".to_string(),
960 capabilities: ServerCapabilities::default(),
961 server_info: Implementation {
962 name: "test-server".to_string(),
963 version: "1.0.0".to_string(),
964 description: None,
965 title: Some("Test Server".to_string()),
966 website_url: None,
967 icons: None,
968 },
969 instructions: Some("Test instructions".to_string()),
970 meta: None,
971 };
972
973 let json = serde_json::to_value(&result).unwrap();
974 assert_eq!(json["protocolVersion"], "2025-11-25");
975 assert_eq!(json["serverInfo"]["name"], "test-server");
976 assert_eq!(json["instructions"], "Test instructions");
977 }
978
979 #[test]
980 fn test_call_tool_params_serialization() {
981 let mut args = HashMap::new();
982 args.insert("input".to_string(), json!("test value"));
983
984 let params = CallToolParams {
985 name: "test_tool".to_string(),
986 arguments: Some(args),
987 meta: None,
988 };
989
990 let json = serde_json::to_value(¶ms).unwrap();
991 assert_eq!(json["name"], "test_tool");
992 assert_eq!(json["arguments"]["input"], "test value");
993 }
994
995 #[test]
996 fn test_call_tool_result_serialization() {
997 let result = CallToolResult {
998 content: vec![ContentBlock::text("Tool executed successfully")],
999 is_error: Some(false),
1000 structured_content: Some(json!({"status": "success", "data": 42})),
1001 meta: None,
1002 };
1003
1004 let json = serde_json::to_value(&result).unwrap();
1005 assert_eq!(json["isError"], false);
1006 assert_eq!(json["structuredContent"]["status"], "success");
1007 assert_eq!(json["structuredContent"]["data"], 42);
1008 }
1009
1010 #[test]
1011 fn test_list_tools_params_serialization() {
1012 let params = ListToolsParams {
1013 cursor: Some("page2".to_string()),
1014 meta: None,
1015 };
1016
1017 let json = serde_json::to_value(¶ms).unwrap();
1018 assert_eq!(json["cursor"], "page2");
1019 }
1020
1021 #[test]
1022 fn test_list_tools_result_serialization() {
1023 let tool = Tool::new("test_tool", "A test tool").with_title("Test Tool");
1024
1025 let result = ListToolsResult {
1026 tools: vec![tool],
1027 next_cursor: Some("page3".to_string()),
1028 meta: None,
1029 };
1030
1031 let json = serde_json::to_value(&result).unwrap();
1032 assert!(json["tools"].is_array());
1033 assert_eq!(json["tools"][0]["name"], "test_tool");
1034 assert_eq!(json["nextCursor"], "page3");
1035 }
1036
1037 #[test]
1038 fn test_create_message_params_serialization() {
1039 let message = SamplingMessage::user_text("Hello, AI!");
1040
1041 let params = CreateMessageParams {
1042 messages: vec![message],
1043 max_tokens: 1000,
1044 system_prompt: Some("You are helpful".to_string()),
1045 include_context: Some("thisServer".to_string()),
1046 temperature: Some(0.7),
1047 stop_sequences: None,
1048 model_preferences: None,
1049 tools: None,
1050 tool_choice: None,
1051 metadata: None,
1052 meta: None,
1053 };
1054
1055 let json = serde_json::to_value(¶ms).unwrap();
1056 assert_eq!(json["maxTokens"], 1000);
1057 assert_eq!(json["systemPrompt"], "You are helpful");
1058 assert_eq!(json["includeContext"], "thisServer");
1059 assert!((json["temperature"].as_f64().unwrap() - 0.7).abs() < 0.01);
1060 }
1061
1062 #[test]
1063 fn test_create_message_result_serialization() {
1064 let result = CreateMessageResult {
1065 role: Role::Assistant,
1066 content: SamplingContent::text("AI response here"),
1067 model: "claude-3-5-sonnet".to_string(),
1068 stop_reason: Some(StopReason::EndTurn),
1069 meta: None,
1070 };
1071
1072 let json = serde_json::to_value(&result).unwrap();
1073 assert_eq!(json["role"], "assistant");
1074 assert_eq!(json["content"]["text"], "AI response here");
1075 assert_eq!(json["model"], "claude-3-5-sonnet");
1076 assert_eq!(json["stopReason"], "endTurn");
1077 }
1078
1079 #[test]
1080 fn test_list_resources_params_serialization() {
1081 let params = ListResourcesParams {
1082 cursor: None,
1083 meta: None,
1084 };
1085
1086 let json = serde_json::to_value(¶ms).unwrap();
1087 assert!(json.is_object());
1088 }
1089
1090 #[test]
1091 fn test_read_resource_params_serialization() {
1092 let params = ReadResourceParams {
1093 uri: "file:///test.txt".to_string(),
1094 meta: None,
1095 };
1096
1097 let json = serde_json::to_value(¶ms).unwrap();
1098 assert_eq!(json["uri"], "file:///test.txt");
1099 }
1100
1101 #[test]
1102 fn test_list_prompts_result_serialization() {
1103 let prompt = Prompt::new("test_prompt")
1104 .with_title("Test Prompt")
1105 .with_description("A test prompt");
1106
1107 let result = ListPromptsResult {
1108 prompts: vec![prompt],
1109 next_cursor: None,
1110 meta: None,
1111 };
1112
1113 let json = serde_json::to_value(&result).unwrap();
1114 assert!(json["prompts"].is_array());
1115 assert_eq!(json["prompts"][0]["name"], "test_prompt");
1116 }
1117
1118 #[test]
1119 fn test_get_prompt_params_serialization() {
1120 let mut arguments = HashMap::new();
1121 arguments.insert("input".to_string(), "test input".to_string());
1122
1123 let params = GetPromptParams {
1124 name: "test_prompt".to_string(),
1125 arguments: Some(arguments),
1126 meta: None,
1127 };
1128
1129 let json = serde_json::to_value(¶ms).unwrap();
1130 assert_eq!(json["name"], "test_prompt");
1131 assert_eq!(json["arguments"]["input"], "test input");
1132 }
1133
1134 #[test]
1135 fn test_progress_params_serialization() {
1136 let params = ProgressParams {
1137 progress_token: json!("upload-123"),
1138 progress: 75.5,
1139 total: Some(100.0),
1140 message: Some("Uploading files...".to_string()),
1141 };
1142
1143 let json = serde_json::to_value(¶ms).unwrap();
1144 assert_eq!(json["progressToken"], "upload-123");
1145 assert_eq!(json["progress"], 75.5);
1146 assert_eq!(json["total"], 100.0);
1147 assert_eq!(json["message"], "Uploading files...");
1148 }
1149
1150 #[test]
1151 fn test_complete_params_serialization() {
1152 let reference = CompletionReference::Prompt {
1153 name: "test_prompt".to_string(),
1154 };
1155
1156 let params = CompleteParams {
1157 reference,
1158 argument: CompletionArgument {
1159 name: "input".to_string(),
1160 value: "partial".to_string(),
1161 },
1162 meta: None,
1163 };
1164
1165 let json = serde_json::to_value(¶ms).unwrap();
1166 assert_eq!(json["ref"]["type"], "ref/prompt");
1167 assert_eq!(json["ref"]["name"], "test_prompt");
1168 assert_eq!(json["argument"]["name"], "input");
1169 assert_eq!(json["argument"]["value"], "partial");
1170 }
1171
1172 #[test]
1173 fn test_all_message_roundtrip_compatibility() {
1174 let test_cases = vec![
1176 (
1177 "InitializeParams",
1178 json!({
1179 "protocolVersion": "2025-11-25",
1180 "capabilities": {},
1181 "clientInfo": {
1182 "name": "test",
1183 "version": "1.0.0"
1184 }
1185 }),
1186 ),
1187 ("ListToolsParams", json!({})),
1188 (
1189 "CallToolParams",
1190 json!({
1191 "name": "test_tool",
1192 "arguments": {"input": "test"}
1193 }),
1194 ),
1195 ];
1196
1197 for (type_name, test_json) in test_cases {
1198 match type_name {
1199 "InitializeParams" => {
1200 let _: InitializeParams = serde_json::from_value(test_json).unwrap();
1201 }
1202 "ListToolsParams" => {
1203 let _: ListToolsParams = serde_json::from_value(test_json).unwrap();
1204 }
1205 "CallToolParams" => {
1206 let _: CallToolParams = serde_json::from_value(test_json).unwrap();
1207 }
1208 _ => unreachable!(),
1209 }
1210 }
1211 }
1212
1213 #[test]
1214 fn test_message_metadata_handling() {
1215 let mut meta = HashMap::new();
1216 meta.insert("custom".to_string(), json!("value"));
1217
1218 let params = InitializeParams {
1219 protocol_version: "2025-11-25".to_string(),
1220 capabilities: ClientCapabilities::default(),
1221 client_info: Implementation::new("test", "1.0.0"),
1222 meta: Some(meta),
1223 };
1224
1225 let json = serde_json::to_value(¶ms).unwrap();
1226 assert_eq!(json["_meta"]["custom"], "value");
1227 }
1228
1229 #[test]
1230 fn test_constructor_methods() {
1231 let tool_params = CallToolParams::new("test_tool".to_string());
1233 assert_eq!(tool_params.name, "test_tool");
1234 assert!(tool_params.arguments.is_none());
1235
1236 let mut args = HashMap::new();
1237 args.insert("key".to_string(), json!("value"));
1238 let tool_params_with_args =
1239 CallToolParams::new_with_arguments("test_tool".to_string(), args.clone());
1240 assert_eq!(tool_params_with_args.name, "test_tool");
1241 assert_eq!(tool_params_with_args.arguments, Some(args));
1242
1243 let resource_params = ReadResourceParams::new("file:///test.txt".to_string());
1245 assert_eq!(resource_params.uri, "file:///test.txt");
1246
1247 let prompt_params = GetPromptParams::new("test_prompt".to_string());
1249 assert_eq!(prompt_params.name, "test_prompt");
1250 assert!(prompt_params.arguments.is_none());
1251
1252 let mut str_args = HashMap::new();
1253 str_args.insert("key".to_string(), "value".to_string());
1254 let prompt_params_with_args =
1255 GetPromptParams::new_with_arguments("test_prompt".to_string(), str_args.clone());
1256 assert_eq!(prompt_params_with_args.name, "test_prompt");
1257 assert_eq!(prompt_params_with_args.arguments, Some(str_args));
1258
1259 let root = Root::new("file:///root".to_string());
1261 assert_eq!(root.uri, "file:///root");
1262 assert!(root.name.is_none());
1263
1264 let root_with_name = root.with_name("Root Name".to_string());
1265 assert_eq!(root_with_name.name, Some("Root Name".to_string()));
1266
1267 let create_params =
1269 CreateMessageParams::new(vec![SamplingMessage::user_text("Hello")], 256)
1270 .with_system_prompt("You are helpful")
1271 .with_include_context("thisServer")
1272 .with_temperature(0.5)
1273 .with_stop_sequences(vec!["STOP".to_string()])
1274 .with_tool_choice(SamplingToolChoice::Auto)
1275 .add_tool(Tool::new("echo", "Echo tool"));
1276 assert_eq!(create_params.max_tokens, 256);
1277 assert_eq!(
1278 create_params.system_prompt,
1279 Some("You are helpful".to_string())
1280 );
1281 assert_eq!(create_params.tools.as_ref().map(Vec::len), Some(1));
1282 assert_eq!(create_params.tool_choice, Some(SamplingToolChoice::Auto));
1283
1284 let mut properties = HashMap::new();
1286 properties.insert(
1287 "name".to_string(),
1288 PrimitiveSchemaDefinition::String {
1289 title: Some("Name".to_string()),
1290 description: None,
1291 min_length: None,
1292 max_length: None,
1293 format: None,
1294 enum_values: None,
1295 enum_names: None,
1296 },
1297 );
1298 let schema = ElicitationSchema {
1299 schema_type: "object".to_string(),
1300 properties,
1301 required: Some(vec!["name".to_string()]),
1302 };
1303 let form_elicit = ElicitParams::form("Need your name", schema.clone());
1304 assert_eq!(form_elicit.mode, Some(ElicitationMode::Form));
1305 assert!(form_elicit.url.is_none());
1306 assert!(form_elicit.requested_schema.is_some());
1307
1308 let url_elicit = ElicitParams::url("Continue setup", "https://example.com/setup");
1309 assert_eq!(url_elicit.mode, Some(ElicitationMode::Url));
1310 assert_eq!(
1311 url_elicit.url,
1312 Some("https://example.com/setup".to_string())
1313 );
1314 assert!(url_elicit.requested_schema.is_none());
1315
1316 let accepted_result =
1318 ElicitResult::accepted(HashMap::from([("name".to_string(), json!("Alice"))]));
1319 assert_eq!(accepted_result.action, ElicitationAction::Accept);
1320 assert!(accepted_result.content.is_some());
1321
1322 let completion = ElicitationCompleteParams::new(ElicitResult::declined());
1323 assert_eq!(completion.result.action, ElicitationAction::Decline);
1324
1325 let task_send = TaskSendParams::new("task-123", json!({"kind":"review"}));
1327 assert_eq!(task_send.task_id, "task-123");
1328
1329 let task_cancel = TaskCancelParams::new("task-123");
1330 assert_eq!(task_cancel.task_id, "task-123");
1331
1332 let task_status =
1333 TaskStatusUpdateParams::new("task-123", "running").with_detail(json!({"progress": 42}));
1334 assert_eq!(task_status.status, "running");
1335 assert!(task_status.detail.is_some());
1336 }
1337
1338 #[test]
1339 fn test_new_2025_06_18_message_types() {
1340 let templates_params = ListResourceTemplatesParams {
1342 cursor: Some("cursor123".to_string()),
1343 meta: None,
1344 };
1345 let json = serde_json::to_value(&templates_params).unwrap();
1346 assert_eq!(json["cursor"], "cursor123");
1347
1348 let roots_params = ListRootsParams { meta: None };
1350 let json = serde_json::to_value(&roots_params).unwrap();
1351 assert!(json.is_object());
1352
1353 let mut properties = HashMap::new();
1355 properties.insert(
1356 "name".to_string(),
1357 PrimitiveSchemaDefinition::String {
1358 title: Some("Your Name".to_string()),
1359 description: Some("Enter your full name".to_string()),
1360 min_length: None,
1361 max_length: None,
1362 format: None,
1363 enum_values: None,
1364 enum_names: None,
1365 },
1366 );
1367
1368 let elicit_params = ElicitParams {
1369 message: "Please fill out the form".to_string(),
1370 mode: Some(ElicitationMode::Form),
1371 url: None,
1372 requested_schema: Some(ElicitationSchema {
1373 schema_type: "object".to_string(),
1374 properties,
1375 required: Some(vec!["name".to_string()]),
1376 }),
1377 meta: None,
1378 };
1379 let json = serde_json::to_value(&elicit_params).unwrap();
1380 assert_eq!(json["message"], "Please fill out the form");
1381 assert_eq!(json["requestedSchema"]["type"], "object");
1382 }
1383
1384 #[test]
1385 fn test_notification_params_serialization() {
1386 let resource_updated = ResourceUpdatedParams {
1388 uri: "file:///updated.txt".to_string(),
1389 };
1390 let json = serde_json::to_value(&resource_updated).unwrap();
1391 assert_eq!(json["uri"], "file:///updated.txt");
1392
1393 let cancelled = CancelledParams {
1395 request_id: json!("req-123"),
1396 reason: Some("User cancelled".to_string()),
1397 };
1398 let json = serde_json::to_value(&cancelled).unwrap();
1399 assert_eq!(json["requestId"], "req-123");
1400 assert_eq!(json["reason"], "User cancelled");
1401
1402 let initialized = InitializedParams { meta: None };
1404 let json = serde_json::to_value(&initialized).unwrap();
1405 assert!(json.is_object());
1406
1407 let logging_msg = LoggingMessageParams {
1409 level: LoggingLevel::Info,
1410 logger: Some("test.logger".to_string()),
1411 data: json!({"message": "Test log message"}),
1412 };
1413 let json = serde_json::to_value(&logging_msg).unwrap();
1414 assert_eq!(json["level"], "info");
1415 assert_eq!(json["logger"], "test.logger");
1416 assert_eq!(json["data"]["message"], "Test log message");
1417
1418 let tool_list_changed = ToolListChangedParams { meta: None };
1420 let json = serde_json::to_value(&tool_list_changed).unwrap();
1421 assert!(json.is_object());
1422
1423 let resource_list_changed = ResourceListChangedParams { meta: None };
1424 let json = serde_json::to_value(&resource_list_changed).unwrap();
1425 assert!(json.is_object());
1426
1427 let prompt_list_changed = PromptListChangedParams { meta: None };
1428 let json = serde_json::to_value(&prompt_list_changed).unwrap();
1429 assert!(json.is_object());
1430 }
1431
1432 #[test]
1433 fn test_result_types_serialization() {
1434 let resources_result = ListResourcesResult {
1436 resources: vec![Resource {
1437 uri: "file:///test.txt".to_string(),
1438 name: "test.txt".to_string(),
1439 description: Some("Test file".to_string()),
1440 mime_type: Some("text/plain".to_string()),
1441 annotations: None,
1442 size: None,
1443 icons: None,
1444 title: None,
1445 meta: None,
1446 }],
1447 next_cursor: Some("next-page".to_string()),
1448 meta: None,
1449 };
1450 let json = serde_json::to_value(&resources_result).unwrap();
1451 assert!(json["resources"].is_array());
1452 assert_eq!(json["resources"][0]["uri"], "file:///test.txt");
1453 assert_eq!(json["nextCursor"], "next-page");
1454
1455 let read_result = ReadResourceResult {
1457 contents: vec![ResourceContents::Text {
1458 uri: "file:///test.txt".to_string(),
1459 mime_type: Some("text/plain".to_string()),
1460 text: "file content".to_string(),
1461 meta: None,
1462 }],
1463 meta: None,
1464 };
1465 let json = serde_json::to_value(&read_result).unwrap();
1466 assert!(json["contents"].is_array());
1467
1468 let complete_result = CompleteResult {
1470 completion: CompletionData {
1471 values: vec!["option1".to_string(), "option2".to_string()],
1472 total: Some(2),
1473 has_more: Some(false),
1474 },
1475 meta: None,
1476 };
1477 let json = serde_json::to_value(&complete_result).unwrap();
1478 assert_eq!(json["completion"]["values"][0], "option1");
1479 assert_eq!(json["completion"]["total"], 2);
1480 assert_eq!(json["completion"]["hasMore"], false);
1481
1482 let roots_result = ListRootsResult {
1484 roots: vec![Root::new("file:///root".to_string()).with_name("Root".to_string())],
1485 meta: None,
1486 };
1487 let json = serde_json::to_value(&roots_result).unwrap();
1488 assert!(json["roots"].is_array());
1489 assert_eq!(json["roots"][0]["uri"], "file:///root");
1490 assert_eq!(json["roots"][0]["name"], "Root");
1491
1492 let ping_result = PingResult { meta: None };
1494 let json = serde_json::to_value(&ping_result).unwrap();
1495 assert!(json.is_object());
1496
1497 let logging_result = SetLoggingLevelResult { meta: None };
1498 let json = serde_json::to_value(&logging_result).unwrap();
1499 assert!(json.is_object());
1500
1501 let subscribe_result = SubscribeResourceResult { meta: None };
1502 let json = serde_json::to_value(&subscribe_result).unwrap();
1503 assert!(json.is_object());
1504
1505 let unsubscribe_result = UnsubscribeResourceResult { meta: None };
1506 let json = serde_json::to_value(&unsubscribe_result).unwrap();
1507 assert!(json.is_object());
1508 }
1509
1510 #[test]
1511 fn test_edge_cases_and_empty_values() {
1512 let empty_list_tools = ListToolsParams::default();
1514 let json = serde_json::to_value(&empty_list_tools).unwrap();
1515 assert!(json.is_object());
1516 assert!(json.get("cursor").is_none());
1517
1518 let tool_no_args = CallToolParams::new("simple_tool".to_string());
1520 let json = serde_json::to_value(&tool_no_args).unwrap();
1521 assert_eq!(json["name"], "simple_tool");
1522 assert!(json.get("arguments").is_none());
1523
1524 let empty_args = HashMap::new();
1526 let tool_empty_args = CallToolParams::new_with_arguments("tool".to_string(), empty_args);
1527 let json = serde_json::to_value(&tool_empty_args).unwrap();
1528 assert_eq!(json["name"], "tool");
1529 assert!(json["arguments"].is_object());
1530 assert_eq!(json["arguments"].as_object().unwrap().len(), 0);
1531
1532 let minimal_progress = ProgressParams {
1534 progress_token: json!("token"),
1535 progress: 50.0,
1536 total: None,
1537 message: None,
1538 };
1539 let json = serde_json::to_value(&minimal_progress).unwrap();
1540 assert_eq!(json["progress"], 50.0);
1541 assert!(json.get("total").is_none());
1542 assert!(json.get("message").is_none());
1543 }
1544}