1use serde::{Deserialize, Serialize};
5
6#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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#[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 #[serde(default)]
175 pub plugin_source: Option<String>,
176}
177
178#[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#[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#[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 #[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#[derive(Debug, Clone, Serialize, Deserialize)]
247#[serde(rename_all = "camelCase")]
248pub struct McpServerInfo {
249 pub name: String,
250 pub version: String,
251}
252
253#[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#[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#[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#[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#[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#[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#[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 #[serde(default)]
335 pub original_tool_name: Option<String>,
336}
337
338#[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#[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 #[serde(default)]
362 pub normalized_names: Option<std::collections::HashMap<String, String>>,
363}