From 0af4ca040fe74db69156ab2748a5f7257c493eb7 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Mon, 2 Mar 2026 12:27:42 +0800 Subject: [PATCH] fix(mcp): improve CCW config update logic and add debug logging - Fix McpManagerPage to read config after optimistic update and pass only expected fields - Add debug logging for enabledTools config building and ccw-tools server saving --- ccw/frontend/src/lib/api.ts | 3 +++ ccw/frontend/src/pages/McpManagerPage.tsx | 14 +++++++++++--- ccw/src/core/routes/mcp-routes.ts | 5 +++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ccw/frontend/src/lib/api.ts b/ccw/frontend/src/lib/api.ts index 645d166c..35c6d889 100644 --- a/ccw/frontend/src/lib/api.ts +++ b/ccw/frontend/src/lib/api.ts @@ -4373,10 +4373,13 @@ function buildCcwMcpServerConfig(config: { // Only use default when enabledTools is undefined (not provided) // When enabledTools is an empty array, set to empty string to disable all tools + console.log('[buildCcwMcpServerConfig] config.enabledTools:', config.enabledTools); if (config.enabledTools !== undefined) { env.CCW_ENABLED_TOOLS = config.enabledTools.join(','); + console.log('[buildCcwMcpServerConfig] Set CCW_ENABLED_TOOLS to:', env.CCW_ENABLED_TOOLS); } else { env.CCW_ENABLED_TOOLS = 'write_file,edit_file,read_file,core_memory,ask_question,smart_search'; + console.log('[buildCcwMcpServerConfig] Using default CCW_ENABLED_TOOLS'); } if (config.projectRoot) { diff --git a/ccw/frontend/src/pages/McpManagerPage.tsx b/ccw/frontend/src/pages/McpManagerPage.tsx index e11c5d91..5d80fd2a 100644 --- a/ccw/frontend/src/pages/McpManagerPage.tsx +++ b/ccw/frontend/src/pages/McpManagerPage.tsx @@ -412,8 +412,7 @@ export function McpManagerPage() { }; const handleUpdateCcwConfig = async (config: Partial) => { - // Read BEFORE optimistic update to capture actual server state - const currentConfig = queryClient.getQueryData(ccwMcpQueryKey) ?? ccwConfig; + // Read BEFORE optimistic update to capture previous state for rollback const previousConfig = queryClient.getQueryData(ccwMcpQueryKey); // Optimistic cache update for immediate UI response @@ -422,8 +421,17 @@ export function McpManagerPage() { return { ...old, ...config }; }); + // Read AFTER optimistic update to get the latest merged state + const currentConfig = queryClient.getQueryData(ccwMcpQueryKey) ?? ccwConfig; + try { - await updateCcwConfig({ ...currentConfig, ...config }); + // Only pass the fields that updateCcwConfig expects + await updateCcwConfig({ + enabledTools: currentConfig.enabledTools, + projectRoot: currentConfig.projectRoot, + allowedDirs: currentConfig.allowedDirs, + enableSandbox: currentConfig.enableSandbox, + }); } catch (error) { console.error('Failed to update CCW config:', error); queryClient.setQueryData(ccwMcpQueryKey, previousConfig); diff --git a/ccw/src/core/routes/mcp-routes.ts b/ccw/src/core/routes/mcp-routes.ts index aa4d84fc..59d9eb1f 100644 --- a/ccw/src/core/routes/mcp-routes.ts +++ b/ccw/src/core/routes/mcp-routes.ts @@ -945,6 +945,11 @@ function addGlobalMcpServer(serverName: string, serverConfig: unknown) { config.mcpServers = {}; } + // Debug logging for ccw-tools + if (serverName === 'ccw-tools') { + console.log('[addGlobalMcpServer] Saving ccw-tools config:', JSON.stringify(serverConfig, null, 2)); + } + // Add the server to top-level mcpServers config.mcpServers[serverName] = serverConfig;