feat(core): disable tool discovery by default and require explicit configuration

This commit is contained in:
Yuna Seol
2026-02-09 14:11:04 -05:00
committed by Yuna Seol
parent ce84b3cb5f
commit b4df1183ba
7 changed files with 63 additions and 0 deletions
+7
View File
@@ -388,6 +388,7 @@ export interface ConfigParameters {
/** @deprecated Use Policy Engine instead */
excludeTools?: string[];
toolDiscoveryCommand?: string;
enableToolDiscovery?: boolean;
toolCallCommand?: string;
mcpServerCommand?: string;
mcpServers?: Record<string, MCPServerConfig>;
@@ -524,6 +525,7 @@ export class Config {
/** @deprecated Use Policy Engine instead */
private readonly excludeTools: string[] | undefined;
private readonly toolDiscoveryCommand: string | undefined;
private readonly enableToolDiscovery: boolean;
private readonly toolCallCommand: string | undefined;
private readonly mcpServerCommand: string | undefined;
private readonly mcpEnabled: boolean;
@@ -696,6 +698,7 @@ export class Config {
this.allowedTools = params.allowedTools;
this.excludeTools = params.excludeTools;
this.toolDiscoveryCommand = params.toolDiscoveryCommand;
this.enableToolDiscovery = params.enableToolDiscovery ?? false;
this.toolCallCommand = params.toolCallCommand;
this.mcpServerCommand = params.mcpServerCommand;
this.mcpServers = params.mcpServers;
@@ -1534,6 +1537,10 @@ export class Config {
return this.toolDiscoveryCommand;
}
getEnableToolDiscovery(): boolean {
return this.enableToolDiscovery;
}
getToolCallCommand(): string | undefined {
return this.toolCallCommand;
}
@@ -22,6 +22,7 @@ import fs from 'node:fs';
import { MockTool } from '../test-utils/mock-tool.js';
import { ToolErrorType } from './tool-error.js';
import type { MessageBus } from '../confirmation-bus/message-bus.js';
import { debugLogger } from '../utils/debugLogger.js';
vi.mock('node:fs');
@@ -216,6 +217,7 @@ describe('ToolRegistry', () => {
unsubscribe: vi.fn(),
} as unknown as MessageBus;
let mockConfigGetToolDiscoveryCommand: ReturnType<typeof vi.spyOn>;
let mockConfigGetEnableToolDiscovery: ReturnType<typeof vi.spyOn>;
let mockConfigGetExcludedTools: MockInstance<
typeof Config.prototype.getExcludeTools
>;
@@ -242,6 +244,12 @@ describe('ToolRegistry', () => {
config,
'getToolDiscoveryCommand',
);
mockConfigGetEnableToolDiscovery = vi.spyOn(
config,
'getEnableToolDiscovery',
);
mockConfigGetEnableToolDiscovery.mockReturnValue(true);
mockConfigGetExcludedTools = vi.spyOn(config, 'getExcludeTools');
vi.spyOn(config, 'getMcpServers');
vi.spyOn(config, 'getMcpServerCommand');
@@ -472,6 +480,22 @@ describe('ToolRegistry', () => {
});
describe('discoverTools', () => {
it('should warn and skip discovery if enableToolDiscovery is false', async () => {
const discoveryCommand = 'my-discovery-command';
mockConfigGetToolDiscoveryCommand.mockReturnValue(discoveryCommand);
mockConfigGetEnableToolDiscovery.mockReturnValue(false);
const warnSpy = vi.spyOn(debugLogger, 'warn');
const mockSpawn = vi.mocked(spawn);
await toolRegistry.discoverAllTools();
expect(warnSpy).toHaveBeenCalledWith(
expect.stringContaining('Tool discovery is disabled by default'),
);
expect(mockSpawn).not.toHaveBeenCalled();
});
it('should will preserve tool parametersJsonSchema during discovery from command', async () => {
const discoveryCommand = 'my-discovery-command';
mockConfigGetToolDiscoveryCommand.mockReturnValue(discoveryCommand);
+7
View File
@@ -314,6 +314,13 @@ export class ToolRegistry {
return;
}
if (!this.config.getEnableToolDiscovery()) {
debugLogger.warn(
'Tool discovery is disabled by default. Please enable it in settings to use discovered tools.',
);
return;
}
try {
const cmdParts = parse(discoveryCmd);
if (cmdParts.length === 0) {