1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9pub const MCP_PROTOCOL_VERSION: &str = "2024-11-05";
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct JsonRpcRequest {
15 pub jsonrpc: String,
17 pub id: Option<serde_json::Value>,
19 pub method: String,
21 #[serde(default)]
23 pub params: Option<serde_json::Value>,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct JsonRpcResponse {
29 pub jsonrpc: String,
31 pub id: Option<serde_json::Value>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub result: Option<serde_json::Value>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub error: Option<JsonRpcError>,
39}
40
41impl JsonRpcResponse {
42 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 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#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct JsonRpcError {
70 pub code: i32,
72 pub message: String,
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub data: Option<serde_json::Value>,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct ServerCapabilities {
82 pub tools: Option<ToolsCapability>,
84 pub resources: Option<ResourcesCapability>,
86 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#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct ToolsCapability {}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ResourcesCapability {
109 #[serde(skip_serializing_if = "Option::is_none")]
111 pub subscribe: Option<bool>,
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct PromptsCapability {}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct ServerInfo {
121 pub name: String,
123 pub version: String,
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct InitializeResult {
130 #[serde(rename = "protocolVersion")]
132 pub protocol_version: String,
133 pub capabilities: ServerCapabilities,
135 #[serde(rename = "serverInfo")]
137 pub server_info: ServerInfo,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct Tool {
143 pub name: String,
145 pub description: String,
147 #[serde(rename = "inputSchema")]
149 pub input_schema: serde_json::Value,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct ListToolsResult {
155 pub tools: Vec<Tool>,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct CallToolRequest {
162 pub name: String,
164 #[serde(default)]
166 pub arguments: HashMap<String, serde_json::Value>,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct CallToolResult {
172 pub content: Vec<ToolContent>,
174 #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
176 pub is_error: Option<bool>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(tag = "type")]
182pub enum ToolContent {
183 #[serde(rename = "text")]
185 Text {
186 text: String,
188 },
189 #[serde(rename = "image")]
191 Image {
192 data: String,
194 mime_type: String,
196 },
197 #[serde(rename = "resource")]
199 Resource {
200 resource: ResourceContent,
202 },
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct ResourceContent {
208 pub uri: String,
210 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
212 pub mime_type: Option<String>,
213 #[serde(skip_serializing_if = "Option::is_none")]
215 pub text: Option<String>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct Resource {
221 pub uri: String,
223 pub name: String,
225 #[serde(skip_serializing_if = "Option::is_none")]
227 pub description: Option<String>,
228 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
230 pub mime_type: Option<String>,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct ListResourcesResult {
236 pub resources: Vec<Resource>,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct ReadResourceRequest {
243 pub uri: String,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct ReadResourceResult {
250 pub contents: Vec<ResourceContent>,
252}