fix(mcp): warn about disabled tool typos on every discovery path (#16120)

Refs #16078

Co-authored-by: Qwen-Coder <[email protected]>
This commit is contained in:
易良andQwen-Coder authored and GitHub committed 2026-11-02 21:41:17 +08:00
1 parent 9336986835
commit e7b86ae32d
2 files changed
+29

No files matched your search

@@ -558,6 +558,32 @@ describe('McpClientManager', () => {
expect(McpClient).not.toHaveBeenCalled();
});
it('reports unmatched disabled tools on pool and incremental discovery', async () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const getDisabledTools = () => new Set(['run_shel_command']);
const { config: poolConfiguration, manager: poolMcpManager } = poolManager(
() => ({ srv: {} }),
vi.fn().mockResolvedValue(mkConn('srv')),
{ getDisabledTools },
);
await poolMcpManager.discoverAllMcpTools(poolConfiguration);
const incrementalConfig = mkConfig(() => ({}), {
isMcpServerDisabled: () => false,
getDisabledTools,
});
const incrementalManager = mkManager({ config: incrementalConfig });
await incrementalManager.discoverAllMcpToolsIncremental(incrementalConfig);
expect(warnSpy).toHaveBeenCalledTimes(2);
expect(
warnSpy.mock.calls.every(([line]) =>
String(line).includes('run_shel_command'),
),
).toBe(true);
});
it('refreshes metadata on a retained unpooled connection without transport churn', async () => {
let serverConfig = {
command: 'node',
@@ -1789,6 +1789,7 @@ export class McpClientManager {
}
// Same settled-registry report as the per-session bulk pass (#12435).
warnOnUnmatchedEagerToolEntries(cliConfig);
warnOnUnmatchedDisabledToolEntries(cliConfig);
}
private releaseAllPooledConnections(): void {
@@ -2408,6 +2409,8 @@ export class McpClientManager {
// MCP hot-reload reconcile both land here, so this is where a misspelt
// `tools.eager` entry becomes visible (#12435).
warnOnUnmatchedEagerToolEntries(cliConfig);
// Repeated discovery is deduplicated by the helper's per-Config ledger.
warnOnUnmatchedDisabledToolEntries(cliConfig);
}
/**