fix(mcp): resolve sync-to-other-side functionality failure

This commit implements a three-layer fix to restore the "Sync to other side"
feature when adding or editing MCP servers across Claude and Codex.

Root Cause Analysis:
1. Frontend issue: New MCP entries had their `enabled` field deleted
2. Backend issue: Default value was `false` when `enabled` was missing
3. Core issue: MCP entries were never copied to the other app's servers

Changes:

Frontend (McpFormModal.tsx):
- Set `enabled=true` by default for new MCP entries
- Preserve existing `enabled` state when editing

Backend (services/mcp.rs):
- Change default value from `unwrap_or(false)` to `unwrap_or(true)`
- Implement cross-app MCP replication when `sync_other_side=true`
- Clone MCP entry to other app's servers before syncing to live files

Impact:
- "Sync to Codex" checkbox now correctly adds MCP to both Claude and Codex
- "Sync to Claude" checkbox now correctly adds MCP to both Codex and Claude
- Both config.json and live files (~/.claude.json, ~/.codex/config.toml) are updated
- Fixes regression introduced during project restructure

Tested:
- TypeScript type checking passed
- Rust clippy linting passed
- Manual testing: MCP sync works bidirectionally
This commit is contained in:
Jason
2025-10-30 22:34:34 +08:00
parent ef85b015d3
commit 717be12991
2 changed files with 29 additions and 3 deletions

View File

@@ -39,18 +39,41 @@ impl McpService {
let mut cfg = state.config.write()?;
let changed = mcp::upsert_in_config_for(&mut cfg, &app, id, spec)?;
// 修复默认启用unwrap_or(true)
// 新增的 MCP 如果缺少 enabled 字段,应该默认为启用状态
let enabled = cfg
.mcp_for(&app)
.servers
.get(id)
.and_then(|entry| entry.get("enabled"))
.and_then(|v| v.as_bool())
.unwrap_or(false);
.unwrap_or(true);
let mut sync_claude = matches!(app, AppType::Claude) && enabled;
let mut sync_codex = matches!(app, AppType::Codex) && enabled;
// 修复sync_other_side=true 时,先将 MCP 复制到另一侧,然后强制同步
// 这才是"同步到另一侧"的正确语义:将 MCP 跨应用复制
if sync_other_side {
// 获取当前 MCP 条目的克隆(刚刚插入的,不可能失败)
let current_entry = cfg
.mcp_for(&app)
.servers
.get(id)
.cloned()
.expect("刚刚插入的 MCP 条目必定存在");
// 将该 MCP 复制到另一侧的 servers
let other_app = match app {
AppType::Claude => AppType::Codex,
AppType::Codex => AppType::Claude,
};
cfg.mcp_for_mut(&other_app)
.servers
.insert(id.to_string(), current_entry);
// 强制同步另一侧
match app {
AppType::Claude => sync_codex = true,
AppType::Codex => sync_claude = true,