1use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8pub const MCP_PROTOCOL_VERSION: &str = "2025-06-18";
10
11pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &["2024-11-05", "2025-06-18", "2025-11-25"];
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase")]
17pub struct InitializeParams {
18 pub protocol_version: String,
20 pub capabilities: ClientCapabilities,
22 pub client_info: ClientInfo,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct ClientCapabilities {
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub sampling: Option<Value>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ClientInfo {
38 pub name: String,
40 pub version: String,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct InitializeResult {
48 pub protocol_version: String,
50 pub capabilities: ServerCapabilities,
52 pub server_info: ServerInfo,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct ServerCapabilities {
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub tools: Option<ToolsCapability>,
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub resources: Option<ResourcesCapability>,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub prompts: Option<PromptsCapability>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct ToolsCapability {
75 #[serde(skip_serializing_if = "Option::is_none")]
77 pub list_changed: Option<bool>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(rename_all = "camelCase")]
83pub struct ResourcesCapability {
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub subscribe: Option<bool>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(rename_all = "camelCase")]
92pub struct PromptsCapability {
93 #[serde(skip_serializing_if = "Option::is_none")]
95 pub list_changed: Option<bool>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase")]
101pub struct ServerInfo {
102 pub name: String,
104 pub version: String,
106 #[serde(skip_serializing_if = "Option::is_none")]
108 pub metadata: Option<Value>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct Tool {
115 pub name: String,
117 pub description: String,
119 pub input_schema: Value,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct ToolsListResult {
126 pub tools: Vec<Tool>,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct ToolCallParams {
133 pub name: String,
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub arguments: Option<Value>,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct ToolCallResult {
143 pub content: Vec<ToolContent>,
145 #[serde(skip_serializing_if = "Option::is_none")]
147 pub is_error: Option<bool>,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(tag = "type")]
153#[serde(rename_all = "lowercase")]
154pub enum ToolContent {
155 Text { text: String },
157 Image { data: String, mime_type: String },
159 Resource { resource: Value },
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct Prompt {
167 pub name: String,
169 #[serde(skip_serializing_if = "Option::is_none")]
171 pub description: Option<String>,
172 #[serde(skip_serializing_if = "Option::is_none")]
174 pub arguments: Option<Vec<PromptArgument>>,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
179#[serde(rename_all = "camelCase")]
180pub struct PromptArgument {
181 pub name: String,
183 #[serde(skip_serializing_if = "Option::is_none")]
185 pub description: Option<String>,
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub required: Option<bool>,
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct PromptsListResult {
194 pub prompts: Vec<Prompt>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct PromptsGetParams {
201 pub name: String,
203 #[serde(skip_serializing_if = "Option::is_none")]
205 pub arguments: Option<Value>,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct PromptsGetResult {
211 #[serde(skip_serializing_if = "Option::is_none")]
213 pub description: Option<String>,
214 pub messages: Vec<PromptMessage>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct PromptMessage {
222 pub role: String,
224 pub content: PromptMessageContent,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(rename_all = "camelCase")]
231pub struct PromptMessageContent {
232 #[serde(rename = "type")]
234 pub content_type: String,
235 pub text: String,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize)]
241#[serde(rename_all = "camelCase")]
242pub struct Resource {
243 pub uri: String,
245 pub name: String,
247 #[serde(skip_serializing_if = "Option::is_none")]
249 pub description: Option<String>,
250 #[serde(skip_serializing_if = "Option::is_none")]
252 pub mime_type: Option<String>,
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct ResourcesListResult {
258 pub resources: Vec<Resource>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct ResourceReadParams {
265 pub uri: String,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
271pub struct ResourceReadResult {
272 pub contents: Vec<ResourceContent>,
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct ResourceContent {
280 pub uri: String,
282 #[serde(skip_serializing_if = "Option::is_none")]
284 pub mime_type: Option<String>,
285 #[serde(skip_serializing_if = "Option::is_none")]
287 pub text: Option<String>,
288 #[serde(skip_serializing_if = "Option::is_none")]
290 pub blob: Option<String>,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct Notification {
300 pub jsonrpc: String,
302 pub method: String,
304 #[serde(skip_serializing_if = "Option::is_none")]
306 pub params: Option<Value>,
307}
308
309impl Notification {
310 pub fn new(method: impl Into<String>, params: Option<Value>) -> Self {
312 Self {
313 jsonrpc: "2.0".to_string(),
314 method: method.into(),
315 params,
316 }
317 }
318
319 pub fn initialized() -> Self {
321 Self::new("notifications/initialized", None)
322 }
323}
324
325