import { resolve } from 'node:path';
import { describe, expect, it } from 'vitest';
import { z } from 'zod';
import { ToolRegistry } from '../src/mcp/registry.js';
import type { ToolDefinition } from '../src/mcp/tools/baseTool.js';
const inputSchema = z.object({ payload: z.string().optional() });
const makeTool = (name: string): ToolDefinition<typeof inputSchema, string> => ({
name,
description: 'test tool',
inputSchema,
execute() {
return Promise.resolve({ success: true, data: 'ok' });
},
});
describe('ToolRegistry', () => {
it('registers and lists tools', () => {
const registry = new ToolRegistry();
registry.register(makeTool('alpha'));
registry.register(makeTool('beta'));
const names = registry.list().map((tool) => tool.name);
expect(names).toEqual(['alpha', 'beta']);
});
it('throws on duplicate registration', () => {
const registry = new ToolRegistry();
registry.register(makeTool('dup'));
expect(() => registry.register(makeTool('dup'))).toThrowError(/already registered/i);
});
it('loads tools from modules', async () => {
const registry = new ToolRegistry();
const modulePath = resolve('tests/fixtures/mockTool.js');
const loaded = await registry.loadFromModules([modulePath]);
expect(loaded).toHaveLength(1);
expect(loaded[0].name).toBe('fixture_tool');
expect(registry.get('fixture_tool')).toBeDefined();
});
});