Skip to main content

prism_mcp_rs/protocol/
messages.rs

1//! MCP Protocol Messages
2//!
3//! Module defines all protocol message types used in MCP communication,
4//! aligned with the 2025-03-26 specification.
5
6use crate::protocol::types::*;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10// ============================================================================
11// Request Parameter Types
12// ============================================================================
13
14/// Parameters for initialize request
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16pub struct InitializeParams {
17    /// Protocol version client supports
18    #[serde(rename = "protocolVersion")]
19    pub protocol_version: String,
20    /// Client capabilities
21    pub capabilities: ClientCapabilities,
22    /// Client implementation info
23    #[serde(rename = "clientInfo")]
24    pub client_info: Implementation,
25    /// Request metadata
26    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
27    pub meta: Option<HashMap<String, serde_json::Value>>,
28}
29
30/// Parameters for tool call request
31#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
32pub struct CallToolParams {
33    /// Name of the tool to call
34    pub name: String,
35    /// Arguments to pass to the tool
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub arguments: Option<HashMap<String, serde_json::Value>>,
38    /// Request metadata
39    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
40    pub meta: Option<HashMap<String, serde_json::Value>>,
41}
42
43/// Parameters for resource read request
44#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
45pub struct ReadResourceParams {
46    /// URI of the resource to read
47    pub uri: String,
48    /// Request metadata
49    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
50    pub meta: Option<HashMap<String, serde_json::Value>>,
51}
52
53/// Parameters for resource subscription request
54#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
55pub struct SubscribeResourceParams {
56    /// URI of the resource to subscribe to
57    pub uri: String,
58    /// Request metadata
59    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
60    pub meta: Option<HashMap<String, serde_json::Value>>,
61}
62
63/// Parameters for resource unsubscription request
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
65pub struct UnsubscribeResourceParams {
66    /// URI of the resource to unsubscribe from
67    pub uri: String,
68    /// Request metadata
69    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
70    pub meta: Option<HashMap<String, serde_json::Value>>,
71}
72
73/// Parameters for prompt get request
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
75pub struct GetPromptParams {
76    /// Name of the prompt
77    pub name: String,
78    /// Arguments for prompt templating
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub arguments: Option<HashMap<String, String>>,
81    /// Request metadata
82    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
83    pub meta: Option<HashMap<String, serde_json::Value>>,
84}
85
86/// Parameters for list requests (with pagination)
87#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
88pub struct ListParams {
89    /// Pagination cursor
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub cursor: Option<String>,
92    /// Request metadata
93    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
94    pub meta: Option<HashMap<String, serde_json::Value>>,
95}
96
97/// Parameters for list tools request
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
99pub struct ListToolsParams {
100    /// Pagination cursor
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub cursor: Option<String>,
103    /// Request metadata
104    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
105    pub meta: Option<HashMap<String, serde_json::Value>>,
106}
107
108/// Parameters for list resources request
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
110pub struct ListResourcesParams {
111    /// Pagination cursor
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub cursor: Option<String>,
114    /// Request metadata
115    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
116    pub meta: Option<HashMap<String, serde_json::Value>>,
117}
118
119/// Parameters for list prompts request
120#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
121pub struct ListPromptsParams {
122    /// Pagination cursor
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub cursor: Option<String>,
125    /// Request metadata
126    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
127    pub meta: Option<HashMap<String, serde_json::Value>>,
128}
129
130/// Parameters for ping request
131#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
132pub struct PingParams {
133    /// Request metadata
134    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
135    pub meta: Option<HashMap<String, serde_json::Value>>,
136}
137
138/// Parameters for list resource templates request (New in 2025-11-25)
139#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
140pub struct ListResourceTemplatesParams {
141    /// Pagination cursor
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub cursor: Option<String>,
144    /// Request metadata
145    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
146    pub meta: Option<HashMap<String, serde_json::Value>>,
147}
148
149/// Parameters for list roots request (New in 2025-11-25)
150#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
151pub struct ListRootsParams {
152    /// Request metadata
153    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
154    pub meta: Option<HashMap<String, serde_json::Value>>,
155}
156
157/// Parameters for completion request
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
159pub struct CompleteParams {
160    /// Reference to the item being completed
161    #[serde(rename = "ref")]
162    pub reference: CompletionReference,
163    /// Argument being completed
164    pub argument: CompletionArgument,
165    /// Request metadata
166    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
167    pub meta: Option<HashMap<String, serde_json::Value>>,
168}
169
170/// Reference for completion
171#[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/// Argument for completion
183#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
184pub struct CompletionArgument {
185    /// Name of the argument
186    pub name: String,
187    /// Current value for completion
188    pub value: String,
189}
190
191/// Parameters for sampling/createMessage request
192#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
193pub struct CreateMessageParams {
194    /// Messages in the conversation
195    pub messages: Vec<SamplingMessage>,
196    /// Maximum tokens to generate
197    #[serde(rename = "maxTokens")]
198    pub max_tokens: u32,
199    /// Optional system prompt
200    #[serde(rename = "systemPrompt", skip_serializing_if = "Option::is_none")]
201    pub system_prompt: Option<String>,
202    /// Include context from servers
203    #[serde(rename = "includeContext", skip_serializing_if = "Option::is_none")]
204    pub include_context: Option<String>,
205    /// Temperature for sampling
206    #[serde(skip_serializing_if = "Option::is_none")]
207    pub temperature: Option<f32>,
208    /// Stop sequences
209    #[serde(rename = "stopSequences", skip_serializing_if = "Option::is_none")]
210    pub stop_sequences: Option<Vec<String>>,
211    /// Model preferences
212    #[serde(rename = "modelPreferences", skip_serializing_if = "Option::is_none")]
213    pub model_preferences: Option<ModelPreferences>,
214    /// Optional tools that the model may call while sampling.
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub tools: Option<Vec<Tool>>,
217    /// Optional strategy for choosing tools during sampling.
218    #[serde(rename = "toolChoice", skip_serializing_if = "Option::is_none")]
219    pub tool_choice: Option<SamplingToolChoice>,
220    /// Provider-specific metadata
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub metadata: Option<HashMap<String, serde_json::Value>>,
223    /// Request metadata
224    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
225    pub meta: Option<HashMap<String, serde_json::Value>>,
226}
227
228/// Parameters for logging level set request
229#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
230pub struct SetLoggingLevelParams {
231    /// Logging level to set
232    pub level: LoggingLevel,
233    /// Request metadata
234    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
235    pub meta: Option<HashMap<String, serde_json::Value>>,
236}
237
238/// Parameters for elicitation request (2025-11-25 NEW)
239#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
240pub struct ElicitParams {
241    /// Message to present to the user
242    pub message: String,
243    /// Interaction mode used by the client UI.
244    #[serde(skip_serializing_if = "Option::is_none")]
245    pub mode: Option<ElicitationMode>,
246    /// URL to open when mode is `url`.
247    #[serde(skip_serializing_if = "Option::is_none")]
248    pub url: Option<String>,
249    /// Schema describing the requested form fields
250    #[serde(rename = "requestedSchema", skip_serializing_if = "Option::is_none")]
251    pub requested_schema: Option<ElicitationSchema>,
252    /// Request metadata
253    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
254    pub meta: Option<HashMap<String, serde_json::Value>>,
255}
256
257/// Elicitation interaction mode.
258#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
259#[serde(rename_all = "lowercase")]
260pub enum ElicitationMode {
261    Form,
262    Url,
263}
264
265// ============================================================================
266// Response Result Types
267// ============================================================================
268
269/// Result for initialize request
270#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
271pub struct InitializeResult {
272    /// Protocol version server supports
273    #[serde(rename = "protocolVersion")]
274    pub protocol_version: String,
275    /// Server capabilities
276    pub capabilities: ServerCapabilities,
277    /// Server implementation info
278    #[serde(rename = "serverInfo")]
279    pub server_info: Implementation,
280    /// Optional instructions for the client
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub instructions: Option<String>,
283    /// Response metadata
284    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
285    pub meta: Option<HashMap<String, serde_json::Value>>,
286}
287
288/// Result for list tools request
289#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
290pub struct ListToolsResult {
291    /// Available tools
292    pub tools: Vec<Tool>,
293    /// Next cursor for pagination
294    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
295    pub next_cursor: Option<String>,
296    /// Response metadata
297    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
298    pub meta: Option<HashMap<String, serde_json::Value>>,
299}
300
301/// Result for list resources request
302#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
303pub struct ListResourcesResult {
304    /// Available resources
305    pub resources: Vec<Resource>,
306    /// Next cursor for pagination
307    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
308    pub next_cursor: Option<String>,
309    /// Response metadata
310    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
311    pub meta: Option<HashMap<String, serde_json::Value>>,
312}
313
314/// Result for list resource templates request
315#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
316pub struct ListResourceTemplatesResult {
317    /// Available resource templates
318    #[serde(rename = "resourceTemplates")]
319    pub resource_templates: Vec<ResourceTemplate>,
320    /// Next cursor for pagination
321    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
322    pub next_cursor: Option<String>,
323    /// Response metadata
324    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
325    pub meta: Option<HashMap<String, serde_json::Value>>,
326}
327
328/// Result for read resource request
329#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
330pub struct ReadResourceResult {
331    /// Resource contents
332    pub contents: Vec<ResourceContents>,
333    /// Response metadata
334    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
335    pub meta: Option<HashMap<String, serde_json::Value>>,
336}
337
338/// Result for list prompts request
339#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
340pub struct ListPromptsResult {
341    /// Available prompts
342    pub prompts: Vec<Prompt>,
343    /// Next cursor for pagination
344    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
345    pub next_cursor: Option<String>,
346    /// Response metadata
347    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
348    pub meta: Option<HashMap<String, serde_json::Value>>,
349}
350
351/// Result for completion request
352#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
353pub struct CompleteResult {
354    /// Completion information
355    pub completion: CompletionData,
356    /// Response metadata
357    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
358    pub meta: Option<HashMap<String, serde_json::Value>>,
359}
360
361/// Completion data
362#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
363pub struct CompletionData {
364    /// Completion values
365    pub values: Vec<String>,
366    /// Total number of completions available
367    #[serde(skip_serializing_if = "Option::is_none")]
368    pub total: Option<u32>,
369    /// Whether there are more completions available
370    #[serde(rename = "hasMore", skip_serializing_if = "Option::is_none")]
371    pub has_more: Option<bool>,
372}
373
374/// Result for list roots request
375#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
376pub struct ListRootsResult {
377    /// Available roots
378    pub roots: Vec<Root>,
379    /// Response metadata
380    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
381    pub meta: Option<HashMap<String, serde_json::Value>>,
382}
383
384/// Result for ping request
385#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
386pub struct PingResult {
387    /// Response metadata
388    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
389    pub meta: Option<HashMap<String, serde_json::Value>>,
390}
391
392/// Result for set logging level request
393#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
394pub struct SetLoggingLevelResult {
395    /// Response metadata
396    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
397    pub meta: Option<HashMap<String, serde_json::Value>>,
398}
399
400/// Result for elicitation request (2025-11-25 NEW)
401#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
402pub struct ElicitResult {
403    /// User action in response to elicitation
404    pub action: ElicitationAction,
405    /// Submitted form data (only present when action is "accept")
406    #[serde(skip_serializing_if = "Option::is_none")]
407    pub content: Option<HashMap<String, serde_json::Value>>,
408    /// Response metadata
409    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
410    pub meta: Option<HashMap<String, serde_json::Value>>,
411}
412
413/// Result for subscribe resource request
414#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
415pub struct SubscribeResourceResult {
416    /// Response metadata
417    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
418    pub meta: Option<HashMap<String, serde_json::Value>>,
419}
420
421/// Result for unsubscribe resource request
422#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
423pub struct UnsubscribeResourceResult {
424    /// Response metadata
425    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
426    pub meta: Option<HashMap<String, serde_json::Value>>,
427}
428
429/// Root definition
430#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
431pub struct Root {
432    /// URI of the root
433    pub uri: String,
434    /// Optional name for the root
435    #[serde(skip_serializing_if = "Option::is_none")]
436    pub name: Option<String>,
437}
438
439// ============================================================================
440// Notification Parameter Types
441// ============================================================================
442
443/// Parameters for progress notification
444#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
445pub struct ProgressParams {
446    /// Progress token from original request
447    #[serde(rename = "progressToken")]
448    pub progress_token: ProgressToken,
449    /// Current progress value
450    pub progress: f32,
451    /// Total progress expected
452    #[serde(skip_serializing_if = "Option::is_none")]
453    pub total: Option<f32>,
454    /// Optional progress message
455    #[serde(skip_serializing_if = "Option::is_none")]
456    pub message: Option<String>,
457}
458
459/// Parameters for resource updated notification
460#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
461pub struct ResourceUpdatedParams {
462    /// URI of the updated resource
463    pub uri: String,
464}
465
466/// Parameters for cancelled notification
467#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
468pub struct CancelledParams {
469    /// ID of the request being cancelled
470    #[serde(rename = "requestId")]
471    pub request_id: RequestId,
472    /// Optional reason for cancellation
473    #[serde(skip_serializing_if = "Option::is_none")]
474    pub reason: Option<String>,
475}
476
477/// Parameters for initialized notification
478#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
479pub struct InitializedParams {
480    /// Notification metadata
481    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
482    pub meta: Option<HashMap<String, serde_json::Value>>,
483}
484
485/// Parameters for logging message notification
486#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
487pub struct LoggingMessageParams {
488    /// Logging level
489    pub level: LoggingLevel,
490    /// Logger name
491    #[serde(skip_serializing_if = "Option::is_none")]
492    pub logger: Option<String>,
493    /// Log data
494    pub data: serde_json::Value,
495}
496
497/// Parameters for tool list changed notification
498#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
499pub struct ToolListChangedParams {
500    /// Response metadata
501    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
502    pub meta: Option<HashMap<String, serde_json::Value>>,
503}
504
505/// Parameters for resource list changed notification
506#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
507pub struct ResourceListChangedParams {
508    /// Response metadata
509    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
510    pub meta: Option<HashMap<String, serde_json::Value>>,
511}
512
513/// Parameters for prompt list changed notification
514#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
515pub struct PromptListChangedParams {
516    /// Response metadata
517    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
518    pub meta: Option<HashMap<String, serde_json::Value>>,
519}
520
521/// Parameters for elicitation completion notification.
522#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
523pub struct ElicitationCompleteParams {
524    /// Final elicitation result payload.
525    pub result: ElicitResult,
526}
527
528/// Parameters for tasks/send.
529#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
530pub struct TaskSendParams {
531    /// Task identifier.
532    #[serde(rename = "taskId")]
533    pub task_id: String,
534    /// Task payload.
535    pub task: serde_json::Value,
536    /// Request metadata.
537    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
538    pub meta: Option<HashMap<String, serde_json::Value>>,
539}
540
541/// Parameters for tasks/cancel.
542#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
543pub struct TaskCancelParams {
544    /// Task identifier.
545    #[serde(rename = "taskId")]
546    pub task_id: String,
547    /// Request metadata.
548    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
549    pub meta: Option<HashMap<String, serde_json::Value>>,
550}
551
552/// Parameters for notifications/tasks/status/update.
553#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
554pub struct TaskStatusUpdateParams {
555    /// Task identifier.
556    #[serde(rename = "taskId")]
557    pub task_id: String,
558    /// Task status value.
559    pub status: String,
560    /// Optional status detail payload.
561    #[serde(skip_serializing_if = "Option::is_none")]
562    pub detail: Option<serde_json::Value>,
563}
564
565/// Parameters for progress notification (alias for better naming)
566#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
567pub struct ProgressNotificationParams {
568    /// Progress token from original request
569    #[serde(rename = "progressToken")]
570    pub progress_token: ProgressToken,
571    /// Current progress value
572    pub progress: f32,
573    /// Total progress expected
574    #[serde(skip_serializing_if = "Option::is_none")]
575    pub total: Option<f32>,
576    /// Optional progress message
577    #[serde(skip_serializing_if = "Option::is_none")]
578    pub message: Option<String>,
579}
580
581/// Parameters for logging message notification (alias for better naming)
582#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
583pub struct LoggingMessageNotificationParams {
584    /// Logging level
585    pub level: LoggingLevel,
586    /// Logger name
587    #[serde(skip_serializing_if = "Option::is_none")]
588    pub logger: Option<String>,
589    /// Log data
590    pub data: serde_json::Value,
591}
592
593// ============================================================================
594// Helper Constructors
595// ============================================================================
596
597impl 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    /// Create minimal sampling/createMessage params.
682    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    /// Set system prompt.
699    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    /// Set context inclusion strategy.
705    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    /// Set sampling temperature.
711    pub fn with_temperature(mut self, temperature: f32) -> Self {
712        self.temperature = Some(temperature);
713        self
714    }
715
716    /// Set stop sequences.
717    pub fn with_stop_sequences(mut self, stop_sequences: Vec<String>) -> Self {
718        self.stop_sequences = Some(stop_sequences);
719        self
720    }
721
722    /// Set model preferences.
723    pub fn with_model_preferences(mut self, model_preferences: ModelPreferences) -> Self {
724        self.model_preferences = Some(model_preferences);
725        self
726    }
727
728    /// Set available tools for sampling.
729    pub fn with_tools(mut self, tools: Vec<Tool>) -> Self {
730        self.tools = Some(tools);
731        self
732    }
733
734    /// Add a single available tool for sampling.
735    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    /// Set tool choice behavior for sampling.
741    pub fn with_tool_choice(mut self, tool_choice: SamplingToolChoice) -> Self {
742        self.tool_choice = Some(tool_choice);
743        self
744    }
745
746    /// Set provider metadata.
747    pub fn with_metadata(mut self, metadata: HashMap<String, serde_json::Value>) -> Self {
748        self.metadata = Some(metadata);
749        self
750    }
751
752    /// Set request metadata.
753    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    /// Create a minimal elicitation request.
761    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    /// Create a form-based elicitation request.
772    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    /// Create a URL-based elicitation request.
783    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    /// Set elicitation mode.
794    pub fn with_mode(mut self, mode: ElicitationMode) -> Self {
795        self.mode = Some(mode);
796        self
797    }
798
799    /// Set URL for URL-mode elicitation.
800    pub fn with_url<S: Into<String>>(mut self, url: S) -> Self {
801        self.url = Some(url.into());
802        self
803    }
804
805    /// Set requested form schema for form-mode elicitation.
806    pub fn with_requested_schema(mut self, requested_schema: ElicitationSchema) -> Self {
807        self.requested_schema = Some(requested_schema);
808        self
809    }
810
811    /// Set request metadata.
812    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    /// Create an accepted elicitation result.
820    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    /// Create a declined elicitation result.
829    pub fn declined() -> Self {
830        Self {
831            action: ElicitationAction::Decline,
832            content: None,
833            meta: None,
834        }
835    }
836
837    /// Create a cancelled elicitation result.
838    pub fn cancelled() -> Self {
839        Self {
840            action: ElicitationAction::Cancel,
841            content: None,
842            meta: None,
843        }
844    }
845
846    /// Set response metadata.
847    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    /// Create a new elicitation completion notification payload.
855    pub fn new(result: ElicitResult) -> Self {
856        Self { result }
857    }
858}
859
860impl TaskSendParams {
861    /// Create a new task send request payload.
862    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    /// Set request metadata.
871    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    /// Create a new task cancel request payload.
879    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    /// Set request metadata.
887    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    /// Create a new task status update notification payload.
895    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    /// Set status detail payload.
904    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// ============================================================================
922// Default Implementations
923// ============================================================================
924
925#[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(&params).unwrap();
948        assert_eq!(json["protocolVersion"], "2025-11-25");
949        assert_eq!(json["clientInfo"]["name"], "test-client");
950
951        // Test round-trip
952        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(&params).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(&params).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(&params).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(&params).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(&params).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(&params).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(&params).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(&params).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        // Test that all message types can be serialized and deserialized
1175        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(&params).unwrap();
1226        assert_eq!(json["_meta"]["custom"], "value");
1227    }
1228
1229    #[test]
1230    fn test_constructor_methods() {
1231        // Test CallToolParams constructors
1232        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        // Test ReadResourceParams constructor
1244        let resource_params = ReadResourceParams::new("file:///test.txt".to_string());
1245        assert_eq!(resource_params.uri, "file:///test.txt");
1246
1247        // Test GetPromptParams constructors
1248        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        // Test Root constructor
1260        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        // Test CreateMessageParams constructors/builders
1268        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        // Test ElicitParams constructors/builders
1285        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        // Test ElicitResult and completion params constructors
1317        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        // Test task message constructors
1326        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        // Test ListResourceTemplatesParams
1341        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        // Test ListRootsParams
1349        let roots_params = ListRootsParams { meta: None };
1350        let json = serde_json::to_value(&roots_params).unwrap();
1351        assert!(json.is_object());
1352
1353        // Test ElicitParams
1354        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        // Test ResourceUpdatedParams
1387        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        // Test CancelledParams
1394        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        // Test InitializedParams
1403        let initialized = InitializedParams { meta: None };
1404        let json = serde_json::to_value(&initialized).unwrap();
1405        assert!(json.is_object());
1406
1407        // Test LoggingMessageParams
1408        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        // Test list changed notification params
1419        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        // Test ListResourcesResult
1435        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        // Test ReadResourceResult
1456        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        // Test CompleteResult
1469        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        // Test ListRootsResult
1483        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        // Test simple result types
1493        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        // Test empty ListToolsParams
1513        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        // Test CallToolParams without arguments
1519        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        // Test with empty arguments map
1525        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        // Test progress with no optional fields
1533        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}