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:
@@ -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,
|
||||
|
||||
@@ -365,10 +365,13 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
|
||||
server: serverSpec,
|
||||
};
|
||||
|
||||
// 修复:新增 MCP 时默认启用(enabled=true)
|
||||
// 编辑模式下保留原有的 enabled 状态
|
||||
if (initialData?.enabled !== undefined) {
|
||||
entry.enabled = initialData.enabled;
|
||||
} else if (!initialData) {
|
||||
delete entry.enabled;
|
||||
} else {
|
||||
// 新增模式:默认启用
|
||||
entry.enabled = true;
|
||||
}
|
||||
|
||||
const nameTrimmed = (formName || trimmedId).trim();
|
||||
|
||||
Reference in New Issue
Block a user