/** * Deep MCP Tools Test Suite * * Comprehensive tests for all MCP tool files covering: * - Schema validation (name, description, inputSchema) * - Array schemas have `items` field * - Handler existence and error handling * - Tool registration across all 24 tool modules * - System tools version/status correctness * * Uses vitest with mocks to isolate from external dependencies. */ import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest'; // ============================================================================ // Mock setup - must be before imports // ============================================================================ // Mock fs to prevent actual file I/O during tests vi.mock('node:fs', () => { const memStore = new Map(); return { existsSync: vi.fn((p: string) => memStore.has(p)), readFileSync: vi.fn((p: string) => memStore.get(p) || '{}'), writeFileSync: vi.fn((p: string, d: string) => memStore.set(p, d)), mkdirSync: vi.fn(), readdirSync: vi.fn(() => []), unlinkSync: vi.fn(), statSync: vi.fn(() => ({ size: 100, isFile: () => true, isDirectory: () => false })), }; }); vi.mock('fs', () => { const memStore = new Map(); return { existsSync: vi.fn((p: string) => memStore.has(p)), readFileSync: vi.fn((p: string) => memStore.get(p) || '{}'), writeFileSync: vi.fn((p: string, d: string) => memStore.set(p, d)), mkdirSync: vi.fn(), readdirSync: vi.fn(() => []), unlinkSync: vi.fn(), statSync: vi.fn(() => ({ size: 100, isFile: () => true, isDirectory: () => false })), }; }); // Mock child_process for browser/security tools vi.mock('child_process', () => ({ execSync: vi.fn(() => '{}'), spawnSync: vi.fn(() => ({ status: 0, stdout: '' })), })); // Mock the memory bridge for agentdb tools vi.mock('../src/memory/memory-bridge.js', () => ({ bridgeHealthCheck: vi.fn(async () => ({ available: true, status: 'healthy' })), bridgeListControllers: vi.fn(async () => []), bridgeStorePattern: vi.fn(async () => ({ success: true })), bridgeSearchPatterns: vi.fn(async () => ({ results: [] })), bridgeRecordFeedback: vi.fn(async () => ({ success: true })), bridgeRecordCausalEdge: vi.fn(async () => ({ success: true })), bridgeRouteTask: vi.fn(async () => ({ route: 'general', confidence: 0.5, agents: ['coder'] })), bridgeSessionStart: vi.fn(async () => ({ success: true })), bridgeSessionEnd: vi.fn(async () => ({ success: true })), bridgeHierarchicalStore: vi.fn(async () => ({ success: true })), bridgeHierarchicalRecall: vi.fn(async () => ({ results: [] })), bridgeConsolidate: vi.fn(async () => ({ success: true })), bridgeBatchOperation: vi.fn(async () => ({ success: true })), bridgeContextSynthesize: vi.fn(async () => ({ success: true })), bridgeSemanticRoute: vi.fn(async () => ({ route: null })), })); // Mock memory-initializer vi.mock('../src/memory/memory-initializer.js', () => ({ generateEmbedding: vi.fn(async () => ({ embedding: new Array(384).fill(0.1), dimensions: 384, model: 'mock' })), storeEntry: vi.fn(async () => ({ success: true, id: 'mock-id' })), searchEntries: vi.fn(async () => ({ success: true, results: [], searchTime: 1 })), listEntries: vi.fn(async () => ({ success: true, entries: [] })), getEntry: vi.fn(async () => null), deleteEntry: vi.fn(async () => ({ success: true })), getStats: vi.fn(async () => ({ totalEntries: 0 })), initializeDatabase: vi.fn(async () => ({ success: true })), initializeMemoryDatabase: vi.fn(async () => ({ success: true })), checkMemoryInitialization: vi.fn(async () => ({ initialized: true, version: '3.0.0' })), migrateFromLegacy: vi.fn(async () => ({ success: true, migrated: 0 })), })); // Mock intelligence module vi.mock('../src/memory/intelligence.js', () => ({ getIntelligenceStats: vi.fn(() => ({ patternsLearned: 0, trajectoriesRecorded: 0, reasoningBankSize: 0, sonaEnabled: false, lastAdaptation: null, })), initializeIntelligence: vi.fn(async () => {}), benchmarkAdaptation: vi.fn(() => ({ avgMs: 0.01, minMs: 0.005, maxMs: 0.02, targetMet: true })), })); // Mock ruvector modules vi.mock('../src/ruvector/model-router.js', () => ({ getModelRouter: vi.fn(() => ({ route: async () => ({ model: 'sonnet', routedBy: 'router' }) })), })); vi.mock('../src/ruvector/enhanced-model-router.js', () => ({ getEnhancedModelRouter: vi.fn(() => ({ route: async () => ({ tier: 2, model: 'sonnet', canSkipLLM: false }), })), })); vi.mock('../src/ruvector/diff-classifier.js', () => ({ analyzeDiff: vi.fn(async () => ({ ref: 'HEAD', timestamp: new Date().toISOString(), files: [], risk: { overall: 'low', score: 10 }, classification: { type: 'patch' }, summary: 'No changes', fileRisks: [], recommendedReviewers: [], })), assessFileRisk: vi.fn(() => ({ risk: 'low', score: 10, reasons: [] })), assessOverallRisk: vi.fn(() => ({ overall: 'low', score: 10 })), classifyDiff: vi.fn(() => ({ type: 'patch' })), suggestReviewers: vi.fn(() => []), getGitDiffNumstat: vi.fn(() => []), })); vi.mock('../src/ruvector/moe-router.js', () => ({ getMoERouter: vi.fn(async () => null), })); vi.mock('../src/memory/sona-optimizer.js', () => ({ getSONAOptimizer: vi.fn(async () => null), })); vi.mock('../src/memory/ewc-consolidation.js', () => ({ getEWCConsolidator: vi.fn(async () => null), })); // Mock transfer modules vi.mock('../src/transfer/anonymization/index.js', () => ({ detectPII: vi.fn(() => ({ hasPII: false, entities: [] })), })); vi.mock('../src/transfer/ipfs/client.js', () => ({ resolveIPNS: vi.fn(async () => 'QmMock'), })); // Mock module for auto-install vi.mock('../src/mcp-tools/auto-install.js', () => ({ autoInstallPackage: vi.fn(async () => false), })); // Mock security package vi.mock('@claude-flow/aidefence', () => { throw new Error('Cannot find package'); }); // Mock embeddings package vi.mock('@claude-flow/embeddings', () => { throw new Error('Cannot find package'); }); vi.mock('agentic-flow/reasoningbank', () => { throw new Error('Cannot find package'); }); // ============================================================================ // Import all tool modules (after mocks are set up) // ============================================================================ import { agentTools } from '../src/mcp-tools/agent-tools.js'; import { agentdbTools } from '../src/mcp-tools/agentdb-tools.js'; import { analyzeTools } from '../src/mcp-tools/analyze-tools.js'; import { browserTools } from '../src/mcp-tools/browser-tools.js'; import { claimsTools } from '../src/mcp-tools/claims-tools.js'; import { configTools } from '../src/mcp-tools/config-tools.js'; import { coordinationTools } from '../src/mcp-tools/coordination-tools.js'; import { daaTools } from '../src/mcp-tools/daa-tools.js'; import { embeddingsTools } from '../src/mcp-tools/embeddings-tools.js'; import { githubTools } from '../src/mcp-tools/github-tools.js'; import { hiveMindTools } from '../src/mcp-tools/hive-mind-tools.js'; import { memoryTools } from '../src/mcp-tools/memory-tools.js'; import { neuralTools } from '../src/mcp-tools/neural-tools.js'; import { performanceTools } from '../src/mcp-tools/performance-tools.js'; import { progressTools } from '../src/mcp-tools/progress-tools.js'; import { securityTools } from '../src/mcp-tools/security-tools.js'; import { sessionTools } from '../src/mcp-tools/session-tools.js'; import { swarmTools } from '../src/mcp-tools/swarm-tools.js'; import { systemTools } from '../src/mcp-tools/system-tools.js'; import { taskTools } from '../src/mcp-tools/task-tools.js'; import { terminalTools } from '../src/mcp-tools/terminal-tools.js'; import { transferTools } from '../src/mcp-tools/transfer-tools.js'; import { workflowTools } from '../src/mcp-tools/workflow-tools.js'; import { hooksTools } from '../src/mcp-tools/hooks-tools.js'; import type { MCPTool } from '../src/mcp-tools/types.js'; // ============================================================================ // Collect all tool modules // ============================================================================ interface ToolModule { name: string; tools: MCPTool[]; } const ALL_MODULES: ToolModule[] = [ { name: 'agent-tools', tools: agentTools }, { name: 'agentdb-tools', tools: agentdbTools }, { name: 'analyze-tools', tools: analyzeTools }, { name: 'browser-tools', tools: browserTools }, { name: 'claims-tools', tools: claimsTools }, { name: 'config-tools', tools: configTools }, { name: 'coordination-tools', tools: coordinationTools }, { name: 'daa-tools', tools: daaTools }, { name: 'embeddings-tools', tools: embeddingsTools }, { name: 'github-tools', tools: githubTools }, { name: 'hive-mind-tools', tools: hiveMindTools }, { name: 'hooks-tools', tools: hooksTools }, { name: 'memory-tools', tools: memoryTools }, { name: 'neural-tools', tools: neuralTools }, { name: 'performance-tools', tools: performanceTools }, { name: 'progress-tools', tools: progressTools }, { name: 'security-tools', tools: securityTools }, { name: 'session-tools', tools: sessionTools }, { name: 'swarm-tools', tools: swarmTools }, { name: 'system-tools', tools: systemTools }, { name: 'task-tools', tools: taskTools }, { name: 'terminal-tools', tools: terminalTools }, { name: 'transfer-tools', tools: transferTools }, { name: 'workflow-tools', tools: workflowTools }, ]; const ALL_TOOLS: MCPTool[] = ALL_MODULES.flatMap(m => m.tools); // ============================================================================ // Tests // ============================================================================ describe('MCP Tools Deep Test Suite', () => { // -------------------------------------------------------------------------- // 1. Module Loading & Registration // -------------------------------------------------------------------------- describe('Module Loading & Registration', () => { it('should load all 24 tool modules', () => { expect(ALL_MODULES).toHaveLength(24); }); it('should have at least 100 total tools across all modules', () => { expect(ALL_TOOLS.length).toBeGreaterThanOrEqual(100); }); it('should export arrays from each module', () => { for (const mod of ALL_MODULES) { expect(Array.isArray(mod.tools)).toBe(true); expect(mod.tools.length).toBeGreaterThan(0); } }); it('should have no duplicate tool names across all modules', () => { const names = ALL_TOOLS.map(t => t.name); const uniqueNames = new Set(names); const duplicates = names.filter((n, i) => names.indexOf(n) !== i); expect(duplicates).toEqual([]); expect(uniqueNames.size).toBe(names.length); }); it('should register expected tool counts per module', () => { const minCounts: Record = { 'agent-tools': 7, 'agentdb-tools': 15, 'analyze-tools': 6, 'browser-tools': 20, 'claims-tools': 12, 'config-tools': 6, 'coordination-tools': 7, 'daa-tools': 8, 'embeddings-tools': 7, 'github-tools': 5, 'hive-mind-tools': 9, 'memory-tools': 7, 'neural-tools': 6, 'performance-tools': 6, 'progress-tools': 4, 'security-tools': 6, 'session-tools': 5, 'swarm-tools': 4, 'system-tools': 7, 'task-tools': 7, 'terminal-tools': 5, 'transfer-tools': 11, 'workflow-tools': 10, }; for (const mod of ALL_MODULES) { const min = minCounts[mod.name]; if (min !== undefined) { expect(mod.tools.length).toBeGreaterThanOrEqual(min); } } }); }); // -------------------------------------------------------------------------- // 2. Schema Validation // -------------------------------------------------------------------------- describe('Schema Validation - All Tools', () => { it('every tool has a non-empty name', () => { for (const tool of ALL_TOOLS) { expect(tool.name).toBeDefined(); expect(typeof tool.name).toBe('string'); expect(tool.name.length).toBeGreaterThan(0); } }); it('every tool has a non-empty description', () => { for (const tool of ALL_TOOLS) { expect(tool.description).toBeDefined(); expect(typeof tool.description).toBe('string'); expect(tool.description.length).toBeGreaterThan(0); } }); it('every tool has an inputSchema with type "object"', () => { for (const tool of ALL_TOOLS) { expect(tool.inputSchema).toBeDefined(); expect(tool.inputSchema.type).toBe('object'); } }); it('every tool inputSchema has a properties field', () => { for (const tool of ALL_TOOLS) { expect(tool.inputSchema.properties).toBeDefined(); expect(typeof tool.inputSchema.properties).toBe('object'); } }); it('every tool has a handler function', () => { for (const tool of ALL_TOOLS) { expect(tool.handler).toBeDefined(); expect(typeof tool.handler).toBe('function'); } }); it('required field is either absent or an array of strings', () => { for (const tool of ALL_TOOLS) { if (tool.inputSchema.required !== undefined) { expect(Array.isArray(tool.inputSchema.required)).toBe(true); for (const req of tool.inputSchema.required!) { expect(typeof req).toBe('string'); } } } }); it('required fields reference existing properties', () => { for (const tool of ALL_TOOLS) { if (tool.inputSchema.required) { const propNames = Object.keys(tool.inputSchema.properties); for (const req of tool.inputSchema.required) { expect(propNames).toContain(req); } } } }); it('tool names follow naming conventions (category_action or category_action-detail)', () => { for (const tool of ALL_TOOLS) { // Names should contain underscore or hyphen as separators // and not have spaces or special chars expect(tool.name).toMatch(/^[a-z][a-z0-9_-]+$/); } }); }); // -------------------------------------------------------------------------- // 3. Array Schema Validation - items field // -------------------------------------------------------------------------- describe('Array Schema Validation', () => { function findArrayProperties(tool: MCPTool): Array<{ toolName: string; propName: string; prop: any }> { const results: Array<{ toolName: string; propName: string; prop: any }> = []; const properties = tool.inputSchema.properties; for (const [propName, prop] of Object.entries(properties)) { const p = prop as Record; if (p.type === 'array') { results.push({ toolName: tool.name, propName, prop: p }); } } return results; } it('all array-typed properties have an items field', () => { const missingItems: string[] = []; for (const tool of ALL_TOOLS) { const arrayProps = findArrayProperties(tool); for (const { toolName, propName, prop } of arrayProps) { if (!prop.items) { missingItems.push(`${toolName}.${propName}`); } } } expect(missingItems).toEqual([]); }); it('array items field specifies a type', () => { for (const tool of ALL_TOOLS) { const arrayProps = findArrayProperties(tool); for (const { prop } of arrayProps) { if (prop.items) { expect(prop.items.type).toBeDefined(); } } } }); }); // -------------------------------------------------------------------------- // 4. Category Consistency // -------------------------------------------------------------------------- describe('Category Consistency', () => { it('tool name prefix matches category when category is set', () => { const exceptions = new Set([ 'mcp_status', // system-tools exports mcp_status 'mcp_start', // system-tools exports mcp_start (#1916 — in-process no-op) 'mcp_stop', // system-tools exports mcp_stop (#1916 — in-process no-op) 'task_summary', // system-tools exports task_summary ]); for (const tool of ALL_TOOLS) { if (tool.category && !exceptions.has(tool.name)) { const prefix = tool.name.split('_')[0].replace(/-/g, ''); const cat = tool.category.replace(/-/g, ''); // Prefix should match category (e.g., agent_spawn -> agent category) expect(prefix).toBe(cat); } } }); }); // -------------------------------------------------------------------------- // 5. Handler Invocation - Agent Tools // -------------------------------------------------------------------------- describe('Agent Tools - Handler Invocation', () => { it('agent_spawn creates an agent with required agentType', async () => { const tool = agentTools.find(t => t.name === 'agent_spawn')!; const result: any = await tool.handler({ agentType: 'coder' }); expect(result.success).toBe(true); expect(result.agentId).toBeDefined(); expect(result.agentType).toBe('coder'); }); it('agent_list returns agents array', async () => { const tool = agentTools.find(t => t.name === 'agent_list')!; const result: any = await tool.handler({}); expect(result.agents).toBeDefined(); expect(Array.isArray(result.agents)).toBe(true); }); it('agent_status returns not_found for unknown agent', async () => { const tool = agentTools.find(t => t.name === 'agent_status')!; const result: any = await tool.handler({ agentId: 'nonexistent' }); expect(result.status).toBe('not_found'); }); it('agent_terminate returns error for unknown agent', async () => { const tool = agentTools.find(t => t.name === 'agent_terminate')!; const result: any = await tool.handler({ agentId: 'nonexistent' }); expect(result.success).toBe(false); }); it('agent_pool status action returns pool info', async () => { const tool = agentTools.find(t => t.name === 'agent_pool')!; const result: any = await tool.handler({ action: 'status' }); expect(result.action).toBe('status'); expect(result.poolId).toBeDefined(); }); it('agent_health returns overall health info', async () => { const tool = agentTools.find(t => t.name === 'agent_health')!; const result: any = await tool.handler({}); expect(result.overall).toBeDefined(); }); it('agent_update returns error for unknown agent', async () => { const tool = agentTools.find(t => t.name === 'agent_update')!; const result: any = await tool.handler({ agentId: 'nonexistent' }); expect(result.success).toBe(false); }); }); // -------------------------------------------------------------------------- // 6. Handler Invocation - System Tools // -------------------------------------------------------------------------- describe('System Tools - Handler Invocation', () => { it('system_status returns version and status', async () => { const tool = systemTools.find(t => t.name === 'system_status')!; const result: any = await tool.handler({}); expect(result.version).toBeDefined(); expect(result.status).toBeDefined(); }); it('system_info returns system information', async () => { const tool = systemTools.find(t => t.name === 'system_info')!; const result: any = await tool.handler({}); expect(result.version).toBeDefined(); expect(result.platform).toBeDefined(); }); it('system_health returns health checks', async () => { const tool = systemTools.find(t => t.name === 'system_health')!; const result: any = await tool.handler({}); expect(result.overall).toBeDefined(); expect(result.checks).toBeDefined(); }); it('system_metrics returns metrics data', async () => { const tool = systemTools.find(t => t.name === 'system_metrics')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('mcp_status returns MCP server info', async () => { const tool = systemTools.find(t => t.name === 'mcp_status')!; const result: any = await tool.handler({}); expect(result.running).toBeDefined(); expect(result.transport).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 7. Handler Invocation - Config Tools // -------------------------------------------------------------------------- describe('Config Tools - Handler Invocation', () => { it('config_get returns value for known key', async () => { const tool = configTools.find(t => t.name === 'config_get')!; const result: any = await tool.handler({ key: 'logging.level' }); expect(result.key).toBe('logging.level'); expect(result.exists).toBeDefined(); }); it('config_set stores a value', async () => { const tool = configTools.find(t => t.name === 'config_set')!; const result: any = await tool.handler({ key: 'test.key', value: 'test-value' }); expect(result.success).toBe(true); }); it('config_list returns configurations', async () => { const tool = configTools.find(t => t.name === 'config_list')!; const result: any = await tool.handler({}); expect(result.configs).toBeDefined(); expect(Array.isArray(result.configs)).toBe(true); }); it('config_reset returns success', async () => { const tool = configTools.find(t => t.name === 'config_reset')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); }); it('config_export returns config data', async () => { const tool = configTools.find(t => t.name === 'config_export')!; const result: any = await tool.handler({}); expect(result.config).toBeDefined(); }); it('config_import returns success', async () => { const tool = configTools.find(t => t.name === 'config_import')!; const result: any = await tool.handler({ config: { 'test.k': 'v' } }); expect(result.success).toBe(true); }); }); // -------------------------------------------------------------------------- // 8. Handler Invocation - Swarm Tools // -------------------------------------------------------------------------- describe('Swarm Tools - Handler Invocation', () => { it('swarm_init returns swarmId and topology', async () => { const tool = swarmTools.find(t => t.name === 'swarm_init')!; const result: any = await tool.handler({ topology: 'hierarchical' }); expect(result.success).toBe(true); expect(result.swarmId).toBeDefined(); expect(result.persisted).toBe(true); }); it('swarm_status returns running status after init', async () => { // Init a swarm first so status has something to report const initTool = swarmTools.find(t => t.name === 'swarm_init')!; const initResult: any = await initTool.handler({ topology: 'mesh' }); const tool = swarmTools.find(t => t.name === 'swarm_status')!; const result: any = await tool.handler({ swarmId: initResult.swarmId }); expect(result.status).toBe('running'); }); it('swarm_shutdown returns success after init', async () => { const initTool = swarmTools.find(t => t.name === 'swarm_init')!; const initResult: any = await initTool.handler({ topology: 'hierarchical' }); const tool = swarmTools.find(t => t.name === 'swarm_shutdown')!; const result: any = await tool.handler({ swarmId: initResult.swarmId }); expect(result.success).toBe(true); expect(result.terminated).toBe(true); }); it('swarm_health returns healthy checks after init', async () => { const initTool = swarmTools.find(t => t.name === 'swarm_init')!; const initResult: any = await initTool.handler({ topology: 'hierarchical' }); const tool = swarmTools.find(t => t.name === 'swarm_health')!; const result: any = await tool.handler({ swarmId: initResult.swarmId }); expect(result.status).toBe('healthy'); expect(result.checks).toBeDefined(); expect(result.healthy).toBe(true); }); it('swarm_health returns not_found for nonexistent swarm ID', async () => { const tool = swarmTools.find(t => t.name === 'swarm_health')!; const result: any = await tool.handler({ swarmId: 'nonexistent-id-999' }); expect(result.status).toBe('not_found'); expect(result.healthy).toBe(false); expect(result.checks).toBeDefined(); }); it('swarm_init rejects invalid topology', async () => { const tool = swarmTools.find(t => t.name === 'swarm_init')!; const result: any = await tool.handler({ topology: 'invalid-topo' }); expect(result.success).toBe(false); expect(result.error).toContain('Invalid topology'); }); }); // -------------------------------------------------------------------------- // 9. Handler Invocation - Task Tools // -------------------------------------------------------------------------- describe('Task Tools - Handler Invocation', () => { it('task_create creates a task', async () => { const tool = taskTools.find(t => t.name === 'task_create')!; const result: any = await tool.handler({ type: 'feature', description: 'Test task' }); expect(result.taskId).toBeDefined(); expect(result.type).toBe('feature'); expect(result.status).toBe('pending'); }); it('task_list returns tasks array', async () => { const tool = taskTools.find(t => t.name === 'task_list')!; const result: any = await tool.handler({}); expect(result.tasks).toBeDefined(); expect(Array.isArray(result.tasks)).toBe(true); }); it('task_status returns not_found for unknown task', async () => { const tool = taskTools.find(t => t.name === 'task_status')!; const result: any = await tool.handler({ taskId: 'nonexistent' }); expect(result.status).toBe('not_found'); }); }); // -------------------------------------------------------------------------- // 10. Handler Invocation - Session Tools // -------------------------------------------------------------------------- describe('Session Tools - Handler Invocation', () => { it('session_list returns sessions', async () => { const tool = sessionTools.find(t => t.name === 'session_list')!; const result: any = await tool.handler({}); expect(result.sessions).toBeDefined(); }); it('session_save creates a session', async () => { const tool = sessionTools.find(t => t.name === 'session_save')!; const result: any = await tool.handler({ name: 'Test Session' }); expect(result.sessionId).toBeDefined(); expect(result.name).toBe('Test Session'); }); }); // -------------------------------------------------------------------------- // 11. Handler Invocation - Hive Mind Tools // -------------------------------------------------------------------------- describe('Hive Mind Tools - Handler Invocation', () => { it('hive-mind_init initializes the hive', async () => { const tool = hiveMindTools.find(t => t.name === 'hive-mind_init')!; const result: any = await tool.handler({ topology: 'mesh' }); expect(result.success).toBe(true); expect(result.topology).toBe('mesh'); }); it('hive-mind_status returns status info', async () => { const tool = hiveMindTools.find(t => t.name === 'hive-mind_status')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('hive-mind_consensus with list action returns data', async () => { const tool = hiveMindTools.find(t => t.name === 'hive-mind_consensus')!; const result: any = await tool.handler({ action: 'list' }); expect(result.action).toBe('list'); }); }); // -------------------------------------------------------------------------- // 12. Handler Invocation - Workflow Tools // -------------------------------------------------------------------------- describe('Workflow Tools - Handler Invocation', () => { it('workflow_list returns workflows', async () => { const tool = workflowTools.find(t => t.name === 'workflow_list')!; const result: any = await tool.handler({}); expect(result.workflows).toBeDefined(); }); it('workflow_create creates a workflow', async () => { const tool = workflowTools.find(t => t.name === 'workflow_create')!; const result: any = await tool.handler({ name: 'test-wf', description: 'Test workflow' }); expect(result.workflowId).toBeDefined(); expect(result.name).toBe('test-wf'); }); }); // -------------------------------------------------------------------------- // 13. Handler Invocation - DAA Tools // -------------------------------------------------------------------------- describe('DAA Tools - Handler Invocation', () => { it('daa_agent_create creates an agent', async () => { const tool = daaTools.find(t => t.name === 'daa_agent_create')!; const result: any = await tool.handler({ id: 'test-daa-1' }); expect(result.success).toBe(true); expect(result.agent.id).toBe('test-daa-1'); }); it('daa_learning_status returns summary', async () => { const tool = daaTools.find(t => t.name === 'daa_learning_status')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.summary).toBeDefined(); }); it('daa_cognitive_pattern returns patterns info', async () => { const tool = daaTools.find(t => t.name === 'daa_cognitive_pattern')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.patterns).toBeDefined(); }); it('daa_performance_metrics returns metrics', async () => { const tool = daaTools.find(t => t.name === 'daa_performance_metrics')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); }); }); // -------------------------------------------------------------------------- // 14. Handler Invocation - Coordination Tools // -------------------------------------------------------------------------- describe('Coordination Tools - Handler Invocation', () => { it('coordination_topology get action returns topology', async () => { const tool = coordinationTools.find(t => t.name === 'coordination_topology')!; const result: any = await tool.handler({ action: 'get' }); expect(result.success).toBe(true); expect(result.topology).toBeDefined(); }); it('coordination_sync status returns sync state', async () => { const tool = coordinationTools.find(t => t.name === 'coordination_sync')!; const result: any = await tool.handler({ action: 'status' }); expect(result.success).toBe(true); }); it('coordination_node list returns nodes', async () => { const tool = coordinationTools.find(t => t.name === 'coordination_node')!; const result: any = await tool.handler({ action: 'list' }); expect(result.success).toBe(true); expect(result.nodes).toBeDefined(); }); it('coordination_metrics returns metrics', async () => { const tool = coordinationTools.find(t => t.name === 'coordination_metrics')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); }); it('coordination_orchestrate accepts task', async () => { const tool = coordinationTools.find(t => t.name === 'coordination_orchestrate')!; const result: any = await tool.handler({ task: 'test task' }); expect(result.success).toBe(true); expect(result.orchestrationId).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 15. Handler Invocation - GitHub Tools // -------------------------------------------------------------------------- describe('GitHub Tools - Handler Invocation', () => { it('github_repo_analyze returns analysis', async () => { const tool = githubTools.find(t => t.name === 'github_repo_analyze')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.repository).toBeDefined(); }); it('github_pr_manage list returns PRs', async () => { const tool = githubTools.find(t => t.name === 'github_pr_manage')!; const result: any = await tool.handler({ action: 'list' }); expect(result.success).toBe(true); }); it('github_metrics returns all metrics', async () => { const tool = githubTools.find(t => t.name === 'github_metrics')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.commits).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 16. Handler Invocation - Terminal Tools // -------------------------------------------------------------------------- describe('Terminal Tools - Handler Invocation', () => { it('terminal_create creates a session', async () => { const tool = terminalTools.find(t => t.name === 'terminal_create')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.sessionId).toBeDefined(); }); it('terminal_list returns sessions', async () => { const tool = terminalTools.find(t => t.name === 'terminal_list')!; const result: any = await tool.handler({}); expect(result.sessions).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 17. Handler Invocation - Claims Tools // -------------------------------------------------------------------------- describe('Claims Tools - Handler Invocation', () => { it('claims_list returns claims', async () => { const tool = claimsTools.find(t => t.name === 'claims_list')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.claims).toBeDefined(); }); it('claims_claim with invalid claimant returns error', async () => { const tool = claimsTools.find(t => t.name === 'claims_claim')!; const result: any = await tool.handler({ issueId: 'issue-1', claimant: 'invalid' }); expect(result.success).toBe(false); expect(result.error).toContain('Invalid claimant'); }); it('claims_board returns board view', async () => { const tool = claimsTools.find(t => t.name === 'claims_board')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.board).toBeDefined(); }); it('claims_stealable returns stealable issues', async () => { const tool = claimsTools.find(t => t.name === 'claims_stealable')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); }); }); // -------------------------------------------------------------------------- // 18. Handler Invocation - Performance Tools // -------------------------------------------------------------------------- describe('Performance Tools - Handler Invocation', () => { it('performance_report returns a report', async () => { const tool = performanceTools.find(t => t.name === 'performance_report')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('performance_metrics returns metrics', async () => { const tool = performanceTools.find(t => t.name === 'performance_metrics')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('performance_benchmark runs a benchmark', async () => { const tool = performanceTools.find(t => t.name === 'performance_benchmark')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 19. Handler Invocation - Neural Tools // -------------------------------------------------------------------------- describe('Neural Tools - Handler Invocation', () => { it('neural_status returns status', async () => { const tool = neuralTools.find(t => t.name === 'neural_status')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('neural_patterns returns patterns list', async () => { const tool = neuralTools.find(t => t.name === 'neural_patterns')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 20. Handler Invocation - AgentDB Tools // -------------------------------------------------------------------------- describe('AgentDB Tools - Handler Invocation', () => { it('agentdb_health returns availability', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_health')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('agentdb_controllers returns controllers list', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_controllers')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('agentdb_pattern-store requires pattern param', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-store')!; const result: any = await tool.handler({}); expect(result.success).toBe(false); expect(result.error).toMatch(/pattern.*(required|must be)/i); }); it('agentdb_pattern-search requires query param', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-search')!; const result: any = await tool.handler({}); expect(result.error).toMatch(/query.*(required|must be)/i); }); it('agentdb_causal-edge validates required fields', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_causal-edge')!; const result: any = await tool.handler({}); expect(result.success).toBe(false); }); it('agentdb_route requires task param', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_route')!; const result: any = await tool.handler({}); expect(result.error).toMatch(/task.*(required|must be)/i); }); it('agentdb_batch validates entries array', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_batch')!; const result: any = await tool.handler({ operation: 'insert' }); expect(result.success).toBe(false); expect(result.error).toContain('entries is required'); }); it('agentdb_batch validates operation type', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_batch')!; const result: any = await tool.handler({ operation: 'invalid', entries: [{ key: 'k' }] }); expect(result.success).toBe(false); expect(result.error).toContain('Invalid operation'); }); }); // -------------------------------------------------------------------------- // 21. Error Handling // -------------------------------------------------------------------------- describe('Error Handling', () => { it('tools handle empty input gracefully', async () => { // Test a selection of tools with empty input const toolsToTest = [ agentTools.find(t => t.name === 'agent_list')!, configTools.find(t => t.name === 'config_list')!, swarmTools.find(t => t.name === 'swarm_status')!, taskTools.find(t => t.name === 'task_list')!, daaTools.find(t => t.name === 'daa_learning_status')!, coordinationTools.find(t => t.name === 'coordination_metrics')!, performanceTools.find(t => t.name === 'performance_report')!, ]; for (const tool of toolsToTest) { const result = await tool.handler({}); expect(result).toBeDefined(); } }); it('tools do not throw on invalid input types', async () => { // These should return errors gracefully instead of throwing const tool = agentTools.find(t => t.name === 'agent_spawn')!; // Pass number instead of string for agentType const result: any = await tool.handler({ agentType: 123 as any }); // Should still succeed - type coercion expect(result).toBeDefined(); }); it('agentdb tools validate string inputs', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-store')!; // Empty string should fail validation const result: any = await tool.handler({ pattern: '' }); expect(result.success).toBe(false); }); it('agentdb tools enforce max string length', async () => { const tool = agentdbTools.find(t => t.name === 'agentdb_feedback')!; // Very long taskId should be rejected const longId = 'x'.repeat(1000); const result: any = await tool.handler({ taskId: longId }); expect(result.success).toBe(false); }); }); // -------------------------------------------------------------------------- // 22. Security Checks // -------------------------------------------------------------------------- describe('Security Checks', () => { it('no tool schemas contain hardcoded paths', () => { for (const tool of ALL_TOOLS) { const schema = JSON.stringify(tool.inputSchema); expect(schema).not.toContain('/home/'); expect(schema).not.toContain('/etc/'); expect(schema).not.toContain('C:\\'); } }); it('no tool schemas contain hardcoded secrets or tokens', () => { for (const tool of ALL_TOOLS) { const schema = JSON.stringify(tool.inputSchema); expect(schema).not.toMatch(/sk-[a-zA-Z0-9]{20,}/); expect(schema).not.toMatch(/password.*=.*[a-zA-Z0-9]{8,}/i); } }); it('no tool names expose internal implementation details', () => { for (const tool of ALL_TOOLS) { expect(tool.name).not.toContain('internal'); expect(tool.name).not.toContain('debug'); expect(tool.name).not.toContain('_raw'); } }); it('session tools sanitize sessionId against path traversal', () => { // session_save should handle path traversal attempts const tool = sessionTools.find(t => t.name === 'session_save')!; // The session file path should be sanitized expect(tool).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 23. Return Format Consistency // -------------------------------------------------------------------------- describe('Return Format Consistency', () => { it('agent_spawn returns success field', async () => { const tool = agentTools.find(t => t.name === 'agent_spawn')!; const result: any = await tool.handler({ agentType: 'coder' }); expect(typeof result.success).toBe('boolean'); }); it('config tools return success field', async () => { const setTool = configTools.find(t => t.name === 'config_set')!; const result: any = await setTool.handler({ key: 'test', value: 'v' }); expect(typeof result.success).toBe('boolean'); }); it('task_create returns taskId and status', async () => { const tool = taskTools.find(t => t.name === 'task_create')!; const result: any = await tool.handler({ type: 'bugfix', description: 'Fix the bug' }); expect(result.taskId).toBeDefined(); expect(typeof result.taskId).toBe('string'); expect(result.status).toBe('pending'); }); it('swarm_init returns success and swarmId', async () => { const tool = swarmTools.find(t => t.name === 'swarm_init')!; const result: any = await tool.handler({}); expect(result.success).toBe(true); expect(result.swarmId).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 24. Progress & Embeddings Tools // -------------------------------------------------------------------------- describe('Progress Tools - Handler Invocation', () => { it('progress_check returns progress metrics', async () => { const tool = progressTools.find(t => t.name === 'progress_check')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('progress_summary returns summary', async () => { const tool = progressTools.find(t => t.name === 'progress_summary')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result).toBeDefined(); }); }); describe('Embeddings Tools - Handler Invocation', () => { it('embeddings_status returns initialization state', async () => { const tool = embeddingsTools.find(t => t.name === 'embeddings_status')!; const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('embeddings_init initializes the subsystem', async () => { const tool = embeddingsTools.find(t => t.name === 'embeddings_init')!; const result: any = await tool.handler({ force: true }); expect(result.success).toBe(true); }); }); // -------------------------------------------------------------------------- // 25. Hooks Tools // -------------------------------------------------------------------------- describe('Hooks Tools - Handler Invocation', () => { it('hooks_list returns hooks list', async () => { const tool = hooksTools.find(t => t.name === 'hooks_list')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result.hooks).toBeDefined(); }); it('hooks_metrics returns metrics', async () => { const tool = hooksTools.find(t => t.name === 'hooks_metrics')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('hooks_worker-list returns workers', async () => { const tool = hooksTools.find(t => t.name === 'hooks_worker-list')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result.workers).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 26. Memory Tools // -------------------------------------------------------------------------- describe('Memory Tools - Handler Invocation', () => { it('memory_store stores an entry', async () => { const tool = memoryTools.find(t => t.name === 'memory_store')!; expect(tool).toBeDefined(); const result: any = await tool.handler({ key: 'test-key', value: 'test-value' }); expect(result).toBeDefined(); }); it('memory_list returns entries', async () => { const tool = memoryTools.find(t => t.name === 'memory_list')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result).toBeDefined(); }); it('memory_stats returns statistics', async () => { const tool = memoryTools.find(t => t.name === 'memory_stats')!; expect(tool).toBeDefined(); const result: any = await tool.handler({}); expect(result).toBeDefined(); }); }); // -------------------------------------------------------------------------- // 27. Cross-Module Integrity // -------------------------------------------------------------------------- describe('Cross-Module Integrity', () => { it('all tool names are valid MCP tool identifiers', () => { for (const tool of ALL_TOOLS) { // MCP tool names should be alphanumeric with underscores/hyphens expect(tool.name).toMatch(/^[a-z][a-z0-9_-]*$/); // No double underscores or hyphens expect(tool.name).not.toMatch(/__/); expect(tool.name).not.toMatch(/--/); } }); it('all descriptions are human-readable sentences', () => { for (const tool of ALL_TOOLS) { // Description should start with uppercase or lowercase letter expect(tool.description).toMatch(/^[A-Za-z]/); // Should be at least 10 characters expect(tool.description.length).toBeGreaterThanOrEqual(10); } }); it('no tool has an empty properties object with required fields', () => { for (const tool of ALL_TOOLS) { if (tool.inputSchema.required && tool.inputSchema.required.length > 0) { const propCount = Object.keys(tool.inputSchema.properties).length; expect(propCount).toBeGreaterThan(0); } } }); it('every property in schema has a type or description', () => { for (const tool of ALL_TOOLS) { for (const [propName, prop] of Object.entries(tool.inputSchema.properties)) { const p = prop as Record; // Every property should have at least a type or description const hasType = p.type !== undefined; const hasDesc = p.description !== undefined; expect(hasType || hasDesc).toBe(true); } } }); }); });