Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:54:05.465Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

types.rs

812 lines · 25.7 KB · rust
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
Served at tenant.openagents/omega Member data and write actions are omitted.