fix(mcp): clear prompt registry on refresh to prevent duplicates (#5385)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
Co-authored-by: Sandy Tao <sandytao520@icloud.com>
This commit is contained in:
Ramón Medrano Llamas 2025-08-05 23:59:31 +02:00 committed by GitHub
parent faf6a5497a
commit 29c3825604
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 12 deletions

View File

@ -53,4 +53,22 @@ export class PromptRegistry {
}
return serverPrompts.sort((a, b) => a.name.localeCompare(b.name));
}
/**
* Clears all the prompts from the registry.
*/
clear(): void {
this.prompts.clear();
}
/**
* Removes all prompts from a specific server.
*/
removePromptsByServer(serverName: string): void {
for (const [name, prompt] of this.prompts.entries()) {
if (prompt.serverName === serverName) {
this.prompts.delete(name);
}
}
}
}

View File

@ -172,6 +172,10 @@ describe('ToolRegistry', () => {
);
vi.spyOn(config, 'getMcpServers');
vi.spyOn(config, 'getMcpServerCommand');
vi.spyOn(config, 'getPromptRegistry').mockReturnValue({
clear: vi.fn(),
removePromptsByServer: vi.fn(),
} as any);
mockDiscoverMcpTools.mockReset().mockResolvedValue(undefined);
});
@ -353,7 +357,7 @@ describe('ToolRegistry', () => {
mcpServerConfigVal,
undefined,
toolRegistry,
undefined,
config.getPromptRegistry(),
false,
);
});
@ -376,7 +380,7 @@ describe('ToolRegistry', () => {
mcpServerConfigVal,
undefined,
toolRegistry,
undefined,
config.getPromptRegistry(),
false,
);
});

View File

@ -150,6 +150,14 @@ export class ToolRegistry {
this.tools.set(tool.name, tool);
}
private removeDiscoveredTools(): void {
for (const tool of this.tools.values()) {
if (tool instanceof DiscoveredTool || tool instanceof DiscoveredMCPTool) {
this.tools.delete(tool.name);
}
}
}
/**
* Discovers tools from project (if available and configured).
* Can be called multiple times to update discovered tools.
@ -157,11 +165,9 @@ export class ToolRegistry {
*/
async discoverAllTools(): Promise<void> {
// remove any previously discovered tools
for (const tool of this.tools.values()) {
if (tool instanceof DiscoveredTool || tool instanceof DiscoveredMCPTool) {
this.tools.delete(tool.name);
}
}
this.removeDiscoveredTools();
this.config.getPromptRegistry().clear();
await this.discoverAndRegisterToolsFromCommand();
@ -182,11 +188,9 @@ export class ToolRegistry {
*/
async discoverMcpTools(): Promise<void> {
// remove any previously discovered tools
for (const tool of this.tools.values()) {
if (tool instanceof DiscoveredMCPTool) {
this.tools.delete(tool.name);
}
}
this.removeDiscoveredTools();
this.config.getPromptRegistry().clear();
// discover tools using MCP servers, if configured
await discoverMcpTools(
@ -210,6 +214,8 @@ export class ToolRegistry {
}
}
this.config.getPromptRegistry().removePromptsByServer(serverName);
const mcpServers = this.config.getMcpServers() ?? {};
const serverConfig = mcpServers[serverName];
if (serverConfig) {