Skip to content

Commit 986b086

Browse files
committed
fix(cli): align mcp existing server advice
1 parent 7954d02 commit 986b086

3 files changed

Lines changed: 52 additions & 16 deletions

File tree

src/cortex-cli/src/agent_cmd/tests.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
#[cfg(test)]
44
mod tests {
55
use crate::agent_cmd::cli::{CopyArgs, ExportArgs};
6-
use crate::agent_cmd::loader::{
7-
load_builtin_agents, parse_frontmatter, read_file_with_encoding,
8-
};
6+
use crate::agent_cmd::loader::{load_builtin_agents, parse_frontmatter};
97
use crate::agent_cmd::types::AgentMode;
8+
use crate::utils::file::read_file_with_encoding;
109

1110
#[test]
1211
fn test_read_file_with_utf8() {

src/cortex-cli/src/mcp_cmd/handlers.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ use super::validation::{
1818
validate_env_var_value, validate_server_name, validate_url, validate_url_internal,
1919
};
2020

21+
fn existing_server_advice(name: &str) -> String {
22+
format!(
23+
"MCP server '{}' already exists. Use --force to overwrite, or 'cortex mcp remove {}' first.",
24+
name, name
25+
)
26+
}
27+
2128
/// Run the list command.
2229
pub(crate) async fn run_list(args: ListArgs) -> Result<()> {
2330
let servers = get_mcp_servers()?;
@@ -253,11 +260,7 @@ pub(crate) async fn run_add(args: AddArgs) -> Result<()> {
253260
// Check if server already exists
254261
let server_exists = get_mcp_server(&name)?.is_some();
255262
if server_exists && !force {
256-
bail!(
257-
"MCP server '{}' already exists. Use --force to overwrite, or 'cortex mcp remove {}' first.",
258-
name,
259-
name
260-
);
263+
bail!("{}", existing_server_advice(&name));
261264
}
262265

263266
// Check for conflicting transport types
@@ -722,11 +725,8 @@ pub(crate) async fn run_rename(args: RenameArgs) -> Result<()> {
722725
}
723726

724727
// Check if new name already exists
725-
if get_mcp_server(&args.new_name)?.is_some() {
726-
bail!(
727-
"MCP server '{}' already exists. Remove it first or choose a different name.",
728-
args.new_name
729-
);
728+
if get_mcp_server(&args.new_name)?.is_some() && !args.force {
729+
bail!("{}", existing_server_advice(&args.new_name));
730730
}
731731

732732
let cortex_home =
@@ -746,6 +746,9 @@ pub(crate) async fn run_rename(args: RenameArgs) -> Result<()> {
746746
if let Some(mcp_servers) = config.get_mut("mcp_servers").and_then(|v| v.as_table_mut())
747747
&& let Some(server_config) = mcp_servers.remove(&args.old_name)
748748
{
749+
if args.force {
750+
mcp_servers.remove(&args.new_name);
751+
}
749752
mcp_servers.insert(args.new_name.clone(), server_config);
750753
}
751754

@@ -889,20 +892,31 @@ mod tests {
889892
let args = RenameArgs {
890893
old_name: "old-name".to_string(),
891894
new_name: "new-name".to_string(),
895+
force: false,
892896
};
893897
assert_eq!(args.old_name, "old-name");
894898
assert_eq!(args.new_name, "new-name");
899+
assert!(!args.force);
895900
}
896901

897902
#[test]
898903
fn test_rename_args_same_name() {
899904
let args = RenameArgs {
900905
old_name: "same".to_string(),
901906
new_name: "same".to_string(),
907+
force: false,
902908
};
903909
assert_eq!(args.old_name, args.new_name);
904910
}
905911

912+
#[test]
913+
fn test_existing_server_advice_is_shared_by_add_and_rename() {
914+
assert_eq!(
915+
existing_server_advice("my-server"),
916+
"MCP server 'my-server' already exists. Use --force to overwrite, or 'cortex mcp remove my-server' first."
917+
);
918+
}
919+
906920
// ========================================================================
907921
// AddArgs tests
908922
// ========================================================================

src/cortex-cli/src/mcp_cmd/types.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub enum McpSubcommand {
2424
List(ListArgs),
2525

2626
/// List configured MCP servers (alias for list).
27-
#[command(visible_alias = "ls")]
2827
Ls(ListArgs),
2928

3029
/// Show details for a configured MCP server.
@@ -116,7 +115,7 @@ pub struct AddArgs {
116115
#[command(
117116
group(
118117
ArgGroup::new("transport")
119-
.args(["command", "url", "sse"])
118+
.args(["command", "url", "sse_url"])
120119
.required(true)
121120
.multiple(false)
122121
)
@@ -174,7 +173,7 @@ pub struct AddMcpSseArgs {
174173
#[arg(
175174
long = "sse-bearer-token-env-var",
176175
value_name = "ENV_VAR",
177-
requires = "sse"
176+
requires = "sse_url"
178177
)]
179178
pub sse_bearer_token_env_var: Option<String>,
180179
}
@@ -213,6 +212,10 @@ pub struct RenameArgs {
213212

214213
/// New name for the MCP server.
215214
pub new_name: String,
215+
216+
/// Overwrite an existing server with the new name.
217+
#[arg(long, short = 'f')]
218+
pub force: bool,
216219
}
217220

218221
/// Auth command with subcommands.
@@ -293,6 +296,7 @@ pub struct DebugArgs {
293296
#[cfg(test)]
294297
mod tests {
295298
use super::*;
299+
use clap::CommandFactory;
296300

297301
// =========================================================================
298302
// ListArgs tests
@@ -666,20 +670,33 @@ mod tests {
666670
let args = RenameArgs {
667671
old_name: "old-server".to_string(),
668672
new_name: "new-server".to_string(),
673+
force: false,
669674
};
670675
assert_eq!(args.old_name, "old-server");
671676
assert_eq!(args.new_name, "new-server");
677+
assert!(!args.force);
672678
}
673679

674680
#[test]
675681
fn test_rename_args_same_name() {
676682
let args = RenameArgs {
677683
old_name: "server".to_string(),
678684
new_name: "server".to_string(),
685+
force: false,
679686
};
680687
assert_eq!(args.old_name, args.new_name);
681688
}
682689

690+
#[test]
691+
fn test_rename_args_force_flag() {
692+
let args = RenameArgs {
693+
old_name: "old-server".to_string(),
694+
new_name: "existing-server".to_string(),
695+
force: true,
696+
};
697+
assert!(args.force);
698+
}
699+
683700
// =========================================================================
684701
// AuthCommand tests
685702
// =========================================================================
@@ -897,6 +914,11 @@ mod tests {
897914
assert!(matches!(subcommand, McpSubcommand::Ls(_)));
898915
}
899916

917+
#[test]
918+
fn test_mcp_cli_command_aliases_are_valid() {
919+
McpCli::command().debug_assert();
920+
}
921+
900922
#[test]
901923
fn test_subcommand_get_variant() {
902924
let subcommand = McpSubcommand::Get(GetArgs {
@@ -951,6 +973,7 @@ mod tests {
951973
let subcommand = McpSubcommand::Rename(RenameArgs {
952974
old_name: "old".to_string(),
953975
new_name: "new".to_string(),
976+
force: false,
954977
});
955978
assert!(matches!(subcommand, McpSubcommand::Rename(_)));
956979
}

0 commit comments

Comments
 (0)