Skip to main content

converge_mcp/
types.rs

1//! MCP protocol types.
2//!
3//! JSON-RPC request/response types and MCP-specific structures
4//! shared by both client and server implementations.
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// MCP protocol version.
10pub const MCP_PROTOCOL_VERSION: &str = "2024-11-05";
11
12/// MCP JSON-RPC request.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct JsonRpcRequest {
15    /// JSON-RPC version string (always `"2.0"`).
16    pub jsonrpc: String,
17    /// Request identifier; `None` for notifications.
18    pub id: Option<serde_json::Value>,
19    /// Method name to invoke.
20    pub method: String,
21    /// Optional method parameters.
22    #[serde(default)]
23    pub params: Option<serde_json::Value>,
24}
25
26/// MCP JSON-RPC response.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct JsonRpcResponse {
29    /// JSON-RPC version string (always `"2.0"`).
30    pub jsonrpc: String,
31    /// Mirrors the `id` from the originating request.
32    pub id: Option<serde_json::Value>,
33    /// Successful result payload; mutually exclusive with `error`.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub result: Option<serde_json::Value>,
36    /// Error payload; mutually exclusive with `result`.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub error: Option<JsonRpcError>,
39}
40
41impl JsonRpcResponse {
42    /// Build a successful response wrapping `result`.
43    pub fn success(id: Option<serde_json::Value>, result: serde_json::Value) -> Self {
44        Self {
45            jsonrpc: "2.0".to_string(),
46            id,
47            result: Some(result),
48            error: None,
49        }
50    }
51
52    /// Build an error response with the given `code` and `message`.
53    pub fn error(id: Option<serde_json::Value>, code: i32, message: String) -> Self {
54        Self {
55            jsonrpc: "2.0".to_string(),
56            id,
57            result: None,
58            error: Some(JsonRpcError {
59                code,
60                message,
61                data: None,
62            }),
63        }
64    }
65}
66
67/// MCP JSON-RPC error.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct JsonRpcError {
70    /// Numeric error code as defined by JSON-RPC / MCP.
71    pub code: i32,
72    /// Human-readable error description.
73    pub message: String,
74    /// Optional additional error data.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub data: Option<serde_json::Value>,
77}
78
79/// MCP server capabilities.
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct ServerCapabilities {
82    /// Tools capability advertised by the server.
83    pub tools: Option<ToolsCapability>,
84    /// Resources capability advertised by the server.
85    pub resources: Option<ResourcesCapability>,
86    /// Prompts capability advertised by the server.
87    pub prompts: Option<PromptsCapability>,
88}
89
90impl Default for ServerCapabilities {
91    fn default() -> Self {
92        Self {
93            tools: Some(ToolsCapability {}),
94            resources: Some(ResourcesCapability {
95                subscribe: Some(false),
96            }),
97            prompts: None,
98        }
99    }
100}
101
102/// Marker type indicating the server exposes tools.
103#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct ToolsCapability {}
105
106/// Marker type indicating the server exposes resources.
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ResourcesCapability {
109    /// Whether the server supports resource-change subscriptions.
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub subscribe: Option<bool>,
112}
113
114/// Marker type indicating the server exposes prompts.
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct PromptsCapability {}
117
118/// MCP server info.
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct ServerInfo {
121    /// Human-readable server name.
122    pub name: String,
123    /// Server version string.
124    pub version: String,
125}
126
127/// MCP initialize result.
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct InitializeResult {
130    /// MCP protocol version in use.
131    #[serde(rename = "protocolVersion")]
132    pub protocol_version: String,
133    /// Capabilities the server supports.
134    pub capabilities: ServerCapabilities,
135    /// Basic information about this server.
136    #[serde(rename = "serverInfo")]
137    pub server_info: ServerInfo,
138}
139
140/// MCP tool definition.
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct Tool {
143    /// Unique tool identifier.
144    pub name: String,
145    /// Human-readable description of the tool.
146    pub description: String,
147    /// JSON Schema describing the tool's input parameters.
148    #[serde(rename = "inputSchema")]
149    pub input_schema: serde_json::Value,
150}
151
152/// MCP tools list result.
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct ListToolsResult {
155    /// All tools available on this server.
156    pub tools: Vec<Tool>,
157}
158
159/// MCP tool call request.
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct CallToolRequest {
162    /// Name of the tool to invoke.
163    pub name: String,
164    /// Arguments to pass to the tool.
165    #[serde(default)]
166    pub arguments: HashMap<String, serde_json::Value>,
167}
168
169/// MCP tool call result.
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct CallToolResult {
172    /// Content items returned by the tool.
173    pub content: Vec<ToolContent>,
174    /// Set to `true` when the tool call produced an error.
175    #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
176    pub is_error: Option<bool>,
177}
178
179/// MCP tool content.
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(tag = "type")]
182pub enum ToolContent {
183    /// Plain-text content.
184    #[serde(rename = "text")]
185    Text {
186        /// The text payload.
187        text: String,
188    },
189    /// Base64-encoded image.
190    #[serde(rename = "image")]
191    Image {
192        /// Base64-encoded image data.
193        data: String,
194        /// MIME type of the image (e.g. `"image/png"`).
195        mime_type: String,
196    },
197    /// Embedded resource reference.
198    #[serde(rename = "resource")]
199    Resource {
200        /// The referenced resource content.
201        resource: ResourceContent,
202    },
203}
204
205/// MCP resource content.
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct ResourceContent {
208    /// URI identifying the resource.
209    pub uri: String,
210    /// MIME type of the content, if known.
211    #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
212    pub mime_type: Option<String>,
213    /// Text content of the resource, if applicable.
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub text: Option<String>,
216}
217
218/// MCP resource definition.
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct Resource {
221    /// URI that uniquely identifies this resource.
222    pub uri: String,
223    /// Human-readable resource name.
224    pub name: String,
225    /// Optional human-readable description.
226    #[serde(skip_serializing_if = "Option::is_none")]
227    pub description: Option<String>,
228    /// MIME type of the resource, if known.
229    #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
230    pub mime_type: Option<String>,
231}
232
233/// MCP resources list result.
234#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct ListResourcesResult {
236    /// All resources available on this server.
237    pub resources: Vec<Resource>,
238}
239
240/// MCP read resource request.
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct ReadResourceRequest {
243    /// URI of the resource to read.
244    pub uri: String,
245}
246
247/// MCP read resource result.
248#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct ReadResourceResult {
250    /// Content items that make up the resource.
251    pub contents: Vec<ResourceContent>,
252}