types.rs

  1use collections::HashMap;
  2use serde::de::DeserializeOwned;
  3use serde::{Deserialize, Serialize};
  4use url::Url;
  5
  6pub const LATEST_PROTOCOL_VERSION: &str = "2025-03-26";
  7pub const VERSION_2024_11_05: &str = "2024-11-05";
  8
  9pub mod requests {
 10    use super::*;
 11
 12    macro_rules! request {
 13        ($method:expr, $name:ident, $params:ty, $response:ty) => {
 14            pub struct $name;
 15
 16            impl Request for $name {
 17                type Params = $params;
 18                type Response = $response;
 19                const METHOD: &'static str = $method;
 20            }
 21        };
 22    }
 23
 24    request!(
 25        "initialize",
 26        Initialize,
 27        InitializeParams,
 28        InitializeResponse
 29    );
 30    request!("tools/call", CallTool, CallToolParams, CallToolResponse);
 31    request!(
 32        "resources/unsubscribe",
 33        ResourcesUnsubscribe,
 34        ResourcesUnsubscribeParams,
 35        ()
 36    );
 37    request!(
 38        "resources/subscribe",
 39        ResourcesSubscribe,
 40        ResourcesSubscribeParams,
 41        ()
 42    );
 43    request!(
 44        "resources/read",
 45        ResourcesRead,
 46        ResourcesReadParams,
 47        ResourcesReadResponse
 48    );
 49    request!("resources/list", ResourcesList, (), ResourcesListResponse);
 50    request!(
 51        "logging/setLevel",
 52        LoggingSetLevel,
 53        LoggingSetLevelParams,
 54        ()
 55    );
 56    request!(
 57        "prompts/get",
 58        PromptsGet,
 59        PromptsGetParams,
 60        PromptsGetResponse
 61    );
 62    request!("prompts/list", PromptsList, (), PromptsListResponse);
 63    request!(
 64        "completion/complete",
 65        CompletionComplete,
 66        CompletionCompleteParams,
 67        CompletionCompleteResponse
 68    );
 69    request!("ping", Ping, (), ());
 70    request!("tools/list", ListTools, (), ListToolsResponse);
 71    request!(
 72        "resources/templates/list",
 73        ListResourceTemplates,
 74        (),
 75        ListResourceTemplatesResponse
 76    );
 77    request!("roots/list", ListRoots, (), ListRootsResponse);
 78}
 79
 80pub trait Request {
 81    type Params: DeserializeOwned + Serialize + Send + Sync + 'static;
 82    type Response: DeserializeOwned + Serialize + Send + Sync + 'static;
 83    const METHOD: &'static str;
 84}
 85
 86pub mod notifications {
 87    use super::*;
 88
 89    macro_rules! notification {
 90        ($method:expr, $name:ident, $params:ty) => {
 91            pub struct $name;
 92
 93            impl Notification for $name {
 94                type Params = $params;
 95                const METHOD: &'static str = $method;
 96            }
 97        };
 98    }
 99
100    notification!("notifications/initialized", Initialized, ());
101    notification!("notifications/progress", Progress, ProgressParams);
102    notification!("notifications/message", Message, MessageParams);
103    notification!(
104        "notifications/resources/updated",
105        ResourcesUpdated,
106        ResourcesUpdatedParams
107    );
108    notification!(
109        "notifications/resources/list_changed",
110        ResourcesListChanged,
111        ()
112    );
113    notification!("notifications/tools/list_changed", ToolsListChanged, ());
114    notification!("notifications/prompts/list_changed", PromptsListChanged, ());
115    notification!("notifications/roots/list_changed", RootsListChanged, ());
116}
117
118pub trait Notification {
119    type Params: DeserializeOwned + Serialize + Send + Sync + 'static;
120    const METHOD: &'static str;
121}
122
123#[derive(Debug, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct MessageParams {
126    pub level: LoggingLevel,
127    pub logger: Option<String>,
128    pub data: serde_json::Value,
129}
130
131#[derive(Debug, Serialize, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct ResourcesUpdatedParams {
134    pub uri: String,
135}
136
137#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
138#[serde(transparent)]
139pub struct ProtocolVersion(pub String);
140
141#[derive(Debug, Serialize, Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct InitializeParams {
144    pub protocol_version: ProtocolVersion,
145    pub capabilities: ClientCapabilities,
146    pub client_info: Implementation,
147    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
148    pub meta: Option<HashMap<String, serde_json::Value>>,
149}
150
151#[derive(Debug, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct CallToolParams {
154    pub name: String,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub arguments: Option<serde_json::Value>,
157    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
158    pub meta: Option<HashMap<String, serde_json::Value>>,
159}
160
161#[derive(Debug, Serialize, Deserialize)]
162#[serde(rename_all = "camelCase")]
163pub struct ResourcesUnsubscribeParams {
164    pub uri: Url,
165    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
166    pub meta: Option<HashMap<String, serde_json::Value>>,
167}
168
169#[derive(Debug, Serialize, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct ResourcesSubscribeParams {
172    pub uri: Url,
173    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
174    pub meta: Option<HashMap<String, serde_json::Value>>,
175}
176
177#[derive(Debug, Serialize, Deserialize)]
178#[serde(rename_all = "camelCase")]
179pub struct ResourcesReadParams {
180    pub uri: Url,
181    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
182    pub meta: Option<HashMap<String, serde_json::Value>>,
183}
184
185#[derive(Debug, Serialize, Deserialize)]
186#[serde(rename_all = "camelCase")]
187pub struct LoggingSetLevelParams {
188    pub level: LoggingLevel,
189    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
190    pub meta: Option<HashMap<String, serde_json::Value>>,
191}
192
193#[derive(Debug, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct PromptsGetParams {
196    pub name: String,
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub arguments: Option<HashMap<String, String>>,
199    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
200    pub meta: Option<HashMap<String, serde_json::Value>>,
201}
202
203#[derive(Debug, Serialize, Deserialize)]
204#[serde(rename_all = "camelCase")]
205pub struct CompletionCompleteParams {
206    #[serde(rename = "ref")]
207    pub reference: CompletionReference,
208    pub argument: CompletionArgument,
209    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
210    pub meta: Option<HashMap<String, serde_json::Value>>,
211}
212
213#[derive(Debug, Serialize, Deserialize)]
214#[serde(untagged)]
215pub enum CompletionReference {
216    Prompt(PromptReference),
217    Resource(ResourceReference),
218}
219
220#[derive(Debug, Serialize, Deserialize)]
221#[serde(rename_all = "camelCase")]
222pub struct PromptReference {
223    #[serde(rename = "type")]
224    pub ty: PromptReferenceType,
225    pub name: String,
226}
227
228#[derive(Debug, Serialize, Deserialize)]
229#[serde(rename_all = "camelCase")]
230pub struct ResourceReference {
231    #[serde(rename = "type")]
232    pub ty: PromptReferenceType,
233    pub uri: Url,
234}
235
236#[derive(Debug, Serialize, Deserialize)]
237#[serde(rename_all = "snake_case")]
238pub enum PromptReferenceType {
239    #[serde(rename = "ref/prompt")]
240    Prompt,
241    #[serde(rename = "ref/resource")]
242    Resource,
243}
244
245#[derive(Debug, Serialize, Deserialize)]
246#[serde(rename_all = "camelCase")]
247pub struct CompletionArgument {
248    pub name: String,
249    pub value: String,
250}
251
252#[derive(Debug, Serialize, Deserialize)]
253#[serde(rename_all = "camelCase")]
254pub struct InitializeResponse {
255    pub protocol_version: ProtocolVersion,
256    pub capabilities: ServerCapabilities,
257    pub server_info: Implementation,
258    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
259    pub meta: Option<HashMap<String, serde_json::Value>>,
260}
261
262#[derive(Debug, Serialize, Deserialize)]
263#[serde(rename_all = "camelCase")]
264pub struct ResourcesReadResponse {
265    pub contents: Vec<ResourceContentsType>,
266    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
267    pub meta: Option<HashMap<String, serde_json::Value>>,
268}
269
270#[derive(Debug, Serialize, Deserialize)]
271#[serde(untagged)]
272pub enum ResourceContentsType {
273    Text(TextResourceContents),
274    Blob(BlobResourceContents),
275}
276
277#[derive(Debug, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct ResourcesListResponse {
280    pub resources: Vec<Resource>,
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub next_cursor: Option<String>,
283    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
284    pub meta: Option<HashMap<String, serde_json::Value>>,
285}
286
287#[derive(Debug, Serialize, Deserialize)]
288#[serde(rename_all = "camelCase")]
289pub struct SamplingMessage {
290    pub role: Role,
291    pub content: MessageContent,
292}
293
294#[derive(Debug, Serialize, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct CreateMessageRequest {
297    pub messages: Vec<SamplingMessage>,
298    #[serde(skip_serializing_if = "Option::is_none")]
299    pub model_preferences: Option<ModelPreferences>,
300    #[serde(skip_serializing_if = "Option::is_none")]
301    pub system_prompt: Option<String>,
302    #[serde(skip_serializing_if = "Option::is_none")]
303    pub include_context: Option<String>,
304    #[serde(skip_serializing_if = "Option::is_none")]
305    pub temperature: Option<f64>,
306    pub max_tokens: u32,
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub stop_sequences: Option<Vec<String>>,
309    #[serde(skip_serializing_if = "Option::is_none")]
310    pub metadata: Option<serde_json::Value>,
311}
312
313#[derive(Debug, Deserialize)]
314#[serde(rename_all = "camelCase")]
315pub struct CreateMessageResult {
316    pub role: Role,
317    pub content: MessageContent,
318    pub model: String,
319    #[serde(skip_serializing_if = "Option::is_none")]
320    pub stop_reason: Option<String>,
321}
322
323#[derive(Debug, Serialize, Deserialize)]
324#[serde(rename_all = "camelCase")]
325pub struct PromptMessage {
326    pub role: Role,
327    pub content: MessageContent,
328}
329
330#[derive(Debug, Serialize, Deserialize)]
331#[serde(rename_all = "lowercase")]
332pub enum Role {
333    User,
334    Assistant,
335}
336
337#[derive(Debug, Serialize, Deserialize)]
338#[serde(tag = "type")]
339pub enum MessageContent {
340    #[serde(rename = "text")]
341    Text {
342        text: String,
343        #[serde(skip_serializing_if = "Option::is_none")]
344        annotations: Option<MessageAnnotations>,
345    },
346    #[serde(rename = "image", rename_all = "camelCase")]
347    Image {
348        data: String,
349        mime_type: String,
350        #[serde(skip_serializing_if = "Option::is_none")]
351        annotations: Option<MessageAnnotations>,
352    },
353    #[serde(rename = "audio", rename_all = "camelCase")]
354    Audio {
355        data: String,
356        mime_type: String,
357        #[serde(skip_serializing_if = "Option::is_none")]
358        annotations: Option<MessageAnnotations>,
359    },
360    #[serde(rename = "resource")]
361    Resource {
362        resource: ResourceContents,
363        #[serde(skip_serializing_if = "Option::is_none")]
364        annotations: Option<MessageAnnotations>,
365    },
366}
367
368#[derive(Debug, Serialize, Deserialize)]
369#[serde(rename_all = "camelCase")]
370pub struct MessageAnnotations {
371    #[serde(skip_serializing_if = "Option::is_none")]
372    pub audience: Option<Vec<Role>>,
373    #[serde(skip_serializing_if = "Option::is_none")]
374    pub priority: Option<f64>,
375}
376
377#[derive(Debug, Serialize, Deserialize)]
378#[serde(rename_all = "camelCase")]
379pub struct PromptsGetResponse {
380    #[serde(skip_serializing_if = "Option::is_none")]
381    pub description: Option<String>,
382    pub messages: Vec<PromptMessage>,
383    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
384    pub meta: Option<HashMap<String, serde_json::Value>>,
385}
386
387#[derive(Debug, Serialize, Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct PromptsListResponse {
390    pub prompts: Vec<Prompt>,
391    #[serde(skip_serializing_if = "Option::is_none")]
392    pub next_cursor: Option<String>,
393    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
394    pub meta: Option<HashMap<String, serde_json::Value>>,
395}
396
397#[derive(Debug, Serialize, Deserialize)]
398#[serde(rename_all = "camelCase")]
399pub struct CompletionCompleteResponse {
400    pub completion: CompletionResult,
401    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
402    pub meta: Option<HashMap<String, serde_json::Value>>,
403}
404
405#[derive(Debug, Serialize, Deserialize)]
406#[serde(rename_all = "camelCase")]
407pub struct CompletionResult {
408    pub values: Vec<String>,
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub total: Option<u32>,
411    #[serde(skip_serializing_if = "Option::is_none")]
412    pub has_more: Option<bool>,
413    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
414    pub meta: Option<HashMap<String, serde_json::Value>>,
415}
416
417#[derive(Debug, Serialize, Deserialize)]
418#[serde(rename_all = "camelCase")]
419pub struct Prompt {
420    pub name: String,
421    #[serde(skip_serializing_if = "Option::is_none")]
422    pub description: Option<String>,
423    #[serde(skip_serializing_if = "Option::is_none")]
424    pub arguments: Option<Vec<PromptArgument>>,
425}
426
427#[derive(Debug, Serialize, Deserialize)]
428#[serde(rename_all = "camelCase")]
429pub struct PromptArgument {
430    pub name: String,
431    #[serde(skip_serializing_if = "Option::is_none")]
432    pub description: Option<String>,
433    #[serde(skip_serializing_if = "Option::is_none")]
434    pub required: Option<bool>,
435}
436
437#[derive(Debug, Serialize, Deserialize)]
438#[serde(rename_all = "camelCase")]
439pub struct ClientCapabilities {
440    #[serde(skip_serializing_if = "Option::is_none")]
441    pub experimental: Option<HashMap<String, serde_json::Value>>,
442    #[serde(skip_serializing_if = "Option::is_none")]
443    pub sampling: Option<serde_json::Value>,
444    #[serde(skip_serializing_if = "Option::is_none")]
445    pub roots: Option<RootsCapabilities>,
446}
447
448#[derive(Default, Debug, Serialize, Deserialize)]
449#[serde(rename_all = "camelCase")]
450pub struct ServerCapabilities {
451    #[serde(skip_serializing_if = "Option::is_none")]
452    pub experimental: Option<HashMap<String, serde_json::Value>>,
453    #[serde(skip_serializing_if = "Option::is_none")]
454    pub logging: Option<serde_json::Value>,
455    #[serde(skip_serializing_if = "Option::is_none")]
456    pub completions: Option<serde_json::Value>,
457    #[serde(skip_serializing_if = "Option::is_none")]
458    pub prompts: Option<PromptsCapabilities>,
459    #[serde(skip_serializing_if = "Option::is_none")]
460    pub resources: Option<ResourcesCapabilities>,
461    #[serde(skip_serializing_if = "Option::is_none")]
462    pub tools: Option<ToolsCapabilities>,
463}
464
465#[derive(Debug, Serialize, Deserialize)]
466#[serde(rename_all = "camelCase")]
467pub struct PromptsCapabilities {
468    #[serde(skip_serializing_if = "Option::is_none")]
469    pub list_changed: Option<bool>,
470}
471
472#[derive(Debug, Serialize, Deserialize)]
473#[serde(rename_all = "camelCase")]
474pub struct ResourcesCapabilities {
475    #[serde(skip_serializing_if = "Option::is_none")]
476    pub subscribe: Option<bool>,
477    #[serde(skip_serializing_if = "Option::is_none")]
478    pub list_changed: Option<bool>,
479}
480
481#[derive(Debug, Serialize, Deserialize)]
482#[serde(rename_all = "camelCase")]
483pub struct ToolsCapabilities {
484    #[serde(skip_serializing_if = "Option::is_none")]
485    pub list_changed: Option<bool>,
486}
487
488#[derive(Debug, Serialize, Deserialize)]
489#[serde(rename_all = "camelCase")]
490pub struct RootsCapabilities {
491    #[serde(skip_serializing_if = "Option::is_none")]
492    pub list_changed: Option<bool>,
493}
494
495#[derive(Debug, Serialize, Deserialize)]
496#[serde(rename_all = "camelCase")]
497pub struct Tool {
498    pub name: String,
499    #[serde(skip_serializing_if = "Option::is_none")]
500    pub description: Option<String>,
501    pub input_schema: serde_json::Value,
502    #[serde(skip_serializing_if = "Option::is_none")]
503    pub annotations: Option<ToolAnnotations>,
504}
505
506#[derive(Debug, Serialize, Deserialize)]
507#[serde(rename_all = "camelCase")]
508pub struct ToolAnnotations {
509    /// A human-readable title for the tool.
510    #[serde(skip_serializing_if = "Option::is_none")]
511    pub title: Option<String>,
512    /// If true, the tool does not modify its environment.
513    #[serde(skip_serializing_if = "Option::is_none")]
514    pub read_only_hint: Option<bool>,
515    /// If true, the tool may perform destructive updates to its environment.
516    #[serde(skip_serializing_if = "Option::is_none")]
517    pub destructive_hint: Option<bool>,
518    /// If true, calling the tool repeatedly with the same arguments will have no additional effect on its environment.
519    #[serde(skip_serializing_if = "Option::is_none")]
520    pub idempotent_hint: Option<bool>,
521    /// If true, this tool may interact with an "open world" of external entities.
522    #[serde(skip_serializing_if = "Option::is_none")]
523    pub open_world_hint: Option<bool>,
524}
525
526#[derive(Debug, Serialize, Deserialize)]
527#[serde(rename_all = "camelCase")]
528pub struct Implementation {
529    pub name: String,
530    pub version: String,
531}
532
533#[derive(Debug, Serialize, Deserialize)]
534#[serde(rename_all = "camelCase")]
535pub struct Resource {
536    pub uri: Url,
537    pub name: String,
538    #[serde(skip_serializing_if = "Option::is_none")]
539    pub description: Option<String>,
540    #[serde(skip_serializing_if = "Option::is_none")]
541    pub mime_type: Option<String>,
542}
543
544#[derive(Debug, Serialize, Deserialize)]
545#[serde(rename_all = "camelCase")]
546pub struct ResourceContents {
547    pub uri: Url,
548    #[serde(skip_serializing_if = "Option::is_none")]
549    pub mime_type: Option<String>,
550}
551
552#[derive(Debug, Serialize, Deserialize)]
553#[serde(rename_all = "camelCase")]
554pub struct TextResourceContents {
555    pub uri: Url,
556    #[serde(skip_serializing_if = "Option::is_none")]
557    pub mime_type: Option<String>,
558    pub text: String,
559}
560
561#[derive(Debug, Serialize, Deserialize)]
562#[serde(rename_all = "camelCase")]
563pub struct BlobResourceContents {
564    pub uri: Url,
565    #[serde(skip_serializing_if = "Option::is_none")]
566    pub mime_type: Option<String>,
567    pub blob: String,
568}
569
570#[derive(Debug, Serialize, Deserialize)]
571#[serde(rename_all = "camelCase")]
572pub struct ResourceTemplate {
573    pub uri_template: String,
574    pub name: String,
575    #[serde(skip_serializing_if = "Option::is_none")]
576    pub description: Option<String>,
577    #[serde(skip_serializing_if = "Option::is_none")]
578    pub mime_type: Option<String>,
579}
580
581#[derive(Debug, Serialize, Deserialize)]
582#[serde(rename_all = "lowercase")]
583pub enum LoggingLevel {
584    Debug,
585    Info,
586    Notice,
587    Warning,
588    Error,
589    Critical,
590    Alert,
591    Emergency,
592}
593
594#[derive(Debug, Serialize, Deserialize)]
595#[serde(rename_all = "camelCase")]
596pub struct ModelPreferences {
597    #[serde(skip_serializing_if = "Option::is_none")]
598    pub hints: Option<Vec<ModelHint>>,
599    #[serde(skip_serializing_if = "Option::is_none")]
600    pub cost_priority: Option<f64>,
601    #[serde(skip_serializing_if = "Option::is_none")]
602    pub speed_priority: Option<f64>,
603    #[serde(skip_serializing_if = "Option::is_none")]
604    pub intelligence_priority: Option<f64>,
605}
606
607#[derive(Debug, Serialize, Deserialize)]
608#[serde(rename_all = "camelCase")]
609pub struct ModelHint {
610    #[serde(skip_serializing_if = "Option::is_none")]
611    pub name: Option<String>,
612}
613
614#[derive(Debug, Serialize)]
615#[serde(untagged)]
616pub enum ClientNotification {
617    Initialized,
618    Progress(ProgressParams),
619    RootsListChanged,
620    Cancelled {
621        request_id: String,
622        #[serde(skip_serializing_if = "Option::is_none")]
623        reason: Option<String>,
624    },
625}
626
627#[derive(Debug, Serialize, Deserialize)]
628#[serde(untagged)]
629pub enum ProgressToken {
630    String(String),
631    Number(f64),
632}
633
634#[derive(Debug, Serialize, Deserialize)]
635#[serde(rename_all = "camelCase")]
636pub struct ProgressParams {
637    pub progress_token: ProgressToken,
638    pub progress: f64,
639    #[serde(skip_serializing_if = "Option::is_none")]
640    pub message: Option<String>,
641    #[serde(skip_serializing_if = "Option::is_none")]
642    pub total: Option<f64>,
643    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
644    pub meta: Option<HashMap<String, serde_json::Value>>,
645}
646
647pub enum CompletionTotal {
648    Exact(u32),
649    HasMore,
650    Unknown,
651}
652
653impl CompletionTotal {
654    pub fn from_options(has_more: Option<bool>, total: Option<u32>) -> Self {
655        match (has_more, total) {
656            (_, Some(count)) => CompletionTotal::Exact(count),
657            (Some(true), _) => CompletionTotal::HasMore,
658            _ => CompletionTotal::Unknown,
659        }
660    }
661}
662
663pub struct Completion {
664    pub values: Vec<String>,
665    pub total: CompletionTotal,
666}
667
668#[derive(Debug, Serialize, Deserialize)]
669#[serde(rename_all = "camelCase")]
670pub struct CallToolResponse {
671    pub content: Vec<ToolResponseContent>,
672    #[serde(skip_serializing_if = "Option::is_none")]
673    pub is_error: Option<bool>,
674    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
675    pub meta: Option<HashMap<String, serde_json::Value>>,
676}
677
678#[derive(Debug, Serialize, Deserialize)]
679#[serde(tag = "type")]
680pub enum ToolResponseContent {
681    #[serde(rename = "text")]
682    Text { text: String },
683    #[serde(rename = "image", rename_all = "camelCase")]
684    Image { data: String, mime_type: String },
685    #[serde(rename = "audio", rename_all = "camelCase")]
686    Audio { data: String, mime_type: String },
687    #[serde(rename = "resource")]
688    Resource { resource: ResourceContents },
689}
690
691#[derive(Debug, Serialize, Deserialize)]
692#[serde(rename_all = "camelCase")]
693pub struct ListToolsResponse {
694    pub tools: Vec<Tool>,
695    #[serde(skip_serializing_if = "Option::is_none")]
696    pub next_cursor: Option<String>,
697    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
698    pub meta: Option<HashMap<String, serde_json::Value>>,
699}
700
701#[derive(Debug, Serialize, Deserialize)]
702#[serde(rename_all = "camelCase")]
703pub struct ListResourceTemplatesResponse {
704    pub resource_templates: Vec<ResourceTemplate>,
705    #[serde(skip_serializing_if = "Option::is_none")]
706    pub next_cursor: Option<String>,
707    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
708    pub meta: Option<HashMap<String, serde_json::Value>>,
709}
710
711#[derive(Debug, Serialize, Deserialize)]
712#[serde(rename_all = "camelCase")]
713pub struct ListRootsResponse {
714    pub roots: Vec<Root>,
715    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
716    pub meta: Option<HashMap<String, serde_json::Value>>,
717}
718
719#[derive(Debug, Serialize, Deserialize)]
720#[serde(rename_all = "camelCase")]
721pub struct Root {
722    pub uri: Url,
723    #[serde(skip_serializing_if = "Option::is_none")]
724    pub name: Option<String>,
725}