diff --git a/src-tauri/src/mcp/codex.rs b/src-tauri/src/mcp/codex.rs index d86b5679c..e7ceacfec 100644 --- a/src-tauri/src/mcp/codex.rs +++ b/src-tauri/src/mcp/codex.rs @@ -359,9 +359,14 @@ pub fn sync_single_server_to_codex( let mut doc = if config_path.exists() { let content = std::fs::read_to_string(&config_path).map_err(|e| AppError::io(&config_path, e))?; - content - .parse::() - .map_err(|e| AppError::McpValidation(format!("解析 Codex config.toml 失败: {e}")))? + // 尝试解析现有配置,如果失败则创建新文档(容错处理) + match content.parse::() { + Ok(doc) => doc, + Err(e) => { + log::warn!("解析 Codex config.toml 失败: {e},将创建新配置"); + toml_edit::DocumentMut::new() + } + } } else { toml_edit::DocumentMut::new() }; @@ -409,9 +414,14 @@ pub fn remove_server_from_codex(id: &str) -> Result<(), AppError> { let content = std::fs::read_to_string(&config_path).map_err(|e| AppError::io(&config_path, e))?; - let mut doc = content - .parse::() - .map_err(|e| AppError::McpValidation(format!("解析 Codex config.toml 失败: {e}")))?; + // 尝试解析现有配置,如果失败则直接返回(无法删除不存在的内容) + let mut doc = match content.parse::() { + Ok(doc) => doc, + Err(e) => { + log::warn!("解析 Codex config.toml 失败: {e},跳过删除操作"); + return Ok(()); + } + }; // 从正确的位置删除:[mcp_servers] if let Some(mcp_servers) = doc.get_mut("mcp_servers").and_then(|s| s.as_table_mut()) { diff --git a/src-tauri/src/services/config.rs b/src-tauri/src/services/config.rs index 3835fb7ad..8a46a2b2a 100644 --- a/src-tauri/src/services/config.rs +++ b/src-tauri/src/services/config.rs @@ -146,7 +146,9 @@ impl ConfigService { let cfg_text = settings.get("config").and_then(Value::as_str); crate::codex_config::write_codex_live_atomic(auth, cfg_text)?; - crate::mcp::sync_enabled_to_codex(config)?; + // 注意:MCP 同步在 v3.7.0 中已通过 McpService 进行,不再在此调用 + // sync_enabled_to_codex 使用旧的 config.mcp.codex 结构,在新架构中为空 + // MCP 的启用/禁用应通过 McpService::toggle_app 进行 let cfg_text_after = crate::codex_config::read_and_validate_codex_config_text()?; if let Some(manager) = config.get_manager_mut(&AppType::Codex) {