This commit finalizes the v3.7.0 unified MCP architecture migration by removing all deprecated code paths and eliminating compiler warnings. Frontend Changes (~950 lines removed): - Remove deprecated components: McpPanel, McpListItem, McpToggle - Remove deprecated hook: useMcpActions - Remove unused API methods: importFrom*, syncEnabledTo*, syncAllServers - Simplify McpFormModal by removing dual-mode logic (unified/legacy) - Remove syncOtherSide checkbox and conflict detection - Clean up unused imports and state variables - Delete associated test files Backend Changes (~400 lines cleaned): - Remove unused Tauri commands: import_mcp_from_*, sync_enabled_mcp_to_* - Delete unused Gemini MCP functions: get_mcp_status, upsert/delete_mcp_server - Add #[allow(deprecated)] to compatibility layer commands - Add #[allow(dead_code)] to legacy helper functions for future migration - Simplify boolean expression in mcp.rs per Clippy suggestion API Deprecation: - Mark legacy APIs with @deprecated JSDoc (getConfig, upsertServerInConfig, etc.) - Preserve backward compatibility for v3.x, planned removal in v4.0 Verification: - ✅ Zero TypeScript errors (pnpm typecheck) - ✅ Zero Clippy warnings (cargo clippy) - ✅ All code formatted (prettier + cargo fmt) - ✅ Builds successfully Total cleanup: ~1,350 lines of code removed/marked Breaking changes: None (all legacy APIs still functional)
198 lines
6.0 KiB
Rust
198 lines
6.0 KiB
Rust
#![allow(non_snake_case)]
|
||
|
||
use std::collections::HashMap;
|
||
|
||
use serde::Serialize;
|
||
use tauri::State;
|
||
|
||
use crate::app_config::AppType;
|
||
use crate::claude_mcp;
|
||
use crate::services::McpService;
|
||
use crate::store::AppState;
|
||
|
||
/// 获取 Claude MCP 状态
|
||
#[tauri::command]
|
||
pub async fn get_claude_mcp_status() -> Result<claude_mcp::McpStatus, String> {
|
||
claude_mcp::get_mcp_status().map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 读取 mcp.json 文本内容
|
||
#[tauri::command]
|
||
pub async fn read_claude_mcp_config() -> Result<Option<String>, String> {
|
||
claude_mcp::read_mcp_json().map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 新增或更新一个 MCP 服务器条目
|
||
#[tauri::command]
|
||
pub async fn upsert_claude_mcp_server(id: String, spec: serde_json::Value) -> Result<bool, String> {
|
||
claude_mcp::upsert_mcp_server(&id, spec).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 删除一个 MCP 服务器条目
|
||
#[tauri::command]
|
||
pub async fn delete_claude_mcp_server(id: String) -> Result<bool, String> {
|
||
claude_mcp::delete_mcp_server(&id).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 校验命令是否在 PATH 中可用(不执行)
|
||
#[tauri::command]
|
||
pub async fn validate_mcp_command(cmd: String) -> Result<bool, String> {
|
||
claude_mcp::validate_command_in_path(&cmd).map_err(|e| e.to_string())
|
||
}
|
||
|
||
#[derive(Serialize)]
|
||
pub struct McpConfigResponse {
|
||
pub config_path: String,
|
||
pub servers: HashMap<String, serde_json::Value>,
|
||
}
|
||
|
||
/// 获取 MCP 配置(来自 ~/.cc-switch/config.json)
|
||
use std::str::FromStr;
|
||
|
||
#[tauri::command]
|
||
#[allow(deprecated)] // 兼容层命令,内部调用已废弃的 Service 方法
|
||
pub async fn get_mcp_config(
|
||
state: State<'_, AppState>,
|
||
app: String,
|
||
) -> Result<McpConfigResponse, String> {
|
||
let config_path = crate::config::get_app_config_path()
|
||
.to_string_lossy()
|
||
.to_string();
|
||
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
||
let servers = McpService::get_servers(&state, app_ty).map_err(|e| e.to_string())?;
|
||
Ok(McpConfigResponse {
|
||
config_path,
|
||
servers,
|
||
})
|
||
}
|
||
|
||
/// 在 config.json 中新增或更新一个 MCP 服务器定义
|
||
/// [已废弃] 该命令仍然使用旧的分应用API,会转换为统一结构
|
||
#[tauri::command]
|
||
pub async fn upsert_mcp_server_in_config(
|
||
state: State<'_, AppState>,
|
||
app: String,
|
||
id: String,
|
||
spec: serde_json::Value,
|
||
sync_other_side: Option<bool>,
|
||
) -> Result<bool, String> {
|
||
use crate::app_config::McpServer;
|
||
|
||
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
||
|
||
// 读取现有的服务器(如果存在)
|
||
let existing_server = {
|
||
let cfg = state.config.read().map_err(|e| e.to_string())?;
|
||
if let Some(servers) = &cfg.mcp.servers {
|
||
servers.get(&id).cloned()
|
||
} else {
|
||
None
|
||
}
|
||
};
|
||
|
||
// 构建新的统一服务器结构
|
||
let mut new_server = if let Some(mut existing) = existing_server {
|
||
// 更新现有服务器
|
||
existing.server = spec.clone();
|
||
existing.apps.set_enabled_for(&app_ty, true);
|
||
existing
|
||
} else {
|
||
// 创建新服务器
|
||
let mut apps = crate::app_config::McpApps::default();
|
||
apps.set_enabled_for(&app_ty, true);
|
||
|
||
// 尝试从 spec 中提取 name,否则使用 id
|
||
let name = spec
|
||
.get("name")
|
||
.and_then(|v| v.as_str())
|
||
.unwrap_or(&id)
|
||
.to_string();
|
||
|
||
McpServer {
|
||
id: id.clone(),
|
||
name,
|
||
server: spec,
|
||
apps,
|
||
description: None,
|
||
homepage: None,
|
||
docs: None,
|
||
tags: Vec::new(),
|
||
}
|
||
};
|
||
|
||
// 如果 sync_other_side 为 true,也启用其他应用
|
||
if sync_other_side.unwrap_or(false) {
|
||
new_server.apps.claude = true;
|
||
new_server.apps.codex = true;
|
||
new_server.apps.gemini = true;
|
||
}
|
||
|
||
McpService::upsert_server(&state, new_server)
|
||
.map(|_| true)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 在 config.json 中删除一个 MCP 服务器定义
|
||
#[tauri::command]
|
||
pub async fn delete_mcp_server_in_config(
|
||
state: State<'_, AppState>,
|
||
_app: String, // 参数保留用于向后兼容,但在统一结构中不再需要
|
||
id: String,
|
||
) -> Result<bool, String> {
|
||
McpService::delete_server(&state, &id).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 设置启用状态并同步到客户端配置
|
||
#[tauri::command]
|
||
#[allow(deprecated)] // 兼容层命令,内部调用已废弃的 Service 方法
|
||
pub async fn set_mcp_enabled(
|
||
state: State<'_, AppState>,
|
||
app: String,
|
||
id: String,
|
||
enabled: bool,
|
||
) -> Result<bool, String> {
|
||
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
||
McpService::set_enabled(&state, app_ty, &id, enabled).map_err(|e| e.to_string())
|
||
}
|
||
|
||
// ============================================================================
|
||
// v3.7.0 新增:统一 MCP 管理命令
|
||
// ============================================================================
|
||
|
||
use crate::app_config::McpServer;
|
||
|
||
/// 获取所有 MCP 服务器(统一结构)
|
||
#[tauri::command]
|
||
pub async fn get_mcp_servers(
|
||
state: State<'_, AppState>,
|
||
) -> Result<HashMap<String, McpServer>, String> {
|
||
McpService::get_all_servers(&state).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 添加或更新 MCP 服务器
|
||
#[tauri::command]
|
||
pub async fn upsert_mcp_server(
|
||
state: State<'_, AppState>,
|
||
server: McpServer,
|
||
) -> Result<(), String> {
|
||
McpService::upsert_server(&state, server).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 删除 MCP 服务器
|
||
#[tauri::command]
|
||
pub async fn delete_mcp_server(state: State<'_, AppState>, id: String) -> Result<bool, String> {
|
||
McpService::delete_server(&state, &id).map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 切换 MCP 服务器在指定应用的启用状态
|
||
#[tauri::command]
|
||
pub async fn toggle_mcp_app(
|
||
state: State<'_, AppState>,
|
||
server_id: String,
|
||
app: String,
|
||
enabled: bool,
|
||
) -> Result<(), String> {
|
||
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
||
McpService::toggle_app(&state, &server_id, app_ty, enabled).map_err(|e| e.to_string())
|
||
}
|