Skip to main content

qudag_mcp/
types.rs

1//! Core types for the QuDAG MCP implementation.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// MCP request type
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct McpRequest {
9    /// JSON-RPC version
10    pub jsonrpc: String,
11    /// Request ID
12    pub id: serde_json::Value,
13    /// Method name
14    pub method: String,
15    /// Parameters
16    pub params: Option<serde_json::Value>,
17}
18
19/// MCP response type
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct McpResponse {
22    /// JSON-RPC version
23    pub jsonrpc: String,
24    /// Request ID
25    pub id: serde_json::Value,
26    /// Result (if successful)
27    pub result: Option<serde_json::Value>,
28    /// Error (if failed)
29    pub error: Option<serde_json::Value>,
30}
31
32/// MCP resource type
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct McpResource {
35    /// Resource URI
36    pub uri: String,
37    /// Resource name
38    pub name: String,
39    /// Resource description
40    pub description: Option<String>,
41    /// MIME type
42    pub mime_type: Option<String>,
43}
44
45/// MCP tool type
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct McpTool {
48    /// Tool name
49    pub name: String,
50    /// Tool description
51    pub description: String,
52    /// Input schema
53    pub input_schema: serde_json::Value,
54}
55
56/// MCP event type
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct McpEvent {
59    /// Event type
60    pub event_type: String,
61    /// Event data
62    pub data: serde_json::Value,
63    /// Timestamp
64    pub timestamp: u64,
65}
66
67/// Resource type enumeration
68#[derive(Debug, Clone, PartialEq, Eq)]
69pub enum ResourceType {
70    /// DAG resource
71    Dag,
72    /// Vault resource
73    Vault,
74    /// Network resource
75    Network,
76    /// Crypto resource
77    Crypto,
78}
79
80/// Tool type enumeration
81#[derive(Debug, Clone, PartialEq, Eq)]
82pub enum ToolType {
83    /// DAG tool
84    Dag,
85    /// Vault tool
86    Vault,
87    /// Network tool
88    Network,
89    /// Crypto tool
90    Crypto,
91}
92
93/// Event type enumeration
94#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
95pub enum EventType {
96    /// System event
97    System,
98    /// Security event
99    Security,
100    /// Network event
101    Network,
102    /// DAG event
103    Dag,
104}
105
106/// Server information
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ServerInfo {
109    /// Server name
110    pub name: String,
111    /// Server version
112    pub version: String,
113}
114
115impl ServerInfo {
116    /// Create new server info
117    pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
118        Self {
119            name: name.into(),
120            version: version.into(),
121        }
122    }
123}
124
125impl Default for ServerInfo {
126    fn default() -> Self {
127        Self {
128            name: "QuDAG MCP Server".to_string(),
129            version: env!("CARGO_PKG_VERSION").to_string(),
130        }
131    }
132}
133
134/// Server capabilities
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ServerCapabilities {
137    /// Supported tools
138    pub tools: Option<serde_json::Value>,
139    /// Supported resources
140    pub resources: Option<serde_json::Value>,
141    /// Supported prompts
142    pub prompts: Option<serde_json::Value>,
143    /// Experimental features
144    pub experimental: Option<HashMap<String, serde_json::Value>>,
145}
146
147impl Default for ServerCapabilities {
148    fn default() -> Self {
149        Self {
150            tools: Some(serde_json::json!({
151                "listChanged": true
152            })),
153            resources: Some(serde_json::json!({
154                "subscribe": true,
155                "listChanged": true
156            })),
157            prompts: Some(serde_json::json!({
158                "listChanged": true
159            })),
160            experimental: Some(HashMap::new()),
161        }
162    }
163}
164
165/// Client information
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct ClientInfo {
168    /// Client name
169    pub name: String,
170    /// Client version
171    pub version: String,
172}
173
174impl ClientInfo {
175    /// Create new client info
176    pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
177        Self {
178            name: name.into(),
179            version: version.into(),
180        }
181    }
182}
183
184/// Tool definition
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct Tool {
187    /// Tool name
188    pub name: String,
189    /// Tool description
190    pub description: String,
191    /// Input schema
192    #[serde(rename = "inputSchema")]
193    pub input_schema: serde_json::Value,
194}
195
196/// Tool result
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct ToolResult {
199    /// Result content
200    pub content: Vec<ToolResultContent>,
201    /// Whether this is an error
202    #[serde(rename = "isError")]
203    pub is_error: Option<bool>,
204}
205
206/// Tool result content
207#[derive(Debug, Clone, Serialize, Deserialize)]
208#[serde(tag = "type")]
209pub enum ToolResultContent {
210    /// Text content
211    #[serde(rename = "text")]
212    Text { text: String },
213    /// Image content
214    #[serde(rename = "image")]
215    Image {
216        data: String,
217        #[serde(rename = "mimeType")]
218        mime_type: String,
219    },
220    /// Resource content
221    #[serde(rename = "resource")]
222    Resource { resource: McpResource },
223}
224
225/// Resource definition
226#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct Resource {
228    /// Resource URI
229    pub uri: String,
230    /// Resource name
231    pub name: String,
232    /// Resource description
233    pub description: Option<String>,
234    /// MIME type
235    pub mime_type: Option<String>,
236}
237
238/// Resource content
239#[derive(Debug, Clone, Serialize, Deserialize)]
240pub struct ResourceContent {
241    /// Resource URI
242    pub uri: String,
243    /// MIME type
244    pub mime_type: Option<String>,
245    /// Text content
246    pub text: Option<String>,
247    /// Binary data (base64 encoded)
248    pub blob: Option<String>,
249}
250
251/// Prompt definition
252#[derive(Debug, Clone, Serialize, Deserialize)]
253pub struct Prompt {
254    /// Prompt name
255    pub name: String,
256    /// Prompt description
257    pub description: Option<String>,
258    /// Prompt arguments
259    pub arguments: Option<Vec<PromptArgument>>,
260}
261
262impl Prompt {
263    /// Create a new prompt
264    pub fn new(name: impl Into<String>) -> Self {
265        Self {
266            name: name.into(),
267            description: None,
268            arguments: None,
269        }
270    }
271
272    /// Set the prompt description
273    pub fn with_description(mut self, description: impl Into<String>) -> Self {
274        self.description = Some(description.into());
275        self
276    }
277
278    /// Set the prompt arguments
279    pub fn with_arguments(mut self, arguments: Vec<PromptArgument>) -> Self {
280        self.arguments = Some(arguments);
281        self
282    }
283}
284
285/// Prompt argument
286#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct PromptArgument {
288    /// Argument name
289    pub name: String,
290    /// Argument description
291    pub description: Option<String>,
292    /// Whether argument is required
293    pub required: Option<bool>,
294}
295
296impl PromptArgument {
297    /// Create a new prompt argument
298    pub fn new(name: impl Into<String>) -> Self {
299        Self {
300            name: name.into(),
301            description: None,
302            required: None,
303        }
304    }
305
306    /// Mark this argument as required
307    pub fn required(mut self) -> Self {
308        self.required = Some(true);
309        self
310    }
311
312    /// Mark this argument as optional
313    pub fn optional(mut self) -> Self {
314        self.required = Some(false);
315        self
316    }
317
318    /// Set the argument description
319    pub fn with_description(mut self, description: impl Into<String>) -> Self {
320        self.description = Some(description.into());
321        self
322    }
323}
324
325/// Prompt message
326#[derive(Debug, Clone, Serialize, Deserialize)]
327pub struct PromptMessage {
328    /// Message role
329    pub role: MessageRole,
330    /// Message content
331    pub content: MessageContent,
332}
333
334/// Message role
335#[derive(Debug, Clone, Serialize, Deserialize)]
336pub enum MessageRole {
337    /// User message
338    #[serde(rename = "user")]
339    User,
340    /// Assistant message
341    #[serde(rename = "assistant")]
342    Assistant,
343    /// System message
344    #[serde(rename = "system")]
345    System,
346}
347
348/// Message content
349#[derive(Debug, Clone, Serialize, Deserialize)]
350#[serde(tag = "type")]
351pub enum MessageContent {
352    /// Text content
353    #[serde(rename = "text")]
354    Text { text: String },
355    /// Image content
356    #[serde(rename = "image")]
357    Image {
358        data: String,
359        #[serde(rename = "mimeType")]
360        mime_type: String,
361    },
362}
363
364/// Resource URI helper
365#[derive(Debug, Clone, PartialEq, Eq, Hash)]
366pub struct ResourceURI(pub String);
367
368impl ResourceURI {
369    /// Create new resource URI
370    pub fn new(uri: impl Into<String>) -> Self {
371        Self(uri.into())
372    }
373
374    /// Create DAG resource URI
375    pub fn dag(path: &str) -> Self {
376        Self(format!("dag://{}", path))
377    }
378
379    /// Create vault resource URI
380    pub fn vault(path: &str) -> Self {
381        Self(format!("vault://{}", path))
382    }
383
384    /// Create network resource URI
385    pub fn network(path: &str) -> Self {
386        Self(format!("network://{}", path))
387    }
388
389    /// Create crypto resource URI
390    pub fn crypto(path: &str) -> Self {
391        Self(format!("crypto://{}", path))
392    }
393
394    /// Get the URI string
395    pub fn as_str(&self) -> &str {
396        &self.0
397    }
398}
399
400impl std::fmt::Display for ResourceURI {
401    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
402        write!(f, "{}", self.0)
403    }
404}
405
406impl From<String> for ResourceURI {
407    fn from(uri: String) -> Self {
408        Self(uri)
409    }
410}
411
412impl From<&str> for ResourceURI {
413    fn from(uri: &str) -> Self {
414        Self(uri.to_string())
415    }
416}
417
418/// Tool name helper
419#[derive(Debug, Clone, PartialEq, Eq, Hash)]
420pub struct ToolName(pub String);
421
422impl ToolName {
423    /// Create new tool name
424    pub fn new(name: impl Into<String>) -> Self {
425        Self(name.into())
426    }
427
428    /// Get the name string
429    pub fn as_str(&self) -> &str {
430        &self.0
431    }
432}
433
434impl std::fmt::Display for ToolName {
435    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
436        write!(f, "{}", self.0)
437    }
438}
439
440impl From<String> for ToolName {
441    fn from(name: String) -> Self {
442        Self(name)
443    }
444}
445
446impl From<&str> for ToolName {
447    fn from(name: &str) -> Self {
448        Self(name.to_string())
449    }
450}
451
452/// Prompt name helper
453#[derive(Debug, Clone, PartialEq, Eq, Hash)]
454pub struct PromptName(pub String);
455
456impl PromptName {
457    /// Create new prompt name
458    pub fn new(name: impl Into<String>) -> Self {
459        Self(name.into())
460    }
461
462    /// Get the name string
463    pub fn as_str(&self) -> &str {
464        &self.0
465    }
466}
467
468impl std::fmt::Display for PromptName {
469    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
470        write!(f, "{}", self.0)
471    }
472}
473
474impl From<String> for PromptName {
475    fn from(name: String) -> Self {
476        Self(name)
477    }
478}
479
480impl From<&str> for PromptName {
481    fn from(name: &str) -> Self {
482        Self(name.to_string())
483    }
484}