Skip to main content
Glama

CTS MCP Server

by EricA1019
server.test.tsโ€ข7.04 kB
import { describe, test, expect, beforeEach } from '@jest/globals'; import { CTSMCPServer } from '../server'; import type { MCPRequest } from '../types'; describe('CTSMCPServer - Unit Tests', () => { let server: CTSMCPServer; beforeEach(() => { server = new CTSMCPServer(); }); describe('Server Initialization', () => { test('should initialize successfully', () => { expect(server).toBeDefined(); expect(server).toBeInstanceOf(CTSMCPServer); }); test('should have correct server info', () => { const serverInfo = (server as any).serverInfo; expect(serverInfo.name).toBe('cts-mcp-server'); expect(serverInfo.version).toBe('1.0.0'); }); test('should register tools on construction', () => { const tools = (server as any).tools; expect(tools.size).toBeGreaterThan(0); }); }); describe('MCP Protocol Handling', () => { test('should handle initialize request', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '0.1.0', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } } }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 1); expect(response).toHaveProperty('result'); expect(response.result).toHaveProperty('protocolVersion'); expect(response.result).toHaveProperty('serverInfo'); expect((response.result as any).serverInfo.name).toBe('cts-mcp-server'); }); test('should handle tools/list request', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 2); expect(response).toHaveProperty('result'); expect(response.result).toHaveProperty('tools'); expect(Array.isArray((response.result as any).tools)).toBe(true); expect((response.result as any).tools.length).toBeGreaterThan(0); }); test('should list all registered tools', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 3, method: 'tools/list', params: {} }; const response = await server.handleMessage(request); const tools = (response.result as any).tools; const toolNames = tools.map((t: any) => t.name); expect(toolNames).toContain('CTS_Export_to_Shrimp'); expect(toolNames).toContain('CTS_Render_Artifact'); expect(toolNames).toContain('CTS_Scan_Project_Signals'); }); test('should handle invalid method gracefully', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 4, method: 'invalid/method', params: {} }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 4); expect(response).toHaveProperty('error'); expect(response.error).toHaveProperty('code'); expect(response.error).toHaveProperty('message'); }); test('should handle malformed request', async () => { const request = { jsonrpc: '2.0', // Missing id and method params: {} } as any; const response = await server.handleMessage(request); expect(response).toHaveProperty('error'); }); }); describe('Tool Routing', () => { test('should route CTS_Export_to_Shrimp tool', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 5, method: 'tools/call', params: { name: 'CTS_Export_to_Shrimp', arguments: { hopPlanJson: JSON.stringify({ phases: [{ name: 'Test Phase', hops: [{ id: '1.1', name: 'Test Hop', description: 'Test description', estimatedLOC: 100, dependencies: [] }] }] }) } } }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 5); // May have error if Shrimp not running, but should route correctly expect(response).toHaveProperty('result'); }); test('should route CTS_Render_Artifact tool', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 6, method: 'tools/call', params: { name: 'CTS_Render_Artifact', arguments: { artifactType: 'hop_dashboard', data: JSON.stringify({ phases: [], statistics: { totalLOC: 0, plannedLOC: 0, complianceRate: 100, completionRate: 0 } }) } } }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 6); expect(response).toHaveProperty('result'); expect(response.result).toHaveProperty('content'); }); test('should handle unknown tool name', async () => { const request: MCPRequest = { jsonrpc: '2.0', id: 7, method: 'tools/call', params: { name: 'Unknown_Tool', arguments: {} } }; const response = await server.handleMessage(request); expect(response).toHaveProperty('id', 7); expect(response).toHaveProperty('error'); expect(response.error).toBeDefined(); expect(response.error?.message).toContain('not found'); }); }); describe('Performance', () => { test('should start in under 2 seconds', async () => { const start = Date.now(); const newServer = new CTSMCPServer(); await newServer.handleMessage({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '0.1.0', capabilities: {}, clientInfo: { name: 'test', version: '1.0.0' } } }); const elapsed = Date.now() - start; expect(elapsed).toBeLessThan(2000); }); test('should handle multiple requests concurrently', async () => { const requests = Array.from({ length: 10 }, (_, i) => ({ jsonrpc: '2.0' as const, id: i, method: 'tools/list', params: {} })); const start = Date.now(); const responses = await Promise.all( requests.map(req => server.handleMessage(req)) ); const elapsed = Date.now() - start; expect(responses).toHaveLength(10); responses.forEach((res: any, i: number) => { expect(res).toHaveProperty('id', i); expect(res).toHaveProperty('result'); }); expect(elapsed).toBeLessThan(500); // All 10 requests under 500ms }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EricA1019/CTS_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server