Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/forge_domain/src/mcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ impl McpServerConfig {
}
}

/// Set the disabled state of this server.
pub fn set_disable(&mut self, disabled: bool) {
match self {
McpServerConfig::Stdio(v) => v.disable = disabled,
McpServerConfig::Http(v) => v.disable = disabled,
}
}

/// Returns the type of MCP server as a string ("STDIO" or "HTTP")
pub fn server_type(&self) -> &'static str {
match self {
Expand Down
26 changes: 26 additions & 0 deletions crates/forge_main/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,12 @@ pub enum McpCommand {

/// Remove stored OAuth credentials for an MCP server.
Logout(McpLogoutArgs),

/// Enable a disabled MCP server.
Enable(McpEnableArgs),

/// Disable an MCP server.
Disable(McpDisableArgs),
}

#[derive(Parser, Debug, Clone)]
Expand Down Expand Up @@ -482,6 +488,26 @@ pub struct McpLogoutArgs {
pub name: String,
}

#[derive(Parser, Debug, Clone)]
pub struct McpEnableArgs {
/// Name of the MCP server to enable.
pub name: String,

/// Configuration scope.
#[arg(short = 's', long = "scope", default_value = "local")]
pub scope: Scope,
}

#[derive(Parser, Debug, Clone)]
pub struct McpDisableArgs {
/// Name of the MCP server to disable.
pub name: String,

/// Configuration scope.
#[arg(short = 's', long = "scope", default_value = "local")]
pub scope: Scope,
}

/// Configuration scope for settings.
#[derive(Copy, Clone, Debug, ValueEnum, Default)]
pub enum Scope {
Expand Down
46 changes: 46 additions & 0 deletions crates/forge_main/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,52 @@ impl<A: API + ConsoleWriter + 'static, F: Fn(ForgeConfig) -> A + Send + Sync> UI
McpCommand::Logout(args) => {
self.handle_mcp_logout(&args.name).await?;
}
McpCommand::Enable(args) => {
let name = forge_api::ServerName::from(args.name.clone());
let scope: forge_domain::Scope = args.scope.into();

// Read scope-specific config
let mut scope_config = self.api.read_mcp_config(Some(&scope)).await?;

// Find and enable the server
if let Some(server) = scope_config.mcp_servers.get_mut(&name) {
server.set_disable(false);
self.api.write_mcp_config(&scope, &scope_config).await?;
self.api.reload_mcp().await?;
self.writeln_title(TitleFormat::info(format!(
"Enabled MCP server: {}",
args.name
)))?;
} else {
self.writeln_title(TitleFormat::error(format!(
"Server '{}' not found",
args.name
)))?;
}
}
McpCommand::Disable(args) => {
let name = forge_api::ServerName::from(args.name.clone());
let scope: forge_domain::Scope = args.scope.into();

// Read scope-specific config
let mut scope_config = self.api.read_mcp_config(Some(&scope)).await?;

// Find and disable the server
if let Some(server) = scope_config.mcp_servers.get_mut(&name) {
server.set_disable(true);
self.api.write_mcp_config(&scope, &scope_config).await?;
self.api.reload_mcp().await?;
self.writeln_title(TitleFormat::info(format!(
"Disabled MCP server: {}",
args.name
)))?;
} else {
self.writeln_title(TitleFormat::error(format!(
"Server '{}' not found",
args.name
)))?;
}
}
},
TopLevelCommand::Info { porcelain, conversation_id } => {
// Only initialize state (agent/provider/model resolution).
Expand Down
Loading