From b132791cd2cb5037240ab6aef65b1d92bad7892e Mon Sep 17 00:00:00 2001 From: Akhilesh Kumar Date: Wed, 11 Mar 2026 20:52:52 +0000 Subject: [PATCH] test(core): add unit tests for subagent MCP tool isolation Unit tests added: 1. Tool Registry Filtering: Verified that main registry hides all '__agent__' prefixed tools. 2. Subagent Tool Inheritance: Verified that agents correctly filter out other agents' MCP tools while retaining their own. Verified with vitest in packages/core. --- .../core/src/agents/local-executor.test.ts | 44 +++++++++++++++++++ packages/core/src/tools/tool-registry.test.ts | 31 +++++++++++++ 2 files changed, 75 insertions(+) diff --git a/packages/core/src/agents/local-executor.test.ts b/packages/core/src/agents/local-executor.test.ts index 653b44c294..ae66aa1b9a 100644 --- a/packages/core/src/agents/local-executor.test.ts +++ b/packages/core/src/agents/local-executor.test.ts @@ -2510,5 +2510,49 @@ describe('LocalAgentExecutor', () => { mcpServers['test-server'], ); }); + + it('should filter out other agents MCP tools when inheriting tools from parent registry', async () => { + const parentMcpTool1 = new DiscoveredMCPTool( + {} as unknown as CallableTool, + '__agent__OtherAgent__server1', + 'tool1', + 'desc1', + {}, + mockConfig.getMessageBus(), + ); + const parentMcpTool2 = new DiscoveredMCPTool( + {} as unknown as CallableTool, + '__agent__TestAgent__server2', + 'tool2', + 'desc2', + {}, + mockConfig.getMessageBus(), + ); + + parentToolRegistry.registerTool(parentMcpTool1); + parentToolRegistry.registerTool(parentMcpTool2); + + const definition = createTestDefinition(); + definition.toolConfig = undefined; // trigger inheritance + + vi.spyOn(mockConfig, 'getMcpClientManager').mockReturnValue({ + maybeDiscoverMcpServer: vi.fn(), + } as unknown as ReturnType); + + const executor = await LocalAgentExecutor.create( + definition, + mockConfig, + onActivity, + ); + + const agentTools = ( + executor as unknown as { toolRegistry: ToolRegistry } + ).toolRegistry.getAllToolNames(); + + expect(agentTools).toContain(parentMcpTool2.asFullyQualifiedTool().name); + expect(agentTools).not.toContain( + parentMcpTool1.asFullyQualifiedTool().name, + ); + }); }); }); diff --git a/packages/core/src/tools/tool-registry.test.ts b/packages/core/src/tools/tool-registry.test.ts index ea560865e6..4fbea3d482 100644 --- a/packages/core/src/tools/tool-registry.test.ts +++ b/packages/core/src/tools/tool-registry.test.ts @@ -284,6 +284,37 @@ describe('ToolRegistry', () => { }); }); + describe('subagent MCP tools filtering', () => { + it('should hide __agent__ prefixed tools when isMainRegistry is true', async () => { + const mainRegistry = new ToolRegistry(config, mockMessageBus, true); + const subagentRegistry = new ToolRegistry(config, mockMessageBus, false); + + const mcpTool = createMCPTool( + '__agent__TestAgent__myServer', + 'my-tool', + 'description', + ); + vi.spyOn(mcpTool, 'getSchema').mockReturnValue({ + name: 'my_tool', + description: 'description', + } as unknown as FunctionDeclaration); + + mainRegistry.registerTool(mcpTool); + subagentRegistry.registerTool(mcpTool); + + const mainDeclarations = + mainRegistry.getFunctionDeclarations('test-model'); + const subagentDeclarations = + subagentRegistry.getFunctionDeclarations('test-model'); + + expect(mainDeclarations.length).toBe(0); + expect(subagentDeclarations.length).toBe(1); + expect(subagentDeclarations[0].name).toBe( + 'mcp___agent__TestAgent__myServer_my-tool', + ); + }); + }); + describe('excluded tools', () => { const simpleTool = new MockTool({ name: 'tool-a',