use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ConfigScope {
Local,
User,
Project,
Dynamic,
Enterprise,
ClaudeAi,
Managed,
}
impl Default for ConfigScope {
fn default() -> Self {
Self::Local
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum Transport {
Stdio,
Sse,
SseIde,
Http,
Ws,
Sdk,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpStdioServerConfig {
#[serde(rename = "type", default)]
pub config_type: Option<String>,
pub command: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub env: Option<std::collections::HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpOAuthConfig {
#[serde(default)]
pub client_id: Option<String>,
#[serde(default)]
pub callback_port: Option<u16>,
#[serde(default)]
pub auth_server_metadata_url: Option<String>,
#[serde(default)]
pub xaa: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpSseServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
#[serde(default)]
pub headers: Option<std::collections::HashMap<String, String>>,
#[serde(default)]
pub headers_helper: Option<String>,
#[serde(default)]
pub oauth: Option<McpOAuthConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpSseIdeServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
pub ide_name: String,
#[serde(default)]
pub ide_running_in_windows: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpWebSocketIdeServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
pub ide_name: String,
#[serde(default)]
pub auth_token: Option<String>,
#[serde(default)]
pub ide_running_in_windows: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpHttpServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
#[serde(default)]
pub headers: Option<std::collections::HashMap<String, String>>,
#[serde(default)]
pub headers_helper: Option<String>,
#[serde(default)]
pub oauth: Option<McpOAuthConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpWebSocketServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
#[serde(default)]
pub headers: Option<std::collections::HashMap<String, String>>,
#[serde(default)]
pub headers_helper: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpSdkServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpClaudeAiProxyServerConfig {
#[serde(rename = "type")]
pub config_type: String,
pub url: String,
pub id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum McpServerConfig {
Stdio(McpStdioServerConfig),
Sse(McpSseServerConfig),
SseIde(McpSseIdeServerConfig),
WebSocketIde(McpWebSocketIdeServerConfig),
Http(McpHttpServerConfig),
WebSocket(McpWebSocketServerConfig),
Sdk(McpSdkServerConfig),
ClaudeAiProxy(McpClaudeAiProxyServerConfig),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ScopedMcpServerConfig {
#[serde(flatten)]
pub config: McpServerConfig,
pub scope: ConfigScope,
#[serde(default)]
pub plugin_source: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct McpJsonConfig {
#[serde(default)]
pub mcp_servers: std::collections::HashMap<String, McpServerConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ServerCapabilities {
#[serde(default)]
pub tools: Option<serde_json::Value>,
#[serde(default)]
pub resources: Option<serde_json::Value>,
#[serde(default)]
pub prompts: Option<serde_json::Value>,
#[serde(default)]
pub logging: Option<serde_json::Value>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConnectedMcpServer {
pub name: String,
#[serde(rename = "type")]
pub server_type: String,
pub capabilities: Option<ServerCapabilities>,
#[serde(default)]
pub server_info: Option<McpServerInfo>,
#[serde(default)]
pub instructions: Option<String>,
pub config: ScopedMcpServerConfig,
#[serde(skip, default)]
pub runtime: Option<std::sync::Arc<rust_mcp_sdk::mcp_client::ClientRuntime>>,
}
impl std::fmt::Debug for ConnectedMcpServer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConnectedMcpServer")
.field("name", &self.name)
.field("server_type", &self.server_type)
.field("capabilities", &self.capabilities)
.field("server_info", &self.server_info)
.field("instructions", &self.instructions)
.field("config", &self.config)
.field("runtime", &self.runtime.is_some())
.finish()
}
}
impl Clone for ConnectedMcpServer {
fn clone(&self) -> Self {
Self {
name: self.name.clone(),
server_type: self.server_type.clone(),
capabilities: self.capabilities.clone(),
server_info: self.server_info.clone(),
instructions: self.instructions.clone(),
config: self.config.clone(),
runtime: self.runtime.clone(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpServerInfo {
pub name: String,
pub version: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FailedMcpServer {
pub name: String,
#[serde(rename = "type")]
pub server_type: String,
pub config: ScopedMcpServerConfig,
#[serde(default)]
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NeedsAuthMcpServer {
pub name: String,
#[serde(rename = "type")]
pub server_type: String,
pub config: ScopedMcpServerConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PendingMcpServer {
pub name: String,
#[serde(rename = "type")]
pub server_type: String,
pub config: ScopedMcpServerConfig,
#[serde(default)]
pub reconnect_attempt: Option<u32>,
#[serde(default)]
pub max_reconnect_attempts: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DisabledMcpServer {
pub name: String,
#[serde(rename = "type")]
pub server_type: String,
pub config: ScopedMcpServerConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum McpServerConnection {
Connected(ConnectedMcpServer),
Failed(FailedMcpServer),
NeedsAuth(NeedsAuthMcpServer),
Pending(PendingMcpServer),
Disabled(DisabledMcpServer),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerResource {
pub uri: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub mime_type: Option<String>,
pub server: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SerializedTool {
pub name: String,
pub description: String,
#[serde(default)]
pub input_json_schema: Option<serde_json::Value>,
#[serde(default)]
pub is_mcp: Option<bool>,
#[serde(default)]
pub original_tool_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SerializedClient {
pub name: String,
#[serde(rename = "type")]
pub client_type: String,
#[serde(default)]
pub capabilities: Option<ServerCapabilities>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct McpCliState {
pub clients: Vec<SerializedClient>,
#[serde(default)]
pub configs: std::collections::HashMap<String, ScopedMcpServerConfig>,
#[serde(default)]
pub tools: Vec<SerializedTool>,
#[serde(default)]
pub resources: std::collections::HashMap<String, Vec<ServerResource>>,
#[serde(default)]
pub normalized_names: Option<std::collections::HashMap<String, String>>,
}