mcp_schema/
types.rs

1//! This module defines MCP + JSON-RPC data structures, using `serde` for
2//! serialization/deserialization. It follows the JSON-RPC 2.0 specification
3//! and the Model Context Protocol (MCP) while ensuring Rust naming conventions
4//! are kept (`snake_case` internally, `camelCase` in JSON).
5//!
6//! # Overview
7//!
8//! - `JSONRPCRequest<T>` / `JSONRPCResponse<U>` are generic types for JSON-RPC messages.
9//! - MCP extends JSON-RPC with additional fields, metadata, and custom structures
10//!   (e.g., `InitializeParams`, `ClientCapabilities`, etc.).
11//! - All fields use `#[serde(rename_all = "camelCase")]` so Rust code remains snake_case
12//!   while JSON output remains camelCase.
13
14use serde::{Deserialize, Serialize};
15use serde_json::Value;
16use std::collections::HashMap;
17
18/// The JSON-RPC version string (always "2.0").
19pub const JSONRPC_VERSION: &str = "2.0";
20
21/// The latest Model Context Protocol version.
22pub const LATEST_PROTOCOL_VERSION: &str = "2024-11-05";
23
24// Below are standard JSON-RPC error codes.
25pub const PARSE_ERROR: i32 = -32700;
26pub const INVALID_REQUEST: i32 = -32600;
27pub const METHOD_NOT_FOUND: i32 = -32601;
28pub const INVALID_PARAMS: i32 = -32602;
29pub const INTERNAL_ERROR: i32 = -32603;
30
31/// A request ID for JSON-RPC, which can be either a string or a number.
32#[derive(Debug, Clone, Serialize, Deserialize)]
33#[serde(untagged)]
34pub enum RequestId {
35    String(String),
36    Number(i64),
37}
38
39/// A progress token for associating progress notifications with a request.
40/// This can be either a string or a number.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42#[serde(untagged)]
43pub enum ProgressToken {
44    String(String),
45    Number(i64),
46}
47
48/// A cursor for pagination.
49pub type Cursor = String;
50
51/// A generic JSON-RPC request.
52///
53/// # Type Parameters
54///
55/// - `T`: The type of the `params` field, containing request-specific data.
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct JSONRPCRequest<T> {
59    /// Must be "2.0" for JSON-RPC.
60    #[serde(rename = "jsonrpc")]
61    pub json_rpc: String,
62
63    /// Method name.
64    pub method: String,
65
66    /// Request ID (string or number).
67    pub id: RequestId,
68
69    /// Generic request parameters.
70    pub params: T,
71}
72
73/// A generic JSON-RPC notification. Notifications do not carry an `id`.
74///
75/// # Type Parameters
76///
77/// - `T`: The type of the `params` field, containing notification-specific data.
78#[derive(Debug, Clone, Serialize, Deserialize)]
79#[serde(rename_all = "camelCase")]
80pub struct JSONRPCNotification<T> {
81    #[serde(rename = "jsonrpc")]
82    pub json_rpc: String,
83    pub method: String,
84    pub params: T,
85}
86
87/// A generic JSON-RPC response.
88///
89/// # Type Parameters
90///
91/// - `U`: The type of the `result` field, containing response-specific data.
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct JSONRPCResponse<U> {
95    #[serde(rename = "jsonrpc")]
96    pub json_rpc: String,
97    pub id: RequestId,
98
99    /// Result object when the request completes successfully.
100    pub result: U,
101}
102
103/// A JSON-RPC error message, indicating that a request failed.
104#[derive(Debug, Clone, Serialize, Deserialize)]
105#[serde(rename_all = "camelCase")]
106pub struct JSONRPCError {
107    #[serde(rename = "jsonrpc")]
108    pub json_rpc: String,
109    pub id: RequestId,
110    pub error: RPCErrorDetail,
111}
112
113/// Provides details about a JSON-RPC error, including an optional `data` field.
114#[derive(Debug, Clone, Serialize, Deserialize)]
115#[serde(rename_all = "camelCase")]
116pub struct RPCErrorDetail {
117    pub code: i32,
118    pub message: String,
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub data: Option<Value>,
121}
122
123/// Parameters for an MCP request, allowing additional arbitrary fields via `flatten`.
124#[derive(Debug, Clone, Serialize, Deserialize)]
125#[serde(rename_all = "camelCase")]
126pub struct MCPRequestParams {
127    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
128    pub meta: Option<RequestMeta>,
129
130    /// Arbitrary extra fields.
131    #[serde(flatten)]
132    pub extra: HashMap<String, Value>,
133}
134
135/// `_meta` field for MCP requests, optionally containing a progress token.
136#[derive(Debug, Clone, Serialize, Deserialize)]
137#[serde(rename_all = "camelCase")]
138pub struct RequestMeta {
139    #[serde(rename = "progressToken", skip_serializing_if = "Option::is_none")]
140    pub progress_token: Option<ProgressToken>,
141}
142
143/// Parameters for an MCP notification, allowing additional arbitrary fields via `flatten`.
144#[derive(Debug, Clone, Serialize, Deserialize, Default)]
145#[serde(rename_all = "camelCase")]
146pub struct MCPNotificationParams {
147    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
148    pub meta: Option<HashMap<String, Value>>,
149    #[serde(flatten)]
150    pub extra: HashMap<String, Value>,
151}
152
153/// Base result type for MCP responses.
154#[derive(Debug, Clone, Serialize, Deserialize)]
155#[serde(rename_all = "camelCase")]
156pub struct MCPResultBase {
157    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
158    pub meta: Option<HashMap<String, Value>>,
159    #[serde(flatten)]
160    pub extra: HashMap<String, Value>,
161}
162
163/// Indicates success but carries no data.
164pub type EmptyResult = MCPResultBase;
165
166/// Represents parameters for a cancelled-notification, which can be sent by either side.
167#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct CancelledNotificationParams {
170    pub request_id: RequestId,
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub reason: Option<String>,
173}
174
175/// Parameters for initializing communication (client -> server).
176#[derive(Debug, Clone, Serialize, Deserialize)]
177#[serde(rename_all = "camelCase")]
178pub struct InitializeParams {
179    pub protocol_version: String,
180    pub capabilities: ClientCapabilities,
181    pub client_info: Implementation,
182}
183
184/// A result returned by the server after an `initialize` request.
185#[derive(Debug, Clone, Serialize, Deserialize)]
186#[serde(rename_all = "camelCase")]
187pub struct InitializeResult {
188    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
189    pub meta: Option<HashMap<String, Value>>,
190
191    pub protocol_version: String,
192    pub capabilities: ServerCapabilities,
193    pub server_info: Implementation,
194
195    /// Optional instructions from the server.
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub instructions: Option<String>,
198
199    #[serde(flatten)]
200    pub extra: HashMap<String, Value>,
201}
202
203/// Describes capabilities a client might support.
204#[derive(Debug, Clone, Serialize, Deserialize)]
205#[serde(rename_all = "camelCase")]
206pub struct ClientCapabilities {
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub experimental: Option<HashMap<String, Value>>,
209
210    #[serde(skip_serializing_if = "Option::is_none")]
211    pub roots: Option<RootsCapability>,
212
213    #[serde(skip_serializing_if = "Option::is_none")]
214    pub sampling: Option<HashMap<String, Value>>,
215
216    #[serde(flatten)]
217    pub extra: HashMap<String, Value>,
218}
219
220/// Describes whether the client supports updated-list notifications for roots.
221#[derive(Debug, Clone, Serialize, Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub struct RootsCapability {
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub list_changed: Option<bool>,
226}
227
228/// A set of capabilities the server may support.
229#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(rename_all = "camelCase")]
231pub struct ServerCapabilities {
232    #[serde(skip_serializing_if = "Option::is_none")]
233    pub experimental: Option<HashMap<String, Value>>,
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub logging: Option<HashMap<String, Value>>,
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub prompts: Option<PromptsCapability>,
238    #[serde(skip_serializing_if = "Option::is_none")]
239    pub resources: Option<ResourcesCapability>,
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub tools: Option<ToolsCapability>,
242
243    #[serde(flatten)]
244    pub extra: HashMap<String, Value>,
245}
246
247/// Indicates server support for prompt-related features.
248#[derive(Debug, Clone, Serialize, Deserialize)]
249#[serde(rename_all = "camelCase")]
250pub struct PromptsCapability {
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub list_changed: Option<bool>,
253}
254
255/// Indicates server support for resource-related features.
256#[derive(Debug, Clone, Serialize, Deserialize)]
257#[serde(rename_all = "camelCase")]
258pub struct ResourcesCapability {
259    #[serde(skip_serializing_if = "Option::is_none")]
260    pub subscribe: Option<bool>,
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub list_changed: Option<bool>,
263}
264
265/// Indicates server support for tool-related features.
266#[derive(Debug, Clone, Serialize, Deserialize)]
267#[serde(rename_all = "camelCase")]
268pub struct ToolsCapability {
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub list_changed: Option<bool>,
271}
272
273/// Represents the name and version of an MCP implementation.
274#[derive(Debug, Clone, Serialize, Deserialize)]
275#[serde(rename_all = "camelCase")]
276pub struct Implementation {
277    pub name: String,
278    pub version: String,
279
280    #[serde(flatten)]
281    pub extra: HashMap<String, Value>,
282}
283
284/// Parameters for the `ping` method (client or server). Generally empty.
285#[derive(Debug, Clone, Serialize, Deserialize, Default)]
286#[serde(rename_all = "camelCase")]
287pub struct PingParams {}
288
289/// Parameters for a progress notification, typically referencing a long-running request.
290#[derive(Debug, Clone, Serialize, Deserialize)]
291#[serde(rename_all = "camelCase")]
292pub struct ProgressNotificationParams {
293    pub progress_token: ProgressToken,
294    pub progress: f64,
295    #[serde(skip_serializing_if = "Option::is_none")]
296    pub total: Option<f64>,
297
298    #[serde(flatten)]
299    pub extra: HashMap<String, Value>,
300}
301
302/// A structure for request parameters that may involve pagination.
303#[derive(Debug, Clone, Serialize, Deserialize, Default)]
304#[serde(rename_all = "camelCase")]
305pub struct PaginatedParams {
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub _meta: Option<RequestMeta>,
308    #[serde(skip_serializing_if = "Option::is_none")]
309    pub cursor: Option<Cursor>,
310
311    #[serde(flatten)]
312    pub extra: HashMap<String, Value>,
313}
314
315/// Indicates that a result can include pagination metadata.
316#[derive(Debug, Clone, Serialize, Deserialize)]
317#[serde(rename_all = "camelCase")]
318pub struct PaginatedResult {
319    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
320    pub meta: Option<HashMap<String, Value>>,
321    #[serde(skip_serializing_if = "Option::is_none")]
322    pub next_cursor: Option<Cursor>,
323
324    #[serde(flatten)]
325    pub extra: HashMap<String, Value>,
326}
327
328/// A result containing a list of resources known to the server.
329#[derive(Debug, Clone, Serialize, Deserialize)]
330#[serde(rename_all = "camelCase")]
331pub struct ListResourcesResult {
332    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
333    pub meta: Option<HashMap<String, Value>>,
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub next_cursor: Option<Cursor>,
336    pub resources: Vec<Resource>,
337
338    #[serde(flatten)]
339    pub extra: HashMap<String, Value>,
340}
341
342/// A result containing a list of resource templates known to the server.
343#[derive(Debug, Clone, Serialize, Deserialize)]
344#[serde(rename_all = "camelCase")]
345pub struct ListResourceTemplatesResult {
346    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
347    pub meta: Option<HashMap<String, Value>>,
348    #[serde(skip_serializing_if = "Option::is_none")]
349    pub next_cursor: Option<Cursor>,
350    pub resource_templates: Vec<ResourceTemplate>,
351
352    #[serde(flatten)]
353    pub extra: HashMap<String, Value>,
354}
355
356/// Parameters for the `resources/read` method.
357#[derive(Debug, Clone, Serialize, Deserialize)]
358#[serde(rename_all = "camelCase")]
359pub struct ReadResourceParams {
360    pub uri: String,
361    #[serde(flatten)]
362    pub extra: HashMap<String, Value>,
363}
364
365/// A result from the `resources/read` method, containing resource contents.
366#[derive(Debug, Clone, Serialize, Deserialize)]
367#[serde(rename_all = "camelCase")]
368pub struct ReadResourceResult {
369    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
370    pub meta: Option<HashMap<String, Value>>,
371    pub contents: Vec<ResourceContents>,
372
373    #[serde(flatten)]
374    pub extra: HashMap<String, Value>,
375}
376
377/// Parameters for `resources/subscribe`.
378#[derive(Debug, Clone, Serialize, Deserialize)]
379#[serde(rename_all = "camelCase")]
380pub struct SubscribeParams {
381    pub uri: String,
382    #[serde(flatten)]
383    pub extra: HashMap<String, Value>,
384}
385
386/// Parameters for `resources/unsubscribe`.
387#[derive(Debug, Clone, Serialize, Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct UnsubscribeParams {
390    pub uri: String,
391    #[serde(flatten)]
392    pub extra: HashMap<String, Value>,
393}
394
395/// Parameters for a `notifications/resources/updated` message.
396#[derive(Debug, Clone, Serialize, Deserialize)]
397#[serde(rename_all = "camelCase")]
398pub struct ResourceUpdatedParams {
399    pub uri: String,
400    #[serde(flatten)]
401    pub extra: HashMap<String, Value>,
402}
403
404/// A resource object that the server can read, possibly with extra metadata.
405#[derive(Debug, Clone, Serialize, Deserialize)]
406#[serde(rename_all = "camelCase")]
407pub struct Resource {
408    pub uri: String,
409    pub name: String,
410    #[serde(skip_serializing_if = "Option::is_none")]
411    pub description: Option<String>,
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub mime_type: Option<String>,
414
415    #[serde(flatten)]
416    pub annotated: Annotated,
417}
418
419/// A resource template, which can be used to generate resource URIs.
420#[derive(Debug, Clone, Serialize, Deserialize)]
421#[serde(rename_all = "camelCase")]
422pub struct ResourceTemplate {
423    pub uri_template: String,
424    pub name: String,
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub description: Option<String>,
427    #[serde(skip_serializing_if = "Option::is_none")]
428    pub mime_type: Option<String>,
429
430    #[serde(flatten)]
431    pub annotated: Annotated,
432}
433
434/// Contents of a resource. May be text or binary data.
435#[derive(Debug, Clone, Serialize, Deserialize)]
436#[serde(untagged)]
437pub enum ResourceContents {
438    Text(TextResourceContents),
439    Blob(BlobResourceContents),
440}
441
442/// Represents textual resource contents.
443#[derive(Debug, Clone, Serialize, Deserialize)]
444#[serde(rename_all = "camelCase")]
445pub struct TextResourceContents {
446    pub uri: String,
447    #[serde(skip_serializing_if = "Option::is_none")]
448    pub mime_type: Option<String>,
449    pub text: String,
450}
451
452/// Represents binary resource contents.
453#[derive(Debug, Clone, Serialize, Deserialize)]
454#[serde(rename_all = "camelCase")]
455pub struct BlobResourceContents {
456    pub uri: String,
457    #[serde(skip_serializing_if = "Option::is_none")]
458    pub mime_type: Option<String>,
459    pub blob: String,
460}
461
462/// A result containing a list of prompts known to the server.
463#[derive(Debug, Clone, Serialize, Deserialize)]
464#[serde(rename_all = "camelCase")]
465pub struct ListPromptsResult {
466    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
467    pub meta: Option<HashMap<String, Value>>,
468    #[serde(skip_serializing_if = "Option::is_none")]
469    pub next_cursor: Option<Cursor>,
470
471    pub prompts: Vec<Prompt>,
472    #[serde(flatten)]
473    pub extra: HashMap<String, Value>,
474}
475
476/// Parameters for `prompts/get`.
477#[derive(Debug, Clone, Serialize, Deserialize)]
478#[serde(rename_all = "camelCase")]
479pub struct GetPromptParams {
480    pub name: String,
481    #[serde(skip_serializing_if = "Option::is_none")]
482    pub arguments: Option<HashMap<String, String>>,
483    #[serde(flatten)]
484    pub extra: HashMap<String, Value>,
485}
486
487/// A result returned by `prompts/get`.
488#[derive(Debug, Clone, Serialize, Deserialize)]
489#[serde(rename_all = "camelCase")]
490pub struct GetPromptResult {
491    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
492    pub meta: Option<HashMap<String, Value>>,
493    #[serde(skip_serializing_if = "Option::is_none")]
494    pub description: Option<String>,
495    pub messages: Vec<PromptMessage>,
496
497    #[serde(flatten)]
498    pub extra: HashMap<String, Value>,
499}
500
501/// A prompt object or prompt template.
502#[derive(Debug, Clone, Serialize, Deserialize)]
503#[serde(rename_all = "camelCase")]
504pub struct Prompt {
505    pub name: String,
506    #[serde(skip_serializing_if = "Option::is_none")]
507    pub description: Option<String>,
508    #[serde(skip_serializing_if = "Option::is_none")]
509    pub arguments: Option<Vec<PromptArgument>>,
510
511    #[serde(flatten)]
512    pub extra: HashMap<String, Value>,
513}
514
515/// Arguments accepted by a prompt, potentially required.
516#[derive(Debug, Clone, Serialize, Deserialize)]
517#[serde(rename_all = "camelCase")]
518pub struct PromptArgument {
519    pub name: String,
520    #[serde(skip_serializing_if = "Option::is_none")]
521    pub description: Option<String>,
522    #[serde(skip_serializing_if = "Option::is_none")]
523    pub required: Option<bool>,
524
525    #[serde(flatten)]
526    pub extra: HashMap<String, Value>,
527}
528
529/// A role in a conversation: either "user" or "assistant".
530#[derive(Debug, Clone, Serialize, Deserialize)]
531#[serde(rename_all = "lowercase")]
532pub enum Role {
533    User,
534    Assistant,
535}
536
537/// A message returned as part of a prompt result.
538#[derive(Debug, Clone, Serialize, Deserialize)]
539#[serde(rename_all = "camelCase")]
540pub struct PromptMessage {
541    pub role: Role,
542    pub content: PromptContent,
543}
544
545/// Represents the content of a prompt message: text, image, or embedded resource.
546#[derive(Debug, Clone, Serialize, Deserialize)]
547#[serde(untagged)]
548pub enum PromptContent {
549    Text(TextContent),
550    Image(ImageContent),
551    Resource(EmbeddedResource),
552}
553
554/// An embedded resource, which can contain a text or blob resource internally.
555#[derive(Debug, Clone, Serialize, Deserialize)]
556#[serde(rename_all = "camelCase")]
557pub struct EmbeddedResource {
558    #[serde(rename = "type")]
559    pub kind: String, // e.g., "resource"
560    pub resource: ResourceContents,
561
562    #[serde(flatten)]
563    pub annotated: Annotated,
564}
565
566/// Allows attaching optional annotations and arbitrary extra fields.
567#[derive(Debug, Clone, Serialize, Deserialize)]
568#[serde(rename_all = "camelCase")]
569pub struct Annotated {
570    #[serde(skip_serializing_if = "Option::is_none")]
571    pub annotations: Option<Annotations>,
572    #[serde(flatten)]
573    pub extra: HashMap<String, Value>,
574}
575
576/// Contains optional annotation data such as `audience` or `priority`.
577#[derive(Debug, Clone, Serialize, Deserialize)]
578#[serde(rename_all = "camelCase")]
579pub struct Annotations {
580    #[serde(skip_serializing_if = "Option::is_none")]
581    pub audience: Option<Vec<Role>>,
582    #[serde(skip_serializing_if = "Option::is_none")]
583    pub priority: Option<f64>,
584    #[serde(flatten)]
585    pub extra: HashMap<String, Value>,
586}
587
588/// Represents text content in a prompt or message.
589#[derive(Debug, Clone, Serialize, Deserialize)]
590#[serde(rename_all = "camelCase")]
591pub struct TextContent {
592    #[serde(rename = "type")]
593    pub kind: String, // "text"
594    pub text: String,
595
596    #[serde(flatten)]
597    pub annotated: Annotated,
598}
599
600/// Represents image content, stored in base64.
601#[derive(Debug, Clone, Serialize, Deserialize)]
602#[serde(rename_all = "camelCase")]
603pub struct ImageContent {
604    #[serde(rename = "type")]
605    pub kind: String, // "image"
606    pub data: String,
607    pub mime_type: String,
608
609    #[serde(flatten)]
610    pub annotated: Annotated,
611}
612
613/// A result listing server-provided tools.
614#[derive(Debug, Clone, Serialize, Deserialize)]
615#[serde(rename_all = "camelCase")]
616pub struct ListToolsResult {
617    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
618    pub meta: Option<HashMap<String, Value>>,
619    #[serde(skip_serializing_if = "Option::is_none")]
620    pub next_cursor: Option<Cursor>,
621    pub tools: Vec<Tool>,
622
623    #[serde(flatten)]
624    pub extra: HashMap<String, Value>,
625}
626
627/// Parameters for the `tools/call` method.
628#[derive(Debug, Clone, Serialize, Deserialize)]
629#[serde(rename_all = "camelCase")]
630pub struct CallToolParams {
631    pub name: String,
632    #[serde(skip_serializing_if = "Option::is_none")]
633    pub arguments: Option<HashMap<String, Value>>,
634
635    #[serde(flatten)]
636    pub extra: HashMap<String, Value>,
637}
638
639/// A result from the `tools/call` method, potentially indicating an error.
640#[derive(Debug, Clone, Serialize, Deserialize)]
641#[serde(rename_all = "camelCase")]
642pub struct CallToolResult {
643    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
644    pub meta: Option<HashMap<String, Value>>,
645    pub content: Vec<PromptContent>,
646    
647    /// Structured content that conforms to the tool's output schema.
648    #[serde(skip_serializing_if = "Option::is_none")]
649    pub structured_content: Option<Value>,
650
651    /// True if the tool call ended in an error.
652    #[serde(skip_serializing_if = "Option::is_none")]
653    pub is_error: Option<bool>,
654
655    #[serde(flatten)]
656    pub extra: HashMap<String, Value>,
657}
658
659/// Annotations that describe tool behavior hints.
660#[derive(Debug, Clone, Serialize, Deserialize)]
661#[serde(rename_all = "camelCase")]
662pub struct ToolAnnotations {
663    #[serde(skip_serializing_if = "Option::is_none")]
664    pub title: Option<String>,
665    #[serde(skip_serializing_if = "Option::is_none")]
666    pub read_only_hint: Option<bool>,
667    #[serde(skip_serializing_if = "Option::is_none")]
668    pub destructive_hint: Option<bool>,
669    #[serde(skip_serializing_if = "Option::is_none")]
670    pub idempotent_hint: Option<bool>,
671    #[serde(skip_serializing_if = "Option::is_none")]
672    pub open_world_hint: Option<bool>,
673}
674
675/// Defines a tool that can be invoked by the client.
676#[derive(Debug, Clone, Serialize, Deserialize)]
677#[serde(rename_all = "camelCase")]
678pub struct Tool {
679    pub name: String,
680    #[serde(skip_serializing_if = "Option::is_none")]
681    pub title: Option<String>,
682    #[serde(skip_serializing_if = "Option::is_none")]
683    pub description: Option<String>,
684    pub input_schema: ToolInputSchema,
685    #[serde(skip_serializing_if = "Option::is_none")]
686    pub output_schema: Option<Value>,
687    #[serde(skip_serializing_if = "Option::is_none")]
688    pub annotations: Option<ToolAnnotations>,
689
690    #[serde(flatten)]
691    pub extra: HashMap<String, Value>,
692}
693
694/// Describes the schema for a tool's input parameters.
695#[derive(Debug, Clone, Serialize, Deserialize)]
696#[serde(rename_all = "camelCase")]
697pub struct ToolInputSchema {
698    #[serde(rename = "type")]
699    pub type_: String, // typically "object"
700    #[serde(skip_serializing_if = "Option::is_none")]
701    pub properties: Option<HashMap<String, Value>>,
702    #[serde(skip_serializing_if = "Option::is_none")]
703    pub required: Option<Vec<String>>,
704}
705
706/// Parameters for enabling or adjusting server-side logging.
707#[derive(Debug, Clone, Serialize, Deserialize)]
708#[serde(rename_all = "camelCase")]
709pub struct SetLevelParams {
710    pub level: LoggingLevel,
711    #[serde(flatten)]
712    pub extra: HashMap<String, Value>,
713}
714
715/// Syslog-like logging severity levels.
716#[derive(Debug, Clone, Serialize, Deserialize)]
717#[serde(rename_all = "lowercase")]
718pub enum LoggingLevel {
719    Debug,
720    Info,
721    Notice,
722    Warning,
723    Error,
724    Critical,
725    Alert,
726    Emergency,
727}
728
729/// A notification with a log message from the server.
730#[derive(Debug, Clone, Serialize, Deserialize)]
731#[serde(rename_all = "camelCase")]
732pub struct LoggingMessageParams {
733    pub level: LoggingLevel,
734    #[serde(skip_serializing_if = "Option::is_none")]
735    pub logger: Option<String>,
736    pub data: Value,
737
738    #[serde(flatten)]
739    pub extra: HashMap<String, Value>,
740}
741
742/// Parameters for the `sampling/createMessage` method.
743#[derive(Debug, Clone, Serialize, Deserialize)]
744#[serde(rename_all = "camelCase")]
745pub struct CreateMessageParams {
746    pub messages: Vec<SamplingMessage>,
747    #[serde(skip_serializing_if = "Option::is_none")]
748    pub model_preferences: Option<ModelPreferences>,
749    #[serde(skip_serializing_if = "Option::is_none")]
750    pub system_prompt: Option<String>,
751    #[serde(skip_serializing_if = "Option::is_none")]
752    pub include_context: Option<String>, // "none" | "thisServer" | "allServers"
753    #[serde(skip_serializing_if = "Option::is_none")]
754    pub temperature: Option<f64>,
755    pub max_tokens: i64,
756    #[serde(skip_serializing_if = "Option::is_none")]
757    pub stop_sequences: Option<Vec<String>>,
758    #[serde(skip_serializing_if = "Option::is_none")]
759    pub metadata: Option<HashMap<String, Value>>,
760    #[serde(flatten)]
761    pub extra: HashMap<String, Value>,
762}
763
764/// A result from `sampling/createMessage`.
765#[derive(Debug, Clone, Serialize, Deserialize)]
766#[serde(rename_all = "camelCase")]
767pub struct CreateMessageResult {
768    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
769    pub meta: Option<HashMap<String, Value>>,
770    pub role: Role,
771    pub content: SamplingContent,
772    pub model: String,
773    #[serde(skip_serializing_if = "Option::is_none")]
774    pub stop_reason: Option<String>,
775    #[serde(flatten)]
776    pub extra: HashMap<String, Value>,
777}
778
779/// Represents a text or image message in sampling.
780#[derive(Debug, Clone, Serialize, Deserialize)]
781#[serde(untagged)]
782pub enum SamplingContent {
783    Text(TextContent),
784    Image(ImageContent),
785}
786
787/// A sampling message (one item in `CreateMessageParams`).
788#[derive(Debug, Clone, Serialize, Deserialize)]
789#[serde(rename_all = "camelCase")]
790pub struct SamplingMessage {
791    pub role: Role,
792    pub content: SamplingContent,
793}
794
795/// Preferences for selecting a model, including cost or speed priorities.
796#[derive(Debug, Clone, Serialize, Deserialize)]
797#[serde(rename_all = "camelCase")]
798pub struct ModelPreferences {
799    #[serde(skip_serializing_if = "Option::is_none")]
800    pub hints: Option<Vec<ModelHint>>,
801    #[serde(skip_serializing_if = "Option::is_none")]
802    pub cost_priority: Option<f64>,
803    #[serde(skip_serializing_if = "Option::is_none")]
804    pub speed_priority: Option<f64>,
805    #[serde(skip_serializing_if = "Option::is_none")]
806    pub intelligence_priority: Option<f64>,
807
808    #[serde(flatten)]
809    pub extra: HashMap<String, Value>,
810}
811
812/// A hint to use when selecting a model (e.g., substring matches).
813#[derive(Debug, Clone, Serialize, Deserialize)]
814#[serde(rename_all = "camelCase")]
815pub struct ModelHint {
816    #[serde(skip_serializing_if = "Option::is_none")]
817    pub name: Option<String>,
818    #[serde(flatten)]
819    pub extra: HashMap<String, Value>,
820}
821
822/// Parameters for `completion/complete`.
823#[derive(Debug, Clone, Serialize, Deserialize)]
824#[serde(rename_all = "camelCase")]
825pub struct CompleteParams {
826    #[serde(rename = "ref")]
827    pub r#ref: ReferenceType,
828    pub argument: CompleteArgument,
829    #[serde(flatten)]
830    pub extra: HashMap<String, Value>,
831}
832
833/// A result from `completion/complete`.
834#[derive(Debug, Clone, Serialize, Deserialize)]
835#[serde(rename_all = "camelCase")]
836pub struct CompleteResult {
837    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
838    pub meta: Option<HashMap<String, Value>>,
839    pub completion: CompletionData,
840    #[serde(flatten)]
841    pub extra: HashMap<String, Value>,
842}
843
844/// A reference to either a resource or a prompt.
845#[derive(Debug, Clone, Serialize, Deserialize)]
846#[serde(rename_all = "camelCase", tag = "type")]
847pub enum ReferenceType {
848    #[serde(rename = "ref/resource")]
849    Resource { uri: String },
850    #[serde(rename = "ref/prompt")]
851    Prompt { name: String },
852}
853
854/// An argument for `completion/complete` (name + value).
855#[derive(Debug, Clone, Serialize, Deserialize)]
856#[serde(rename_all = "camelCase")]
857pub struct CompleteArgument {
858    pub name: String,
859    pub value: String,
860    #[serde(flatten)]
861    pub extra: HashMap<String, Value>,
862}
863
864/// Data returned in the `completion` field, containing possible completions.
865#[derive(Debug, Clone, Serialize, Deserialize)]
866#[serde(rename_all = "camelCase")]
867pub struct CompletionData {
868    pub values: Vec<String>,
869    #[serde(skip_serializing_if = "Option::is_none")]
870    pub total: Option<i64>,
871    #[serde(skip_serializing_if = "Option::is_none")]
872    pub has_more: Option<bool>,
873}
874
875/// Parameters for `roots/list`.
876#[derive(Debug, Clone, Serialize, Deserialize, Default)]
877#[serde(rename_all = "camelCase")]
878pub struct ListRootsParams {
879    #[serde(flatten)]
880    pub extra: HashMap<String, Value>,
881}
882
883/// A result listing root URIs from the client.
884#[derive(Debug, Clone, Serialize, Deserialize)]
885#[serde(rename_all = "camelCase")]
886pub struct ListRootsResult {
887    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
888    pub meta: Option<HashMap<String, Value>>,
889    pub roots: Vec<Root>,
890    #[serde(flatten)]
891    pub extra: HashMap<String, Value>,
892}
893
894/// Represents a root directory or file, typically starting with `file://`.
895#[derive(Debug, Clone, Serialize, Deserialize)]
896#[serde(rename_all = "camelCase")]
897pub struct Root {
898    pub uri: String,
899    #[serde(skip_serializing_if = "Option::is_none")]
900    pub name: Option<String>,
901    #[serde(flatten)]
902    pub extra: HashMap<String, Value>,
903}
904
905/// Parameters for the elicitation/create request.
906#[derive(Debug, Clone, Serialize, Deserialize)]
907#[serde(rename_all = "camelCase")]
908pub struct ElicitationCreateParams {
909    /// The prompt message to display to the user.
910    pub message: String,
911    
912    /// A JSON Schema defining the structure of the expected user response.
913    pub requested_schema: Value,
914    
915    #[serde(flatten)]
916    pub extra: HashMap<String, Value>,
917}
918
919/// Result from the elicitation/create request.
920#[derive(Debug, Clone, Serialize, Deserialize)]
921#[serde(rename_all = "camelCase")]
922pub struct ElicitationCreateResult {
923    /// The action taken by the user.
924    pub action: ElicitationAction,
925    
926    /// The user's response conforming to the requested schema (if accepted).
927    #[serde(skip_serializing_if = "Option::is_none")]
928    pub content: Option<Value>,
929    
930    #[serde(flatten)]
931    pub extra: HashMap<String, Value>,
932}
933
934/// Possible actions for elicitation responses.
935#[derive(Debug, Clone, Serialize, Deserialize)]
936#[serde(rename_all = "lowercase")]
937pub enum ElicitationAction {
938    Accept,
939    Reject,
940    Cancel,
941}
942/// A union of all possible client requests. The `method` field identifies the variant.
943#[derive(Debug, Clone, Serialize, Deserialize)]
944#[serde(tag = "method", rename_all = "camelCase")]
945pub enum ClientRequest {
946    #[serde(rename = "ping")]
947    Ping {
948        #[serde(rename = "jsonrpc")]
949        json_rpc: String,
950        id: RequestId,
951        #[serde(default)]
952        params: PingParams,
953    },
954    #[serde(rename = "initialize")]
955    Initialize {
956        #[serde(rename = "jsonrpc")]
957        json_rpc: String,
958        id: RequestId,
959        params: InitializeParams,
960    },
961    #[serde(rename = "completion/complete")]
962    Complete {
963        #[serde(rename = "jsonrpc")]
964        json_rpc: String,
965        id: RequestId,
966        params: CompleteParams,
967    },
968    #[serde(rename = "logging/setLevel")]
969    SetLevel {
970        #[serde(rename = "jsonrpc")]
971        json_rpc: String,
972        id: RequestId,
973        params: SetLevelParams,
974    },
975    #[serde(rename = "prompts/get")]
976    GetPrompt {
977        #[serde(rename = "jsonrpc")]
978        json_rpc: String,
979        id: RequestId,
980        params: GetPromptParams,
981    },
982    #[serde(rename = "prompts/list")]
983    ListPrompts {
984        #[serde(rename = "jsonrpc")]
985        json_rpc: String,
986        id: RequestId,
987        #[serde(default)]
988        params: PaginatedParams,
989    },
990    #[serde(rename = "resources/list")]
991    ListResources {
992        #[serde(rename = "jsonrpc")]
993        json_rpc: String,
994        id: RequestId,
995        #[serde(default)]
996        params: PaginatedParams,
997    },
998    #[serde(rename = "resources/templates/list")]
999    ListResourceTemplates {
1000        #[serde(rename = "jsonrpc")]
1001        json_rpc: String,
1002        id: RequestId,
1003        #[serde(default)]
1004        params: PaginatedParams,
1005    },
1006    #[serde(rename = "resources/read")]
1007    ReadResource {
1008        #[serde(rename = "jsonrpc")]
1009        json_rpc: String,
1010        id: RequestId,
1011        params: ReadResourceParams,
1012    },
1013    #[serde(rename = "resources/subscribe")]
1014    Subscribe {
1015        #[serde(rename = "jsonrpc")]
1016        json_rpc: String,
1017        id: RequestId,
1018        params: SubscribeParams,
1019    },
1020    #[serde(rename = "resources/unsubscribe")]
1021    Unsubscribe {
1022        #[serde(rename = "jsonrpc")]
1023        json_rpc: String,
1024        id: RequestId,
1025        params: UnsubscribeParams,
1026    },
1027    #[serde(rename = "tools/call")]
1028    CallTool {
1029        #[serde(rename = "jsonrpc")]
1030        json_rpc: String,
1031        id: RequestId,
1032        params: CallToolParams,
1033    },
1034    #[serde(rename = "tools/list")]
1035    ListTools {
1036        #[serde(rename = "jsonrpc")]
1037        json_rpc: String,
1038        id: RequestId,
1039        #[serde(default)]
1040        params: PaginatedParams,
1041    },
1042    #[serde(rename = "elicitation/create")]
1043    ElicitationCreate {
1044        #[serde(rename = "jsonrpc")]
1045        json_rpc: String,
1046        id: RequestId,
1047        params: ElicitationCreateParams,
1048    },
1049}
1050
1051/// A union of all possible client notifications.
1052#[derive(Debug, Clone, Serialize, Deserialize)]
1053#[serde(tag = "method", rename_all = "camelCase")]
1054pub enum ClientNotification {
1055    #[serde(rename = "notifications/cancelled")]
1056    Cancelled {
1057        #[serde(rename = "jsonrpc")]
1058        json_rpc: String,
1059        params: CancelledNotificationParams,
1060    },
1061    #[serde(rename = "notifications/progress")]
1062    Progress {
1063        #[serde(rename = "jsonrpc")]
1064        json_rpc: String,
1065        params: ProgressNotificationParams,
1066    },
1067    #[serde(rename = "notifications/initialized")]
1068    Initialized {
1069        #[serde(rename = "jsonrpc")]
1070        json_rpc: String,
1071        #[serde(default)]
1072        params: MCPNotificationParams,
1073    },
1074    #[serde(rename = "notifications/roots/list_changed")]
1075    RootsListChanged {
1076        #[serde(rename = "jsonrpc")]
1077        json_rpc: String,
1078        #[serde(default)]
1079        params: MCPNotificationParams,
1080    },
1081}
1082
1083/// A union of possible server requests.
1084#[derive(Debug, Clone, Serialize, Deserialize)]
1085#[serde(tag = "method", rename_all = "camelCase")]
1086pub enum ServerRequest {
1087    #[serde(rename = "ping")]
1088    Ping {
1089        #[serde(rename = "jsonrpc")]
1090        json_rpc: String,
1091        id: RequestId,
1092        #[serde(default)]
1093        params: PingParams,
1094    },
1095    #[serde(rename = "sampling/createMessage")]
1096    CreateMessage {
1097        #[serde(rename = "jsonrpc")]
1098        json_rpc: String,
1099        id: RequestId,
1100        params: CreateMessageParams,
1101    },
1102    #[serde(rename = "roots/list")]
1103    ListRoots {
1104        #[serde(rename = "jsonrpc")]
1105        json_rpc: String,
1106        id: RequestId,
1107        #[serde(default)]
1108        params: ListRootsParams,
1109    },
1110}
1111
1112/// A union of possible server notifications.
1113#[derive(Debug, Clone, Serialize, Deserialize)]
1114#[serde(tag = "method", rename_all = "camelCase")]
1115pub enum ServerNotification {
1116    #[serde(rename = "notifications/cancelled")]
1117    Cancelled {
1118        #[serde(rename = "jsonrpc")]
1119        json_rpc: String,
1120        params: CancelledNotificationParams,
1121    },
1122    #[serde(rename = "notifications/progress")]
1123    Progress {
1124        #[serde(rename = "jsonrpc")]
1125        json_rpc: String,
1126        params: ProgressNotificationParams,
1127    },
1128    #[serde(rename = "notifications/message")]
1129    LoggingMessage {
1130        #[serde(rename = "jsonrpc")]
1131        json_rpc: String,
1132        params: LoggingMessageParams,
1133    },
1134    #[serde(rename = "notifications/resources/updated")]
1135    ResourceUpdated {
1136        #[serde(rename = "jsonrpc")]
1137        json_rpc: String,
1138        params: ResourceUpdatedParams,
1139    },
1140    #[serde(rename = "notifications/resources/list_changed")]
1141    ResourceListChanged {
1142        #[serde(rename = "jsonrpc")]
1143        json_rpc: String,
1144        #[serde(default)]
1145        params: MCPNotificationParams,
1146    },
1147    #[serde(rename = "notifications/tools/list_changed")]
1148    ToolListChanged {
1149        #[serde(rename = "jsonrpc")]
1150        json_rpc: String,
1151        #[serde(default)]
1152        params: MCPNotificationParams,
1153    },
1154    #[serde(rename = "notifications/prompts/list_changed")]
1155    PromptListChanged {
1156        #[serde(rename = "jsonrpc")]
1157        json_rpc: String,
1158        #[serde(default)]
1159        params: MCPNotificationParams,
1160    },
1161}
1162
1163/// A union of all possible server results.
1164#[derive(Debug, Clone, Serialize, Deserialize)]
1165#[serde(untagged)]
1166pub enum ServerResult {
1167    Empty(EmptyResult),
1168    Initialize(InitializeResult),
1169    Complete(CompleteResult),
1170    GetPrompt(GetPromptResult),
1171    ListPrompts(ListPromptsResult),
1172    ListResources(ListResourcesResult),
1173    ListResourceTemplates(ListResourceTemplatesResult),
1174    ReadResource(ReadResourceResult),
1175    CallTool(CallToolResult),
1176    ListTools(ListToolsResult),
1177    ElicitationCreate(ElicitationCreateResult),
1178}