turul_mcp_builders/
protocol_impls.rs

1//! Framework trait implementations for protocol types
2//!
3//! This module provides framework trait implementations for concrete protocol types
4//! (Resource, Prompt, Tool, Root, etc.) from turul_mcp_protocol, enabling them to be used
5//! with framework features like ResourceDefinition, PromptDefinition, ToolDefinition, etc.
6//!
7//! **CRITICAL**: Every protocol type that has corresponding framework traits MUST have
8//! implementations here. Missing implementations break the trait hierarchy and cause
9//! compilation failures in user code.
10
11use turul_mcp_protocol::{Resource, Prompt, Tool, ToolSchema};
12use turul_mcp_protocol::roots::Root;
13use turul_mcp_protocol::sampling::{CreateMessageParams, SamplingMessage, ModelPreferences};
14use turul_mcp_protocol::logging::{LoggingMessageNotification, LoggingLevel};
15use turul_mcp_protocol::completion::{CompleteRequest, CompletionReference, CompleteArgument, CompletionContext};
16use turul_mcp_protocol::elicitation::{ElicitCreateRequest, ElicitationSchema};
17use turul_mcp_protocol::notifications::{
18    ResourceListChangedNotification, ToolListChangedNotification, PromptListChangedNotification,
19    RootsListChangedNotification, ProgressNotification, ResourceUpdatedNotification,
20    CancelledNotification, InitializedNotification, Notification,
21};
22use crate::traits::*;
23
24// ============================================================================
25// Resource trait implementations
26// ============================================================================
27
28impl HasResourceMetadata for Resource {
29    fn name(&self) -> &str {
30        &self.name
31    }
32
33    fn title(&self) -> Option<&str> {
34        self.title.as_deref()
35    }
36}
37
38impl HasResourceDescription for Resource {
39    fn description(&self) -> Option<&str> {
40        self.description.as_deref()
41    }
42}
43
44impl HasResourceUri for Resource {
45    fn uri(&self) -> &str {
46        &self.uri
47    }
48}
49
50impl HasResourceMimeType for Resource {
51    fn mime_type(&self) -> Option<&str> {
52        self.mime_type.as_deref()
53    }
54}
55
56impl HasResourceSize for Resource {
57    fn size(&self) -> Option<u64> {
58        self.size
59    }
60}
61
62impl HasResourceAnnotations for Resource {
63    fn annotations(&self) -> Option<&turul_mcp_protocol::meta::Annotations> {
64        self.annotations.as_ref()
65    }
66}
67
68impl HasResourceMeta for Resource {
69    fn resource_meta(&self) -> Option<&std::collections::HashMap<String, serde_json::Value>> {
70        self.meta.as_ref()
71    }
72}
73
74// ResourceDefinition is automatically implemented via blanket impl
75
76// ============================================================================
77// Prompt trait implementations
78// ============================================================================
79
80impl HasPromptMetadata for Prompt {
81    fn name(&self) -> &str {
82        &self.name
83    }
84
85    fn title(&self) -> Option<&str> {
86        self.title.as_deref()
87    }
88}
89
90impl HasPromptDescription for Prompt {
91    fn description(&self) -> Option<&str> {
92        self.description.as_deref()
93    }
94}
95
96impl HasPromptArguments for Prompt {
97    fn arguments(&self) -> Option<&Vec<turul_mcp_protocol::prompts::PromptArgument>> {
98        self.arguments.as_ref()
99    }
100}
101
102impl HasPromptAnnotations for Prompt {
103    fn annotations(&self) -> Option<&turul_mcp_protocol::prompts::PromptAnnotations> {
104        // Prompt struct doesn't have annotations field in current protocol
105        None
106    }
107}
108
109impl HasPromptMeta for Prompt {
110    fn prompt_meta(&self) -> Option<&std::collections::HashMap<String, serde_json::Value>> {
111        self.meta.as_ref()
112    }
113}
114
115// PromptDefinition is automatically implemented via blanket impl
116
117// ============================================================================
118// Tool trait implementations
119// ============================================================================
120
121impl HasBaseMetadata for Tool {
122    fn name(&self) -> &str {
123        &self.name
124    }
125
126    fn title(&self) -> Option<&str> {
127        self.title.as_deref()
128    }
129}
130
131impl HasDescription for Tool {
132    fn description(&self) -> Option<&str> {
133        self.description.as_deref()
134    }
135}
136
137impl HasInputSchema for Tool {
138    fn input_schema(&self) -> &ToolSchema {
139        &self.input_schema
140    }
141}
142
143impl HasOutputSchema for Tool {
144    fn output_schema(&self) -> Option<&ToolSchema> {
145        self.output_schema.as_ref()
146    }
147}
148
149impl HasAnnotations for Tool {
150    fn annotations(&self) -> Option<&turul_mcp_protocol::tools::ToolAnnotations> {
151        self.annotations.as_ref()
152    }
153}
154
155impl HasToolMeta for Tool {
156    fn tool_meta(&self) -> Option<&std::collections::HashMap<String, serde_json::Value>> {
157        self.meta.as_ref()
158    }
159}
160
161// ToolDefinition is automatically implemented via blanket impl
162
163// ============================================================================
164// Root trait implementations
165// ============================================================================
166
167impl HasRootMetadata for Root {
168    fn name(&self) -> Option<&str> {
169        self.name.as_deref()
170    }
171
172    fn uri(&self) -> &str {
173        &self.uri
174    }
175}
176
177impl HasRootPermissions for Root {
178    // Root struct doesn't have permissions field - framework can add later if needed
179}
180
181impl HasRootFiltering for Root {
182    // Root struct doesn't have filtering field - framework can add later if needed
183}
184
185impl HasRootAnnotations for Root {
186    fn annotations(&self) -> Option<&std::collections::HashMap<String, serde_json::Value>> {
187        self.meta.as_ref()
188    }
189}
190
191// RootDefinition is automatically implemented via blanket impl
192
193// ============================================================================
194// Sampling trait implementations
195// ============================================================================
196
197impl HasSamplingConfig for CreateMessageParams {
198    fn max_tokens(&self) -> u32 {
199        self.max_tokens
200    }
201
202    fn temperature(&self) -> Option<f64> {
203        self.temperature
204    }
205
206    fn stop_sequences(&self) -> Option<&Vec<String>> {
207        self.stop_sequences.as_ref()
208    }
209}
210
211impl HasSamplingContext for CreateMessageParams {
212    fn messages(&self) -> &[SamplingMessage] {
213        &self.messages
214    }
215
216    fn system_prompt(&self) -> Option<&str> {
217        self.system_prompt.as_deref()
218    }
219
220    fn include_context(&self) -> Option<&str> {
221        self.include_context.as_deref()
222    }
223}
224
225impl HasModelPreferences for CreateMessageParams {
226    fn model_preferences(&self) -> Option<&ModelPreferences> {
227        self.model_preferences.as_ref()
228    }
229
230    fn metadata(&self) -> Option<&serde_json::Value> {
231        self.metadata.as_ref()
232    }
233}
234
235// SamplingDefinition is automatically implemented via blanket impl
236
237impl HasSamplingMessageMetadata for SamplingMessage {
238    fn role(&self) -> &turul_mcp_protocol::sampling::Role {
239        &self.role
240    }
241
242    fn content(&self) -> &turul_mcp_protocol::prompts::ContentBlock {
243        &self.content
244    }
245}
246
247// ============================================================================
248// Logging trait implementations
249// ============================================================================
250
251impl HasLoggingMetadata for LoggingMessageNotification {
252    fn method(&self) -> &str {
253        &self.method
254    }
255
256    fn logger_name(&self) -> Option<&str> {
257        self.params.logger.as_deref()
258    }
259}
260
261impl HasLogLevel for LoggingMessageNotification {
262    fn level(&self) -> LoggingLevel {
263        self.params.level
264    }
265}
266
267impl HasLogFormat for LoggingMessageNotification {
268    fn data(&self) -> &serde_json::Value {
269        &self.params.data
270    }
271}
272
273impl HasLogTransport for LoggingMessageNotification {
274    // Use default implementations
275}
276
277// LoggerDefinition is automatically implemented via blanket impl
278
279// ============================================================================
280// Completion trait implementations
281// ============================================================================
282
283impl HasCompletionMetadata for CompleteRequest {
284    fn method(&self) -> &str {
285        &self.method
286    }
287
288    fn reference(&self) -> &CompletionReference {
289        &self.params.reference
290    }
291}
292
293impl HasCompletionContext for CompleteRequest {
294    fn argument(&self) -> &CompleteArgument {
295        &self.params.argument
296    }
297
298    fn context(&self) -> Option<&CompletionContext> {
299        self.params.context.as_ref()
300    }
301}
302
303impl HasCompletionHandling for CompleteRequest {
304    // Use default implementations
305}
306
307// CompletionDefinition is automatically implemented via blanket impl
308
309// ============================================================================
310// Elicitation trait implementations
311// ============================================================================
312
313impl HasElicitationMetadata for ElicitCreateRequest {
314    fn message(&self) -> &str {
315        &self.params.message
316    }
317
318    // title() uses default implementation which returns None
319}
320
321impl HasElicitationSchema for ElicitCreateRequest {
322    fn requested_schema(&self) -> &ElicitationSchema {
323        &self.params.requested_schema
324    }
325}
326
327impl HasElicitationHandling for ElicitCreateRequest {
328    // Use default implementations
329}
330
331// ElicitationDefinition is automatically implemented via blanket impl
332
333// ============================================================================
334// Notification trait implementations
335// ============================================================================
336
337// Base Notification type
338impl HasNotificationMetadata for Notification {
339    fn method(&self) -> &str {
340        &self.method
341    }
342}
343
344impl HasNotificationPayload for Notification {
345    fn payload(&self) -> Option<serde_json::Value> {
346        self.params.as_ref().map(|params| {
347            let mut map = serde_json::Map::new();
348
349            // Add all params.other fields
350            for (key, value) in &params.other {
351                map.insert(key.clone(), value.clone());
352            }
353
354            // Add _meta if present
355            if let Some(meta) = &params.meta
356                && let Ok(meta_value) = serde_json::to_value(meta)
357            {
358                map.insert("_meta".to_string(), meta_value);
359            }
360
361            serde_json::Value::Object(map)
362        })
363    }
364}
365
366impl HasNotificationRules for Notification {}
367
368// ResourceListChangedNotification
369impl HasNotificationMetadata for ResourceListChangedNotification {
370    fn method(&self) -> &str {
371        &self.method
372    }
373}
374
375impl HasNotificationPayload for ResourceListChangedNotification {
376    fn payload(&self) -> Option<serde_json::Value> {
377        // Serialize params if present (includes _meta)
378        self.params.as_ref().and_then(|p| serde_json::to_value(p).ok())
379    }
380}
381
382impl HasNotificationRules for ResourceListChangedNotification {}
383
384// ToolListChangedNotification
385impl HasNotificationMetadata for ToolListChangedNotification {
386    fn method(&self) -> &str {
387        &self.method
388    }
389}
390
391impl HasNotificationPayload for ToolListChangedNotification {
392    fn payload(&self) -> Option<serde_json::Value> {
393        // Serialize params if present (includes _meta)
394        self.params.as_ref().and_then(|p| serde_json::to_value(p).ok())
395    }
396}
397
398impl HasNotificationRules for ToolListChangedNotification {}
399
400// PromptListChangedNotification
401impl HasNotificationMetadata for PromptListChangedNotification {
402    fn method(&self) -> &str {
403        &self.method
404    }
405}
406
407impl HasNotificationPayload for PromptListChangedNotification {
408    fn payload(&self) -> Option<serde_json::Value> {
409        // Serialize params if present (includes _meta)
410        self.params.as_ref().and_then(|p| serde_json::to_value(p).ok())
411    }
412}
413
414impl HasNotificationRules for PromptListChangedNotification {}
415
416// RootsListChangedNotification
417impl HasNotificationMetadata for RootsListChangedNotification {
418    fn method(&self) -> &str {
419        &self.method
420    }
421}
422
423impl HasNotificationPayload for RootsListChangedNotification {
424    fn payload(&self) -> Option<serde_json::Value> {
425        // Serialize params if present (includes _meta)
426        self.params.as_ref().and_then(|p| serde_json::to_value(p).ok())
427    }
428}
429
430impl HasNotificationRules for RootsListChangedNotification {}
431
432// ProgressNotification
433impl HasNotificationMetadata for ProgressNotification {
434    fn method(&self) -> &str {
435        &self.method
436    }
437}
438
439impl HasNotificationPayload for ProgressNotification {
440    fn payload(&self) -> Option<serde_json::Value> {
441        // Serialize the entire params struct (includes progressToken, progress, total, message, _meta)
442        serde_json::to_value(&self.params).ok()
443    }
444}
445
446impl HasNotificationRules for ProgressNotification {
447    fn priority(&self) -> u32 {
448        2 // Progress notifications have higher priority
449    }
450}
451
452// ResourceUpdatedNotification
453impl HasNotificationMetadata for ResourceUpdatedNotification {
454    fn method(&self) -> &str {
455        &self.method
456    }
457}
458
459impl HasNotificationPayload for ResourceUpdatedNotification {
460    fn payload(&self) -> Option<serde_json::Value> {
461        // Serialize params (includes uri, _meta)
462        serde_json::to_value(&self.params).ok()
463    }
464}
465
466impl HasNotificationRules for ResourceUpdatedNotification {}
467
468// CancelledNotification
469impl HasNotificationMetadata for CancelledNotification {
470    fn method(&self) -> &str {
471        &self.method
472    }
473}
474
475impl HasNotificationPayload for CancelledNotification {
476    fn payload(&self) -> Option<serde_json::Value> {
477        // Serialize params (includes requestId, reason, _meta)
478        serde_json::to_value(&self.params).ok()
479    }
480}
481
482impl HasNotificationRules for CancelledNotification {
483    fn priority(&self) -> u32 {
484        3 // Cancellation has highest priority
485    }
486}
487
488// InitializedNotification
489impl HasNotificationMetadata for InitializedNotification {
490    fn method(&self) -> &str {
491        &self.method
492    }
493}
494
495impl HasNotificationPayload for InitializedNotification {
496    fn payload(&self) -> Option<serde_json::Value> {
497        // Serialize params if present (includes _meta)
498        self.params.as_ref().and_then(|p| serde_json::to_value(p).ok())
499    }
500}
501
502impl HasNotificationRules for InitializedNotification {
503    fn priority(&self) -> u32 {
504        3 // Initialization has highest priority
505    }
506}
507
508// NotificationDefinition is automatically implemented via blanket impl for all notification types