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}