Skip to main content

ai_agent/services/mcp/
types.rs

1// Source: /data/home/swei/claudecode/openclaudecode/src/services/mcp/types.ts
2//! MCP types and configurations
3
4use serde::{Deserialize, Serialize};
5
6/// Configuration scope for MCP servers
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
8#[serde(rename_all = "lowercase")]
9pub enum ConfigScope {
10    Local,
11    User,
12    Project,
13    Dynamic,
14    Enterprise,
15    ClaudeAi,
16    Managed,
17}
18
19impl Default for ConfigScope {
20    fn default() -> Self {
21        Self::Local
22    }
23}
24
25/// Transport type for MCP server connections
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
27#[serde(rename_all = "kebab-case")]
28pub enum Transport {
29    Stdio,
30    Sse,
31    SseIde,
32    Http,
33    Ws,
34    Sdk,
35}
36
37/// MCP stdio server configuration
38#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(rename_all = "camelCase")]
40pub struct McpStdioServerConfig {
41    #[serde(rename = "type", default)]
42    pub config_type: Option<String>,
43    pub command: String,
44    #[serde(default)]
45    pub args: Vec<String>,
46    #[serde(default)]
47    pub env: Option<std::collections::HashMap<String, String>>,
48}
49
50/// MCP OAuth configuration
51#[derive(Debug, Clone, Serialize, Deserialize)]
52#[serde(rename_all = "camelCase")]
53pub struct McpOAuthConfig {
54    #[serde(default)]
55    pub client_id: Option<String>,
56    #[serde(default)]
57    pub callback_port: Option<u16>,
58    #[serde(default)]
59    pub auth_server_metadata_url: Option<String>,
60    #[serde(default)]
61    pub xaa: Option<bool>,
62}
63
64/// MCP SSE server configuration
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(rename_all = "camelCase")]
67pub struct McpSseServerConfig {
68    #[serde(rename = "type")]
69    pub config_type: String,
70    pub url: String,
71    #[serde(default)]
72    pub headers: Option<std::collections::HashMap<String, String>>,
73    #[serde(default)]
74    pub headers_helper: Option<String>,
75    #[serde(default)]
76    pub oauth: Option<McpOAuthConfig>,
77}
78
79/// MCP SSE IDE server configuration (internal use for IDE extensions)
80#[derive(Debug, Clone, Serialize, Deserialize)]
81#[serde(rename_all = "camelCase")]
82pub struct McpSseIdeServerConfig {
83    #[serde(rename = "type")]
84    pub config_type: String,
85    pub url: String,
86    pub ide_name: String,
87    #[serde(default)]
88    pub ide_running_in_windows: Option<bool>,
89}
90
91/// MCP WebSocket IDE server configuration (internal use for IDE extensions)
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct McpWebSocketIdeServerConfig {
95    #[serde(rename = "type")]
96    pub config_type: String,
97    pub url: String,
98    pub ide_name: String,
99    #[serde(default)]
100    pub auth_token: Option<String>,
101    #[serde(default)]
102    pub ide_running_in_windows: Option<bool>,
103}
104
105/// MCP HTTP server configuration
106#[derive(Debug, Clone, Serialize, Deserialize)]
107#[serde(rename_all = "camelCase")]
108pub struct McpHttpServerConfig {
109    #[serde(rename = "type")]
110    pub config_type: String,
111    pub url: String,
112    #[serde(default)]
113    pub headers: Option<std::collections::HashMap<String, String>>,
114    #[serde(default)]
115    pub headers_helper: Option<String>,
116    #[serde(default)]
117    pub oauth: Option<McpOAuthConfig>,
118}
119
120/// MCP WebSocket server configuration
121#[derive(Debug, Clone, Serialize, Deserialize)]
122#[serde(rename_all = "camelCase")]
123pub struct McpWebSocketServerConfig {
124    #[serde(rename = "type")]
125    pub config_type: String,
126    pub url: String,
127    #[serde(default)]
128    pub headers: Option<std::collections::HashMap<String, String>>,
129    #[serde(default)]
130    pub headers_helper: Option<String>,
131}
132
133/// MCP SDK server configuration (internal use)
134#[derive(Debug, Clone, Serialize, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct McpSdkServerConfig {
137    #[serde(rename = "type")]
138    pub config_type: String,
139    pub name: String,
140}
141
142/// MCP Claude.ai proxy server configuration (internal use)
143#[derive(Debug, Clone, Serialize, Deserialize)]
144#[serde(rename_all = "camelCase")]
145pub struct McpClaudeAiProxyServerConfig {
146    #[serde(rename = "type")]
147    pub config_type: String,
148    pub url: String,
149    pub id: String,
150}
151
152/// MCP server configuration (discriminated union)
153#[derive(Debug, Clone, Serialize, Deserialize)]
154#[serde(untagged)]
155pub enum McpServerConfig {
156    Stdio(McpStdioServerConfig),
157    Sse(McpSseServerConfig),
158    SseIde(McpSseIdeServerConfig),
159    WebSocketIde(McpWebSocketIdeServerConfig),
160    Http(McpHttpServerConfig),
161    WebSocket(McpWebSocketServerConfig),
162    Sdk(McpSdkServerConfig),
163    ClaudeAiProxy(McpClaudeAiProxyServerConfig),
164}
165
166/// Scoped MCP server configuration with scope information
167#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct ScopedMcpServerConfig {
170    #[serde(flatten)]
171    pub config: McpServerConfig,
172    pub scope: ConfigScope,
173    /// For plugin-provided servers: the providing plugin's source (e.g. 'slack@anthropic')
174    #[serde(default)]
175    pub plugin_source: Option<String>,
176}
177
178/// MCP JSON configuration file format
179#[derive(Debug, Clone, Serialize, Deserialize, Default)]
180#[serde(rename_all = "camelCase")]
181pub struct McpJsonConfig {
182    #[serde(default)]
183    pub mcp_servers: std::collections::HashMap<String, McpServerConfig>,
184}
185
186/// Server capabilities from MCP server
187#[derive(Debug, Clone, Serialize, Deserialize, Default)]
188pub struct ServerCapabilities {
189    #[serde(default)]
190    pub tools: Option<serde_json::Value>,
191    #[serde(default)]
192    pub resources: Option<serde_json::Value>,
193    #[serde(default)]
194    pub prompts: Option<serde_json::Value>,
195    #[serde(default)]
196    pub logging: Option<serde_json::Value>,
197}
198
199/// Connected MCP server
200#[derive(Serialize, Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct ConnectedMcpServer {
203    pub name: String,
204    #[serde(rename = "type")]
205    pub server_type: String,
206    pub capabilities: Option<ServerCapabilities>,
207    #[serde(default)]
208    pub server_info: Option<McpServerInfo>,
209    #[serde(default)]
210    pub instructions: Option<String>,
211    pub config: ScopedMcpServerConfig,
212    /// Live MCP client runtime. Not serialized, must be set after deserialization.
213    #[serde(skip, default)]
214    pub runtime: Option<std::sync::Arc<rust_mcp_sdk::mcp_client::ClientRuntime>>,
215}
216
217impl std::fmt::Debug for ConnectedMcpServer {
218    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219        f.debug_struct("ConnectedMcpServer")
220            .field("name", &self.name)
221            .field("server_type", &self.server_type)
222            .field("capabilities", &self.capabilities)
223            .field("server_info", &self.server_info)
224            .field("instructions", &self.instructions)
225            .field("config", &self.config)
226            .field("runtime", &self.runtime.is_some())
227            .finish()
228    }
229}
230
231impl Clone for ConnectedMcpServer {
232    fn clone(&self) -> Self {
233        Self {
234            name: self.name.clone(),
235            server_type: self.server_type.clone(),
236            capabilities: self.capabilities.clone(),
237            server_info: self.server_info.clone(),
238            instructions: self.instructions.clone(),
239            config: self.config.clone(),
240            runtime: self.runtime.clone(),
241        }
242    }
243}
244
245/// MCP server info
246#[derive(Debug, Clone, Serialize, Deserialize)]
247#[serde(rename_all = "camelCase")]
248pub struct McpServerInfo {
249    pub name: String,
250    pub version: String,
251}
252
253/// Failed MCP server
254#[derive(Debug, Clone, Serialize, Deserialize)]
255#[serde(rename_all = "camelCase")]
256pub struct FailedMcpServer {
257    pub name: String,
258    #[serde(rename = "type")]
259    pub server_type: String,
260    pub config: ScopedMcpServerConfig,
261    #[serde(default)]
262    pub error: Option<String>,
263}
264
265/// MCP server that needs authentication
266#[derive(Debug, Clone, Serialize, Deserialize)]
267#[serde(rename_all = "camelCase")]
268pub struct NeedsAuthMcpServer {
269    pub name: String,
270    #[serde(rename = "type")]
271    pub server_type: String,
272    pub config: ScopedMcpServerConfig,
273}
274
275/// Pending MCP server (connecting)
276#[derive(Debug, Clone, Serialize, Deserialize)]
277#[serde(rename_all = "camelCase")]
278pub struct PendingMcpServer {
279    pub name: String,
280    #[serde(rename = "type")]
281    pub server_type: String,
282    pub config: ScopedMcpServerConfig,
283    #[serde(default)]
284    pub reconnect_attempt: Option<u32>,
285    #[serde(default)]
286    pub max_reconnect_attempts: Option<u32>,
287}
288
289/// Disabled MCP server
290#[derive(Debug, Clone, Serialize, Deserialize)]
291#[serde(rename_all = "camelCase")]
292pub struct DisabledMcpServer {
293    pub name: String,
294    #[serde(rename = "type")]
295    pub server_type: String,
296    pub config: ScopedMcpServerConfig,
297}
298
299/// MCP server connection state
300#[derive(Debug, Clone, Serialize, Deserialize)]
301#[serde(untagged)]
302pub enum McpServerConnection {
303    Connected(ConnectedMcpServer),
304    Failed(FailedMcpServer),
305    NeedsAuth(NeedsAuthMcpServer),
306    Pending(PendingMcpServer),
307    Disabled(DisabledMcpServer),
308}
309
310/// Server resource from MCP server
311#[derive(Debug, Clone, Serialize, Deserialize)]
312pub struct ServerResource {
313    pub uri: String,
314    #[serde(default)]
315    pub name: Option<String>,
316    #[serde(default)]
317    pub description: Option<String>,
318    #[serde(default)]
319    pub mime_type: Option<String>,
320    pub server: String,
321}
322
323/// Serialized tool from MCP server
324#[derive(Debug, Clone, Serialize, Deserialize)]
325#[serde(rename_all = "camelCase")]
326pub struct SerializedTool {
327    pub name: String,
328    pub description: String,
329    #[serde(default)]
330    pub input_json_schema: Option<serde_json::Value>,
331    #[serde(default)]
332    pub is_mcp: Option<bool>,
333    /// Original unnormalized tool name from MCP server
334    #[serde(default)]
335    pub original_tool_name: Option<String>,
336}
337
338/// Serialized client state
339#[derive(Debug, Clone, Serialize, Deserialize)]
340#[serde(rename_all = "camelCase")]
341pub struct SerializedClient {
342    pub name: String,
343    #[serde(rename = "type")]
344    pub client_type: String,
345    #[serde(default)]
346    pub capabilities: Option<ServerCapabilities>,
347}
348
349/// MCP CLI state for persistence
350#[derive(Debug, Clone, Serialize, Deserialize, Default)]
351#[serde(rename_all = "camelCase")]
352pub struct McpCliState {
353    pub clients: Vec<SerializedClient>,
354    #[serde(default)]
355    pub configs: std::collections::HashMap<String, ScopedMcpServerConfig>,
356    #[serde(default)]
357    pub tools: Vec<SerializedTool>,
358    #[serde(default)]
359    pub resources: std::collections::HashMap<String, Vec<ServerResource>>,
360    /// Maps normalized names to original names
361    #[serde(default)]
362    pub normalized_names: Option<std::collections::HashMap<String, String>>,
363}