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
This commit is contained in:
catlog22
2026-03-02 12:27:42 +08:00
parent 7af258f43d
commit 0af4ca040f
3 changed files with 19 additions and 3 deletions

View File

@@ -4373,10 +4373,13 @@ function buildCcwMcpServerConfig(config: {
// Only use default when enabledTools is undefined (not provided) // Only use default when enabledTools is undefined (not provided)
// When enabledTools is an empty array, set to empty string to disable all tools // 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) { if (config.enabledTools !== undefined) {
env.CCW_ENABLED_TOOLS = config.enabledTools.join(','); env.CCW_ENABLED_TOOLS = config.enabledTools.join(',');
console.log('[buildCcwMcpServerConfig] Set CCW_ENABLED_TOOLS to:', env.CCW_ENABLED_TOOLS);
} else { } else {
env.CCW_ENABLED_TOOLS = 'write_file,edit_file,read_file,core_memory,ask_question,smart_search'; 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) { if (config.projectRoot) {

View File

@@ -412,8 +412,7 @@ export function McpManagerPage() {
}; };
const handleUpdateCcwConfig = async (config: Partial<CcwMcpConfig>) => { const handleUpdateCcwConfig = async (config: Partial<CcwMcpConfig>) => {
// Read BEFORE optimistic update to capture actual server state // Read BEFORE optimistic update to capture previous state for rollback
const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;
const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey); const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey);
// Optimistic cache update for immediate UI response // Optimistic cache update for immediate UI response
@@ -422,8 +421,17 @@ export function McpManagerPage() {
return { ...old, ...config }; return { ...old, ...config };
}); });
// Read AFTER optimistic update to get the latest merged state
const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;
try { 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) { } catch (error) {
console.error('Failed to update CCW config:', error); console.error('Failed to update CCW config:', error);
queryClient.setQueryData(ccwMcpQueryKey, previousConfig); queryClient.setQueryData(ccwMcpQueryKey, previousConfig);

View File

@@ -945,6 +945,11 @@ function addGlobalMcpServer(serverName: string, serverConfig: unknown) {
config.mcpServers = {}; 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 // Add the server to top-level mcpServers
config.mcpServers[serverName] = serverConfig; config.mcpServers[serverName] = serverConfig;