fix(LocalRunnerClient): support cleaning non-existing MCP Servers' tools while MCP configuration files changed in CommonMcp

This commit is contained in:
2026-01-16 21:48:17 +08:00
parent fb5cabc747
commit c793851107
2 changed files with 42 additions and 6 deletions

View File

@@ -1349,6 +1349,8 @@ public class LocalRunnerClient extends RunnerClient {
// new mcp clients and outdated clients has been updated in above logic
// this part focus on removing non-existing mcp
mcpClients.keySet().removeIf(id -> !existingMcpIdSet.contains(id));
// clear relevant tools' action info
existedMetaActions.keySet().removeIf(id -> !existingMcpIdSet.contains(id.split("::")[0]));
}
private boolean fileChanged(File file, McpConfigFileRecord fileRecord) {

View File

@@ -701,6 +701,40 @@ public class LocalRunnerClientTest {
}
}
@Test
void testCommonMcpRemoveEntryFromConfig(@TempDir Path tempDir) throws IOException, InterruptedException {
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
try {
Path mcpDir = tempDir.resolve("action").resolve("mcp");
Files.createDirectories(mcpDir);
Path configFile = mcpDir.resolve("servers.json");
String config = buildCommonMcpConfig(
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"),
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
);
writeCommonMcpConfig(configFile, config);
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
String updatedConfig = buildCommonMcpConfig(
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
);
writeCommonMcpConfig(configFile, updatedConfig);
waitForCondition(() -> !hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
} finally {
executor.shutdownNow();
}
}
@Test
void testCommonMcpInvalidJsonRecovery(@TempDir Path tempDir) throws IOException, InterruptedException {
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();