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