/**
* Server Tool Definition Tests
*
* Tests for MCPServer's tool definition exposure
*/
import { describe, it, expect, beforeEach } from 'vitest';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { MCPServer } from '../../src/server.js';
describe('MCPServer Tool Definitions', () => {
let mcpServer: MCPServer;
let sdkServer: Server;
beforeEach(() => {
sdkServer = new Server(
{
name: 'test-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
logging: {},
},
}
);
mcpServer = new MCPServer(sdkServer);
});
describe('getToolDefinitions', () => {
it('should return tool definitions', () => {
const tools = mcpServer.getToolDefinitions();
expect(tools).toBeDefined();
expect(Array.isArray(tools)).toBe(true);
});
it('should return at least one tool', () => {
const tools = mcpServer.getToolDefinitions();
expect(tools.length).toBeGreaterThan(0);
});
it('should return get-population tool', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
expect(populationTool).toBeDefined();
expect(populationTool?.name).toBe('get-population');
});
it('should have proper tool structure', () => {
const tools = mcpServer.getToolDefinitions();
const tool = tools[0];
expect(tool).toHaveProperty('name');
expect(tool).toHaveProperty('description');
expect(tool).toHaveProperty('inputSchema');
expect(typeof tool.name).toBe('string');
expect(typeof tool.description).toBe('string');
expect(typeof tool.inputSchema).toBe('object');
});
it('should have valid inputSchema structure', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
expect(populationTool?.inputSchema).toHaveProperty('type');
expect(populationTool?.inputSchema).toHaveProperty('properties');
expect(populationTool?.inputSchema.type).toBe('object');
});
it('should have states parameter in get-population tool', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
expect(populationTool?.inputSchema.properties).toHaveProperty('states');
expect(populationTool?.inputSchema.properties.states.type).toBe('array');
});
it('should mark states as required in get-population tool', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
expect(populationTool?.inputSchema.required).toBeDefined();
expect(populationTool?.inputSchema.required).toContain('states');
});
it('should have FIPS description in states parameter', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
const statesParam = populationTool?.inputSchema.properties.states;
expect(statesParam?.description).toBeDefined();
expect(statesParam?.description).toContain('FIPS');
});
it('should return readonly array', () => {
const tools = mcpServer.getToolDefinitions();
// Test that it's a proper array
expect(Array.isArray(tools)).toBe(true);
expect(tools.length).toBeGreaterThanOrEqual(1);
});
it('should return consistent tool definitions on multiple calls', () => {
const tools1 = mcpServer.getToolDefinitions();
const tools2 = mcpServer.getToolDefinitions();
expect(tools1.length).toBe(tools2.length);
expect(tools1[0].name).toBe(tools2[0].name);
});
});
describe('Tool Definition Content', () => {
it('should have descriptive tool names', () => {
const tools = mcpServer.getToolDefinitions();
tools.forEach(tool => {
expect(tool.name).toBeTruthy();
expect(tool.name.length).toBeGreaterThan(0);
// Tool names should be kebab-case
expect(tool.name).toMatch(/^[a-z]+(-[a-z]+)*$/);
});
});
it('should have meaningful descriptions', () => {
const tools = mcpServer.getToolDefinitions();
tools.forEach(tool => {
expect(tool.description).toBeTruthy();
expect(tool.description.length).toBeGreaterThan(10);
});
});
it('should have well-formed schemas', () => {
const tools = mcpServer.getToolDefinitions();
tools.forEach(tool => {
expect(tool.inputSchema.type).toBe('object');
expect(tool.inputSchema.properties).toBeDefined();
expect(typeof tool.inputSchema.properties).toBe('object');
});
});
it('should have proper array item definitions for array parameters', () => {
const tools = mcpServer.getToolDefinitions();
const populationTool = tools.find(t => t.name === 'get-population');
const statesParam = populationTool?.inputSchema.properties.states;
expect(statesParam?.items).toBeDefined();
// JSON Schema uses 'integer' for whole numbers
expect(statesParam?.items.type).toBe('integer');
});
});
});