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)]
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    /// True if the tool call ended in an error.
648    #[serde(skip_serializing_if = "Option::is_none")]
649    pub is_error: Option<bool>,
650
651    #[serde(flatten)]
652    pub extra: HashMap<String, Value>,
653}
654
655/// Defines a tool that can be invoked by the client.
656#[derive(Debug, Clone, Serialize, Deserialize)]
657#[serde(rename_all = "camelCase")]
658pub struct Tool {
659    pub name: String,
660    #[serde(skip_serializing_if = "Option::is_none")]
661    pub description: Option<String>,
662    pub input_schema: ToolInputSchema,
663
664    #[serde(flatten)]
665    pub extra: HashMap<String, Value>,
666}
667
668/// Describes the schema for a tool's input parameters.
669#[derive(Debug, Clone, Serialize, Deserialize)]
670#[serde(rename_all = "camelCase")]
671pub struct ToolInputSchema {
672    #[serde(rename = "type")]
673    pub type_: String, // typically "object"
674    #[serde(skip_serializing_if = "Option::is_none")]
675    pub properties: Option<HashMap<String, Value>>,
676    #[serde(skip_serializing_if = "Option::is_none")]
677    pub required: Option<Vec<String>>,
678}
679
680/// Parameters for enabling or adjusting server-side logging.
681#[derive(Debug, Clone, Serialize, Deserialize)]
682#[serde(rename_all = "camelCase")]
683pub struct SetLevelParams {
684    pub level: LoggingLevel,
685    #[serde(flatten)]
686    pub extra: HashMap<String, Value>,
687}
688
689/// Syslog-like logging severity levels.
690#[derive(Debug, Clone, Serialize, Deserialize)]
691#[serde(rename_all = "lowercase")]
692pub enum LoggingLevel {
693    Debug,
694    Info,
695    Notice,
696    Warning,
697    Error,
698    Critical,
699    Alert,
700    Emergency,
701}
702
703/// A notification with a log message from the server.
704#[derive(Debug, Clone, Serialize, Deserialize)]
705#[serde(rename_all = "camelCase")]
706pub struct LoggingMessageParams {
707    pub level: LoggingLevel,
708    #[serde(skip_serializing_if = "Option::is_none")]
709    pub logger: Option<String>,
710    pub data: Value,
711
712    #[serde(flatten)]
713    pub extra: HashMap<String, Value>,
714}
715
716/// Parameters for the `sampling/createMessage` method.
717#[derive(Debug, Clone, Serialize, Deserialize)]
718#[serde(rename_all = "camelCase")]
719pub struct CreateMessageParams {
720    pub messages: Vec<SamplingMessage>,
721    #[serde(skip_serializing_if = "Option::is_none")]
722    pub model_preferences: Option<ModelPreferences>,
723    #[serde(skip_serializing_if = "Option::is_none")]
724    pub system_prompt: Option<String>,
725    #[serde(skip_serializing_if = "Option::is_none")]
726    pub include_context: Option<String>, // "none" | "thisServer" | "allServers"
727    #[serde(skip_serializing_if = "Option::is_none")]
728    pub temperature: Option<f64>,
729    pub max_tokens: i64,
730    #[serde(skip_serializing_if = "Option::is_none")]
731    pub stop_sequences: Option<Vec<String>>,
732    #[serde(skip_serializing_if = "Option::is_none")]
733    pub metadata: Option<HashMap<String, Value>>,
734    #[serde(flatten)]
735    pub extra: HashMap<String, Value>,
736}
737
738/// A result from `sampling/createMessage`.
739#[derive(Debug, Clone, Serialize, Deserialize)]
740#[serde(rename_all = "camelCase")]
741pub struct CreateMessageResult {
742    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
743    pub meta: Option<HashMap<String, Value>>,
744    pub role: Role,
745    pub content: SamplingContent,
746    pub model: String,
747    #[serde(skip_serializing_if = "Option::is_none")]
748    pub stop_reason: Option<String>,
749    #[serde(flatten)]
750    pub extra: HashMap<String, Value>,
751}
752
753/// Represents a text or image message in sampling.
754#[derive(Debug, Clone, Serialize, Deserialize)]
755#[serde(untagged)]
756pub enum SamplingContent {
757    Text(TextContent),
758    Image(ImageContent),
759}
760
761/// A sampling message (one item in `CreateMessageParams`).
762#[derive(Debug, Clone, Serialize, Deserialize)]
763#[serde(rename_all = "camelCase")]
764pub struct SamplingMessage {
765    pub role: Role,
766    pub content: SamplingContent,
767}
768
769/// Preferences for selecting a model, including cost or speed priorities.
770#[derive(Debug, Clone, Serialize, Deserialize)]
771#[serde(rename_all = "camelCase")]
772pub struct ModelPreferences {
773    #[serde(skip_serializing_if = "Option::is_none")]
774    pub hints: Option<Vec<ModelHint>>,
775    #[serde(skip_serializing_if = "Option::is_none")]
776    pub cost_priority: Option<f64>,
777    #[serde(skip_serializing_if = "Option::is_none")]
778    pub speed_priority: Option<f64>,
779    #[serde(skip_serializing_if = "Option::is_none")]
780    pub intelligence_priority: Option<f64>,
781
782    #[serde(flatten)]
783    pub extra: HashMap<String, Value>,
784}
785
786/// A hint to use when selecting a model (e.g., substring matches).
787#[derive(Debug, Clone, Serialize, Deserialize)]
788#[serde(rename_all = "camelCase")]
789pub struct ModelHint {
790    #[serde(skip_serializing_if = "Option::is_none")]
791    pub name: Option<String>,
792    #[serde(flatten)]
793    pub extra: HashMap<String, Value>,
794}
795
796/// Parameters for `completion/complete`.
797#[derive(Debug, Clone, Serialize, Deserialize)]
798#[serde(rename_all = "camelCase")]
799pub struct CompleteParams {
800    #[serde(rename = "ref")]
801    pub r#ref: ReferenceType,
802    pub argument: CompleteArgument,
803    #[serde(flatten)]
804    pub extra: HashMap<String, Value>,
805}
806
807/// A result from `completion/complete`.
808#[derive(Debug, Clone, Serialize, Deserialize)]
809#[serde(rename_all = "camelCase")]
810pub struct CompleteResult {
811    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
812    pub meta: Option<HashMap<String, Value>>,
813    pub completion: CompletionData,
814    #[serde(flatten)]
815    pub extra: HashMap<String, Value>,
816}
817
818/// A reference to either a resource or a prompt.
819#[derive(Debug, Clone, Serialize, Deserialize)]
820#[serde(rename_all = "camelCase", tag = "type")]
821pub enum ReferenceType {
822    #[serde(rename = "ref/resource")]
823    Resource { uri: String },
824    #[serde(rename = "ref/prompt")]
825    Prompt { name: String },
826}
827
828/// An argument for `completion/complete` (name + value).
829#[derive(Debug, Clone, Serialize, Deserialize)]
830#[serde(rename_all = "camelCase")]
831pub struct CompleteArgument {
832    pub name: String,
833    pub value: String,
834    #[serde(flatten)]
835    pub extra: HashMap<String, Value>,
836}
837
838/// Data returned in the `completion` field, containing possible completions.
839#[derive(Debug, Clone, Serialize, Deserialize)]
840#[serde(rename_all = "camelCase")]
841pub struct CompletionData {
842    pub values: Vec<String>,
843    #[serde(skip_serializing_if = "Option::is_none")]
844    pub total: Option<i64>,
845    #[serde(skip_serializing_if = "Option::is_none")]
846    pub has_more: Option<bool>,
847}
848
849/// Parameters for `roots/list`.
850#[derive(Debug, Clone, Serialize, Deserialize, Default)]
851#[serde(rename_all = "camelCase")]
852pub struct ListRootsParams {
853    #[serde(flatten)]
854    pub extra: HashMap<String, Value>,
855}
856
857/// A result listing root URIs from the client.
858#[derive(Debug, Clone, Serialize, Deserialize)]
859#[serde(rename_all = "camelCase")]
860pub struct ListRootsResult {
861    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
862    pub meta: Option<HashMap<String, Value>>,
863    pub roots: Vec<Root>,
864    #[serde(flatten)]
865    pub extra: HashMap<String, Value>,
866}
867
868/// Represents a root directory or file, typically starting with `file://`.
869#[derive(Debug, Clone, Serialize, Deserialize)]
870#[serde(rename_all = "camelCase")]
871pub struct Root {
872    pub uri: String,
873    #[serde(skip_serializing_if = "Option::is_none")]
874    pub name: Option<String>,
875    #[serde(flatten)]
876    pub extra: HashMap<String, Value>,
877}
878
879/// A union of all possible client requests. The `method` field identifies the variant.
880#[derive(Debug, Clone, Serialize, Deserialize)]
881#[serde(tag = "method", rename_all = "camelCase")]
882pub enum ClientRequest {
883    #[serde(rename = "ping")]
884    Ping {
885        #[serde(rename = "jsonrpc")]
886        json_rpc: String,
887        id: RequestId,
888        #[serde(default)]
889        params: PingParams,
890    },
891    #[serde(rename = "initialize")]
892    Initialize {
893        #[serde(rename = "jsonrpc")]
894        json_rpc: String,
895        id: RequestId,
896        params: InitializeParams,
897    },
898    #[serde(rename = "completion/complete")]
899    Complete {
900        #[serde(rename = "jsonrpc")]
901        json_rpc: String,
902        id: RequestId,
903        params: CompleteParams,
904    },
905    #[serde(rename = "logging/setLevel")]
906    SetLevel {
907        #[serde(rename = "jsonrpc")]
908        json_rpc: String,
909        id: RequestId,
910        params: SetLevelParams,
911    },
912    #[serde(rename = "prompts/get")]
913    GetPrompt {
914        #[serde(rename = "jsonrpc")]
915        json_rpc: String,
916        id: RequestId,
917        params: GetPromptParams,
918    },
919    #[serde(rename = "prompts/list")]
920    ListPrompts {
921        #[serde(rename = "jsonrpc")]
922        json_rpc: String,
923        id: RequestId,
924        params: PaginatedParams,
925    },
926    #[serde(rename = "resources/list")]
927    ListResources {
928        #[serde(rename = "jsonrpc")]
929        json_rpc: String,
930        id: RequestId,
931        params: PaginatedParams,
932    },
933    #[serde(rename = "resources/templates/list")]
934    ListResourceTemplates {
935        #[serde(rename = "jsonrpc")]
936        json_rpc: String,
937        id: RequestId,
938        params: PaginatedParams,
939    },
940    #[serde(rename = "resources/read")]
941    ReadResource {
942        #[serde(rename = "jsonrpc")]
943        json_rpc: String,
944        id: RequestId,
945        params: ReadResourceParams,
946    },
947    #[serde(rename = "resources/subscribe")]
948    Subscribe {
949        #[serde(rename = "jsonrpc")]
950        json_rpc: String,
951        id: RequestId,
952        params: SubscribeParams,
953    },
954    #[serde(rename = "resources/unsubscribe")]
955    Unsubscribe {
956        #[serde(rename = "jsonrpc")]
957        json_rpc: String,
958        id: RequestId,
959        params: UnsubscribeParams,
960    },
961    #[serde(rename = "tools/call")]
962    CallTool {
963        #[serde(rename = "jsonrpc")]
964        json_rpc: String,
965        id: RequestId,
966        params: CallToolParams,
967    },
968    #[serde(rename = "tools/list")]
969    ListTools {
970        #[serde(rename = "jsonrpc")]
971        json_rpc: String,
972        id: RequestId,
973        params: PaginatedParams,
974    },
975}
976
977/// A union of all possible client notifications.
978#[derive(Debug, Clone, Serialize, Deserialize)]
979#[serde(tag = "method", rename_all = "camelCase")]
980pub enum ClientNotification {
981    #[serde(rename = "notifications/cancelled")]
982    Cancelled {
983        #[serde(rename = "jsonrpc")]
984        json_rpc: String,
985        params: CancelledNotificationParams,
986    },
987    #[serde(rename = "notifications/progress")]
988    Progress {
989        #[serde(rename = "jsonrpc")]
990        json_rpc: String,
991        params: ProgressNotificationParams,
992    },
993    #[serde(rename = "notifications/initialized")]
994    Initialized {
995        #[serde(rename = "jsonrpc")]
996        json_rpc: String,
997        #[serde(default)]
998        params: MCPNotificationParams,
999    },
1000    #[serde(rename = "notifications/roots/list_changed")]
1001    RootsListChanged {
1002        #[serde(rename = "jsonrpc")]
1003        json_rpc: String,
1004        #[serde(default)]
1005        params: MCPNotificationParams,
1006    },
1007}
1008
1009/// A union of possible server requests.
1010#[derive(Debug, Clone, Serialize, Deserialize)]
1011#[serde(tag = "method", rename_all = "camelCase")]
1012pub enum ServerRequest {
1013    #[serde(rename = "ping")]
1014    Ping {
1015        #[serde(rename = "jsonrpc")]
1016        json_rpc: String,
1017        id: RequestId,
1018        #[serde(default)]
1019        params: PingParams,
1020    },
1021    #[serde(rename = "sampling/createMessage")]
1022    CreateMessage {
1023        #[serde(rename = "jsonrpc")]
1024        json_rpc: String,
1025        id: RequestId,
1026        params: CreateMessageParams,
1027    },
1028    #[serde(rename = "roots/list")]
1029    ListRoots {
1030        #[serde(rename = "jsonrpc")]
1031        json_rpc: String,
1032        id: RequestId,
1033        #[serde(default)]
1034        params: ListRootsParams,
1035    },
1036}
1037
1038/// A union of possible server notifications.
1039#[derive(Debug, Clone, Serialize, Deserialize)]
1040#[serde(tag = "method", rename_all = "camelCase")]
1041pub enum ServerNotification {
1042    #[serde(rename = "notifications/cancelled")]
1043    Cancelled {
1044        #[serde(rename = "jsonrpc")]
1045        json_rpc: String,
1046        params: CancelledNotificationParams,
1047    },
1048    #[serde(rename = "notifications/progress")]
1049    Progress {
1050        #[serde(rename = "jsonrpc")]
1051        json_rpc: String,
1052        params: ProgressNotificationParams,
1053    },
1054    #[serde(rename = "notifications/message")]
1055    LoggingMessage {
1056        #[serde(rename = "jsonrpc")]
1057        json_rpc: String,
1058        params: LoggingMessageParams,
1059    },
1060    #[serde(rename = "notifications/resources/updated")]
1061    ResourceUpdated {
1062        #[serde(rename = "jsonrpc")]
1063        json_rpc: String,
1064        params: ResourceUpdatedParams,
1065    },
1066    #[serde(rename = "notifications/resources/list_changed")]
1067    ResourceListChanged {
1068        #[serde(rename = "jsonrpc")]
1069        json_rpc: String,
1070        #[serde(default)]
1071        params: MCPNotificationParams,
1072    },
1073    #[serde(rename = "notifications/tools/list_changed")]
1074    ToolListChanged {
1075        #[serde(rename = "jsonrpc")]
1076        json_rpc: String,
1077        #[serde(default)]
1078        params: MCPNotificationParams,
1079    },
1080    #[serde(rename = "notifications/prompts/list_changed")]
1081    PromptListChanged {
1082        #[serde(rename = "jsonrpc")]
1083        json_rpc: String,
1084        #[serde(default)]
1085        params: MCPNotificationParams,
1086    },
1087}
1088
1089/// A union of all possible server results.
1090#[derive(Debug, Clone, Serialize, Deserialize)]
1091#[serde(untagged)]
1092pub enum ServerResult {
1093    Empty(EmptyResult),
1094    Initialize(InitializeResult),
1095    Complete(CompleteResult),
1096    GetPrompt(GetPromptResult),
1097    ListPrompts(ListPromptsResult),
1098    ListResources(ListResourcesResult),
1099    ListResourceTemplates(ListResourceTemplatesResult),
1100    ReadResource(ReadResourceResult),
1101    CallTool(CallToolResult),
1102    ListTools(ListToolsResult),
1103}