mcp_protocol_sdk/protocol/
messages.rs

1//! MCP Protocol Messages
2//!
3//! This 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 completion request
139#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
140pub struct CompleteParams {
141    /// Reference to the item being completed
142    #[serde(rename = "ref")]
143    pub reference: CompletionReference,
144    /// Argument being completed
145    pub argument: CompletionArgument,
146    /// Request metadata
147    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
148    pub meta: Option<HashMap<String, serde_json::Value>>,
149}
150
151/// Reference for completion
152#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
153#[serde(tag = "type")]
154pub enum CompletionReference {
155    #[serde(rename = "ref/prompt")]
156    Prompt { name: String },
157    #[serde(rename = "ref/resource")]
158    Resource { uri: String },
159    #[serde(rename = "ref/tool")]
160    Tool { name: String },
161}
162
163/// Argument for completion
164#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
165pub struct CompletionArgument {
166    /// Name of the argument
167    pub name: String,
168    /// Current value for completion
169    pub value: String,
170}
171
172/// Parameters for sampling/createMessage request
173#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
174pub struct CreateMessageParams {
175    /// Messages in the conversation
176    pub messages: Vec<SamplingMessage>,
177    /// Maximum tokens to generate
178    #[serde(rename = "maxTokens")]
179    pub max_tokens: u32,
180    /// Optional system prompt
181    #[serde(rename = "systemPrompt", skip_serializing_if = "Option::is_none")]
182    pub system_prompt: Option<String>,
183    /// Include context from servers
184    #[serde(rename = "includeContext", skip_serializing_if = "Option::is_none")]
185    pub include_context: Option<String>,
186    /// Temperature for sampling
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub temperature: Option<f32>,
189    /// Stop sequences
190    #[serde(rename = "stopSequences", skip_serializing_if = "Option::is_none")]
191    pub stop_sequences: Option<Vec<String>>,
192    /// Model preferences
193    #[serde(rename = "modelPreferences", skip_serializing_if = "Option::is_none")]
194    pub model_preferences: Option<ModelPreferences>,
195    /// Provider-specific metadata
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub metadata: Option<HashMap<String, serde_json::Value>>,
198    /// Request metadata
199    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
200    pub meta: Option<HashMap<String, serde_json::Value>>,
201}
202
203/// Parameters for logging level set request
204#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
205pub struct SetLoggingLevelParams {
206    /// Logging level to set
207    pub level: LoggingLevel,
208    /// Request metadata
209    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
210    pub meta: Option<HashMap<String, serde_json::Value>>,
211}
212
213// ============================================================================
214// Response Result Types
215// ============================================================================
216
217/// Result for initialize request
218#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
219pub struct InitializeResult {
220    /// Protocol version server supports
221    #[serde(rename = "protocolVersion")]
222    pub protocol_version: String,
223    /// Server capabilities
224    pub capabilities: ServerCapabilities,
225    /// Server implementation info
226    #[serde(rename = "serverInfo")]
227    pub server_info: Implementation,
228    /// Optional instructions for the client
229    #[serde(skip_serializing_if = "Option::is_none")]
230    pub instructions: Option<String>,
231    /// Response metadata
232    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
233    pub meta: Option<HashMap<String, serde_json::Value>>,
234}
235
236/// Result for list tools request
237#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
238pub struct ListToolsResult {
239    /// Available tools
240    pub tools: Vec<Tool>,
241    /// Next cursor for pagination
242    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
243    pub next_cursor: Option<String>,
244    /// Response metadata
245    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
246    pub meta: Option<HashMap<String, serde_json::Value>>,
247}
248
249/// Result for list resources request
250#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
251pub struct ListResourcesResult {
252    /// Available resources
253    pub resources: Vec<Resource>,
254    /// Next cursor for pagination
255    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
256    pub next_cursor: Option<String>,
257    /// Response metadata
258    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
259    pub meta: Option<HashMap<String, serde_json::Value>>,
260}
261
262/// Result for list resource templates request
263#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
264pub struct ListResourceTemplatesResult {
265    /// Available resource templates
266    #[serde(rename = "resourceTemplates")]
267    pub resource_templates: Vec<ResourceTemplate>,
268    /// Next cursor for pagination
269    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
270    pub next_cursor: Option<String>,
271    /// Response metadata
272    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
273    pub meta: Option<HashMap<String, serde_json::Value>>,
274}
275
276/// Result for read resource request
277#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
278pub struct ReadResourceResult {
279    /// Resource contents
280    pub contents: Vec<ResourceContents>,
281    /// Response metadata
282    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
283    pub meta: Option<HashMap<String, serde_json::Value>>,
284}
285
286/// Result for list prompts request
287#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
288pub struct ListPromptsResult {
289    /// Available prompts
290    pub prompts: Vec<Prompt>,
291    /// Next cursor for pagination
292    #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
293    pub next_cursor: Option<String>,
294    /// Response metadata
295    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
296    pub meta: Option<HashMap<String, serde_json::Value>>,
297}
298
299/// Result for completion request
300#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
301pub struct CompleteResult {
302    /// Completion information
303    pub completion: CompletionData,
304    /// Response metadata
305    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
306    pub meta: Option<HashMap<String, serde_json::Value>>,
307}
308
309/// Completion data
310#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
311pub struct CompletionData {
312    /// Completion values
313    pub values: Vec<String>,
314    /// Total number of completions available
315    #[serde(skip_serializing_if = "Option::is_none")]
316    pub total: Option<u32>,
317    /// Whether there are more completions available
318    #[serde(rename = "hasMore", skip_serializing_if = "Option::is_none")]
319    pub has_more: Option<bool>,
320}
321
322/// Result for list roots request
323#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
324pub struct ListRootsResult {
325    /// Available roots
326    pub roots: Vec<Root>,
327    /// Response metadata
328    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
329    pub meta: Option<HashMap<String, serde_json::Value>>,
330}
331
332/// Result for ping request
333#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
334pub struct PingResult {
335    /// Response metadata
336    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
337    pub meta: Option<HashMap<String, serde_json::Value>>,
338}
339
340/// Result for set logging level request
341#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
342pub struct SetLoggingLevelResult {
343    /// Response metadata
344    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
345    pub meta: Option<HashMap<String, serde_json::Value>>,
346}
347
348/// Result for subscribe resource request
349#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
350pub struct SubscribeResourceResult {
351    /// Response metadata
352    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
353    pub meta: Option<HashMap<String, serde_json::Value>>,
354}
355
356/// Result for unsubscribe resource request
357#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
358pub struct UnsubscribeResourceResult {
359    /// Response metadata
360    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
361    pub meta: Option<HashMap<String, serde_json::Value>>,
362}
363
364/// Root definition
365#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
366pub struct Root {
367    /// URI of the root
368    pub uri: String,
369    /// Optional name for the root
370    #[serde(skip_serializing_if = "Option::is_none")]
371    pub name: Option<String>,
372}
373
374// ============================================================================
375// Notification Parameter Types
376// ============================================================================
377
378/// Parameters for progress notification
379#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
380pub struct ProgressParams {
381    /// Progress token from original request
382    #[serde(rename = "progressToken")]
383    pub progress_token: ProgressToken,
384    /// Current progress value
385    pub progress: f32,
386    /// Total progress expected
387    #[serde(skip_serializing_if = "Option::is_none")]
388    pub total: Option<f32>,
389    /// Optional progress message
390    #[serde(skip_serializing_if = "Option::is_none")]
391    pub message: Option<String>,
392}
393
394/// Parameters for resource updated notification
395#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
396pub struct ResourceUpdatedParams {
397    /// URI of the updated resource
398    pub uri: String,
399}
400
401/// Parameters for cancelled notification
402#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
403pub struct CancelledParams {
404    /// ID of the request being cancelled
405    #[serde(rename = "requestId")]
406    pub request_id: RequestId,
407    /// Optional reason for cancellation
408    #[serde(skip_serializing_if = "Option::is_none")]
409    pub reason: Option<String>,
410}
411
412/// Parameters for initialized notification
413#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
414pub struct InitializedParams {
415    /// Notification metadata
416    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
417    pub meta: Option<HashMap<String, serde_json::Value>>,
418}
419
420/// Parameters for logging message notification
421#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
422pub struct LoggingMessageParams {
423    /// Logging level
424    pub level: LoggingLevel,
425    /// Logger name
426    #[serde(skip_serializing_if = "Option::is_none")]
427    pub logger: Option<String>,
428    /// Log data
429    pub data: serde_json::Value,
430}
431
432/// Parameters for tool list changed notification
433#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
434pub struct ToolListChangedParams {
435    /// Response metadata
436    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
437    pub meta: Option<HashMap<String, serde_json::Value>>,
438}
439
440/// Parameters for resource list changed notification
441#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
442pub struct ResourceListChangedParams {
443    /// Response metadata
444    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
445    pub meta: Option<HashMap<String, serde_json::Value>>,
446}
447
448/// Parameters for prompt list changed notification
449#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
450pub struct PromptListChangedParams {
451    /// Response metadata
452    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
453    pub meta: Option<HashMap<String, serde_json::Value>>,
454}
455
456/// Parameters for progress notification (alias for better naming)
457#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
458pub struct ProgressNotificationParams {
459    /// Progress token from original request
460    #[serde(rename = "progressToken")]
461    pub progress_token: ProgressToken,
462    /// Current progress value
463    pub progress: f32,
464    /// Total progress expected
465    #[serde(skip_serializing_if = "Option::is_none")]
466    pub total: Option<f32>,
467    /// Optional progress message
468    #[serde(skip_serializing_if = "Option::is_none")]
469    pub message: Option<String>,
470}
471
472/// Parameters for logging message notification (alias for better naming)
473#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
474pub struct LoggingMessageNotificationParams {
475    /// Logging level
476    pub level: LoggingLevel,
477    /// Logger name
478    #[serde(skip_serializing_if = "Option::is_none")]
479    pub logger: Option<String>,
480    /// Log data
481    pub data: serde_json::Value,
482}
483
484// ============================================================================
485// Helper Constructors
486// ============================================================================
487
488impl CallToolParams {
489    pub fn new(name: String) -> Self {
490        Self {
491            name,
492            arguments: None,
493            meta: None,
494        }
495    }
496
497    pub fn new_with_arguments(name: String, arguments: HashMap<String, serde_json::Value>) -> Self {
498        Self {
499            name,
500            arguments: Some(arguments),
501            meta: None,
502        }
503    }
504
505    pub fn with_arguments(mut self, arguments: HashMap<String, serde_json::Value>) -> Self {
506        self.arguments = Some(arguments);
507        self
508    }
509}
510
511impl ReadResourceParams {
512    pub fn new(uri: String) -> Self {
513        Self { uri, meta: None }
514    }
515}
516
517impl GetPromptParams {
518    pub fn new(name: String) -> Self {
519        Self {
520            name,
521            arguments: None,
522            meta: None,
523        }
524    }
525
526    pub fn new_with_arguments(name: String, arguments: HashMap<String, String>) -> Self {
527        Self {
528            name,
529            arguments: Some(arguments),
530            meta: None,
531        }
532    }
533
534    pub fn with_arguments(mut self, arguments: HashMap<String, String>) -> Self {
535        self.arguments = Some(arguments);
536        self
537    }
538}
539
540impl InitializeParams {
541    pub fn new(
542        protocol_version: String,
543        capabilities: ClientCapabilities,
544        client_info: Implementation,
545    ) -> Self {
546        Self {
547            protocol_version,
548            capabilities,
549            client_info,
550            meta: None,
551        }
552    }
553}
554
555impl InitializeResult {
556    pub fn new(
557        protocol_version: String,
558        capabilities: ServerCapabilities,
559        server_info: Implementation,
560    ) -> Self {
561        Self {
562            protocol_version,
563            capabilities,
564            server_info,
565            instructions: None,
566            meta: None,
567        }
568    }
569}
570
571impl Root {
572    pub fn new(uri: String) -> Self {
573        Self { uri, name: None }
574    }
575
576    pub fn with_name(mut self, name: String) -> Self {
577        self.name = Some(name);
578        self
579    }
580}
581
582// ============================================================================
583// Default Implementations
584// ============================================================================