Skip to main content

myko_server/mcp/
types.rs

1//! MCP protocol types for JSON-RPC communication.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// MCP JSON-RPC request.
7#[derive(Debug, Deserialize)]
8pub struct McpRequest {
9    pub jsonrpc: String,
10    pub id: Value,
11    pub method: String,
12    #[serde(default)]
13    pub params: Option<Value>,
14}
15
16/// MCP JSON-RPC response.
17#[derive(Debug, Serialize)]
18pub struct McpResponse {
19    pub jsonrpc: String,
20    pub id: Value,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub result: Option<Value>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub error: Option<McpError>,
25}
26
27impl McpResponse {
28    /// Create a success response.
29    pub fn success(id: Value, result: Value) -> Self {
30        Self {
31            jsonrpc: "2.0".to_string(),
32            id,
33            result: Some(result),
34            error: None,
35        }
36    }
37
38    /// Create an error response.
39    pub fn error(id: Value, error: McpError) -> Self {
40        Self {
41            jsonrpc: "2.0".to_string(),
42            id,
43            result: None,
44            error: Some(error),
45        }
46    }
47}
48
49/// MCP JSON-RPC error.
50#[derive(Debug, Serialize)]
51pub struct McpError {
52    pub code: i32,
53    pub message: String,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub data: Option<Value>,
56}
57
58impl McpError {
59    /// Standard error codes
60    pub const PARSE_ERROR: i32 = -32700;
61    pub const INVALID_REQUEST: i32 = -32600;
62    pub const METHOD_NOT_FOUND: i32 = -32601;
63    pub const INVALID_PARAMS: i32 = -32602;
64    pub const INTERNAL_ERROR: i32 = -32603;
65
66    pub fn parse_error(msg: impl Into<String>) -> Self {
67        Self {
68            code: Self::PARSE_ERROR,
69            message: msg.into(),
70            data: None,
71        }
72    }
73
74    pub fn method_not_found(method: &str) -> Self {
75        Self {
76            code: Self::METHOD_NOT_FOUND,
77            message: format!("Method not found: {}", method),
78            data: None,
79        }
80    }
81
82    pub fn invalid_params(msg: impl Into<String>) -> Self {
83        Self {
84            code: Self::INVALID_PARAMS,
85            message: msg.into(),
86            data: None,
87        }
88    }
89
90    pub fn internal_error(msg: impl Into<String>) -> Self {
91        Self {
92            code: Self::INTERNAL_ERROR,
93            message: msg.into(),
94            data: None,
95        }
96    }
97}
98
99/// MCP tool definition.
100#[derive(Debug, Clone, Serialize)]
101pub struct McpTool {
102    pub name: String,
103    pub description: String,
104    #[serde(rename = "inputSchema")]
105    pub input_schema: Value,
106}
107
108/// MCP resource definition.
109#[derive(Debug, Clone, Serialize)]
110pub struct McpResource {
111    pub uri: String,
112    pub name: String,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub description: Option<String>,
115    #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
116    pub mime_type: Option<String>,
117}
118
119/// MCP resource contents.
120#[derive(Debug, Clone, Serialize)]
121pub struct McpResourceContents {
122    pub uri: String,
123    #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
124    pub mime_type: Option<String>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub text: Option<String>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub blob: Option<String>,
129}
130
131/// MCP tool call result content.
132#[derive(Debug, Clone, Serialize)]
133pub struct McpToolContent {
134    #[serde(rename = "type")]
135    pub content_type: String,
136    pub text: String,
137}
138
139impl McpToolContent {
140    pub fn text(text: impl Into<String>) -> Self {
141        Self {
142            content_type: "text".to_string(),
143            text: text.into(),
144        }
145    }
146}
147
148/// MCP server capabilities.
149#[derive(Debug, Clone, Serialize, Default)]
150pub struct McpCapabilities {
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub tools: Option<Value>,
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub resources: Option<Value>,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub prompts: Option<Value>,
157}
158
159/// MCP server info.
160#[derive(Debug, Clone, Serialize)]
161pub struct McpServerInfo {
162    pub name: String,
163    pub version: String,
164}