Skip to main content

aimdb_mcp/protocol/
mcp.rs

1//! MCP protocol-specific types
2//!
3//! Model Context Protocol version 2025-06-18
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// MCP protocol version (preferred)
9pub const MCP_PROTOCOL_VERSION: &str = "2025-06-18";
10
11/// Supported MCP protocol versions
12pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &["2024-11-05", "2025-06-18", "2025-11-25"];
13
14/// Initialize request parameters
15#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase")]
17pub struct InitializeParams {
18    /// Protocol version requested by client
19    pub protocol_version: String,
20    /// Client capabilities
21    pub capabilities: ClientCapabilities,
22    /// Client info
23    pub client_info: ClientInfo,
24}
25
26/// Client capabilities
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct ClientCapabilities {
30    /// Sampling capability (optional)
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub sampling: Option<Value>,
33}
34
35/// Client info
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ClientInfo {
38    /// Client name
39    pub name: String,
40    /// Client version
41    pub version: String,
42}
43
44/// Initialize response result
45#[derive(Debug, Clone, Serialize, Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct InitializeResult {
48    /// Protocol version supported by server
49    pub protocol_version: String,
50    /// Server capabilities
51    pub capabilities: ServerCapabilities,
52    /// Server info
53    pub server_info: ServerInfo,
54}
55
56/// Server capabilities
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct ServerCapabilities {
60    /// Tools capability (optional)
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub tools: Option<ToolsCapability>,
63    /// Resources capability (optional)
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub resources: Option<ResourcesCapability>,
66    /// Prompts capability (optional)
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub prompts: Option<PromptsCapability>,
69}
70
71/// Tools capability
72#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct ToolsCapability {
75    /// Whether the tool list can change
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub list_changed: Option<bool>,
78}
79
80/// Resources capability
81#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(rename_all = "camelCase")]
83pub struct ResourcesCapability {
84    /// Whether subscriptions are supported
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub subscribe: Option<bool>,
87}
88
89/// Prompts capability
90#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(rename_all = "camelCase")]
92pub struct PromptsCapability {
93    /// Whether the prompt list can change
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub list_changed: Option<bool>,
96}
97
98/// Server info
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase")]
101pub struct ServerInfo {
102    /// Server name
103    pub name: String,
104    /// Server version
105    pub version: String,
106    /// Optional metadata (custom server-specific information)
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub metadata: Option<Value>,
109}
110
111/// Tool definition
112#[derive(Debug, Clone, Serialize, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct Tool {
115    /// Tool name
116    pub name: String,
117    /// Tool description
118    pub description: String,
119    /// Input schema (JSON Schema)
120    pub input_schema: Value,
121}
122
123/// Tools list result
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct ToolsListResult {
126    /// Available tools
127    pub tools: Vec<Tool>,
128}
129
130/// Tool call parameters
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct ToolCallParams {
133    /// Tool name
134    pub name: String,
135    /// Tool arguments (optional)
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub arguments: Option<Value>,
138}
139
140/// Tool call result
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct ToolCallResult {
143    /// Tool execution result content
144    pub content: Vec<ToolContent>,
145    /// Whether the tool call failed
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub is_error: Option<bool>,
148}
149
150/// Tool content item
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(tag = "type")]
153#[serde(rename_all = "lowercase")]
154pub enum ToolContent {
155    /// Text content
156    Text { text: String },
157    /// Image content (not used in aimdb-mcp)
158    Image { data: String, mime_type: String },
159    /// Resource content (not used in aimdb-mcp)
160    Resource { resource: Value },
161}
162
163/// Prompt definition
164#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct Prompt {
167    /// Prompt name (unique identifier)
168    pub name: String,
169    /// Prompt description (human-readable)
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub description: Option<String>,
172    /// Optional arguments schema
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub arguments: Option<Vec<PromptArgument>>,
175}
176
177/// Prompt argument definition
178#[derive(Debug, Clone, Serialize, Deserialize)]
179#[serde(rename_all = "camelCase")]
180pub struct PromptArgument {
181    /// Argument name
182    pub name: String,
183    /// Argument description
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub description: Option<String>,
186    /// Whether this argument is required
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub required: Option<bool>,
189}
190
191/// Prompts list result
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct PromptsListResult {
194    /// Available prompts
195    pub prompts: Vec<Prompt>,
196}
197
198/// Prompts get parameters
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct PromptsGetParams {
201    /// Prompt name to retrieve
202    pub name: String,
203    /// Optional arguments for the prompt
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub arguments: Option<Value>,
206}
207
208/// Prompts get result
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct PromptsGetResult {
211    /// Prompt description (optional)
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub description: Option<String>,
214    /// Prompt messages
215    pub messages: Vec<PromptMessage>,
216}
217
218/// Prompt message
219#[derive(Debug, Clone, Serialize, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct PromptMessage {
222    /// Message role (user, assistant, system)
223    pub role: String,
224    /// Message content
225    pub content: PromptMessageContent,
226}
227
228/// Prompt message content
229#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(rename_all = "camelCase")]
231pub struct PromptMessageContent {
232    /// Content type (always "text" for now)
233    #[serde(rename = "type")]
234    pub content_type: String,
235    /// Text content
236    pub text: String,
237}
238
239/// Resource definition
240#[derive(Debug, Clone, Serialize, Deserialize)]
241#[serde(rename_all = "camelCase")]
242pub struct Resource {
243    /// Resource URI
244    pub uri: String,
245    /// Resource name (human-readable)
246    pub name: String,
247    /// Resource description (optional)
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub description: Option<String>,
250    /// MIME type (optional)
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub mime_type: Option<String>,
253}
254
255/// Resources list result
256#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct ResourcesListResult {
258    /// Available resources
259    pub resources: Vec<Resource>,
260}
261
262/// Resource read parameters
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct ResourceReadParams {
265    /// Resource URI to read
266    pub uri: String,
267}
268
269/// Resource read result
270#[derive(Debug, Clone, Serialize, Deserialize)]
271pub struct ResourceReadResult {
272    /// Resource contents
273    pub contents: Vec<ResourceContent>,
274}
275
276/// Resource content item
277#[derive(Debug, Clone, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct ResourceContent {
280    /// Resource URI
281    pub uri: String,
282    /// MIME type (optional)
283    #[serde(skip_serializing_if = "Option::is_none")]
284    pub mime_type: Option<String>,
285    /// Text content (optional)
286    #[serde(skip_serializing_if = "Option::is_none")]
287    pub text: Option<String>,
288    /// Binary content as base64 (optional)
289    #[serde(skip_serializing_if = "Option::is_none")]
290    pub blob: Option<String>,
291}
292
293// ============================================================================
294// Notifications
295// ============================================================================
296
297/// Notification message (server -> client)
298#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct Notification {
300    /// JSON-RPC version
301    pub jsonrpc: String,
302    /// Notification method
303    pub method: String,
304    /// Notification parameters
305    #[serde(skip_serializing_if = "Option::is_none")]
306    pub params: Option<Value>,
307}
308
309impl Notification {
310    /// Create a new notification
311    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    /// Create a notification for initialized event
320    pub fn initialized() -> Self {
321        Self::new("notifications/initialized", None)
322    }
323}
324
325// ============================================================================
326// Resource Read Support
327// ============================================================================