F6: kimi-cli command parity — kigi acp, mcp auth, --mcp-config-file

- `kigi acp`: top-level alias for the stdio ACP server (kimi-cli `acp`).
  AgentArgs.mode is now optional — bare `kigi agent` and `kigi acp` both
  default to stdio at dispatch; `kigi acp <mode>` is rejected.
- `kigi mcp auth <name>`: authorize an OAuth-enabled remote MCP server
  (kimi-cli `mcp auth`). Reuses the doctor's interactive connection path:
  starts the named server with OauthInteractivity::Interactive (browser
  flow when required), completes the handshake, and reports the tool
  count. Stdio servers and unknown names fail with actionable errors.
- `--mcp-config-file <PATH>` (repeatable, global): extra MCP config files
  in the .mcp.json shape ({"mcpServers": {...}}), kimi-cli semantics.
  Files are validated at parse time (fail fast on unreadable/invalid
  JSON), carried across the TUI -> shell boundary via
  KIGI_MCP_CONFIG_FILES, and merged at HIGHEST priority — an explicitly
  passed file overrides every config scope. Covered by loader unit tests
  and verified live: an injected server surfaces in the session's
  x.ai/mcp/servers_updated notification via both the flag and the env.

The stale bare-agent-requires-mode CLI test is re-contracted to the new
default-to-stdio behavior.
This commit is contained in:
2026-07-17 20:15:56 -04:00
parent 74b210535e
commit a3f062b522
6 changed files with 246 additions and 12 deletions
+25
View File
@@ -80,6 +80,11 @@ pub enum McpCommand {
#[arg(short = 's', long, value_enum)]
scope: Option<McpScope>,
},
/// Authorize with an OAuth-enabled remote MCP server
Auth {
/// Name of the MCP server to authorize
name: String,
},
/// Diagnose MCP server configuration and connectivity
Doctor {
/// Emit machine-readable JSON output
@@ -142,10 +147,30 @@ pub async fn run(mcp_args: McpArgs) -> Result<()> {
McpCommand::List { json } => run_list(json),
McpCommand::Add(args) => run_add(args).await,
McpCommand::Remove { name, scope } => run_remove(&name, scope).await,
McpCommand::Auth { name } => run_auth(&name).await,
McpCommand::Doctor { json, name } => run_doctor(json, name).await,
}
}
/// kimi-cli `mcp auth` parity: start the named remote server with the
/// interactive OAuth flow and report the tool count on success.
async fn run_auth(name: &str) -> Result<()> {
let cwd = current_dir_or_exit();
println!("Authorizing with '{name}'...");
println!("A browser window will open if authorization is required.");
match kigi_shell::mcp_doctor::run_auth(&cwd, name).await {
Ok(tool_count) => {
println!("Successfully authorized with '{name}'.");
println!("Available tools: {tool_count}");
Ok(())
}
Err(e) => {
eprintln!("Authorization failed: {e}");
std::process::exit(1);
}
}
}
fn run_list(json: bool) -> Result<()> {
// Include project-scoped servers (nearest definition wins), matching what
// a session started in this directory would load from config.toml files.