UNPKG

@uplinq/mcp-vitest

Version:

MCP server for Vitest with watch-mode support for fast test feedback

126 lines 5.09 kB
#!/usr/bin/env node import { detectTransport, getTransportDescription } from './utils/transport-detector.js'; import { createVitestMCPServer } from './server.js'; import { program } from 'commander'; import packageJson from '../package.json' with { type: 'json' }; import { log, error, setStdioTransport } from './utils/logger.js'; /** * Main entry point for the MCP Vitest server */ async function main() { // Setup CLI program .name('@uplinq/mcp-vitest') .description('MCP server for Vitest with watch-mode support') .version(packageJson.version, '-v, --version', 'display version number') .option('--stdio', 'force stdio transport (default)') .option('--sse <port>', 'use SSE transport on specified port') .option('--http <port>', 'use HTTP stream transport on specified port') .parse(); const options = program.opts(); try { // Detect transport configuration let transportConfig; if (options.stdio) { transportConfig = { transportType: 'stdio' }; } else if (options.sse) { const port = parseInt(options.sse); if (isNaN(port)) { error('Error: SSE port must be a valid number'); process.exit(1); } transportConfig = { transportType: 'sse', sse: { port } }; } else if (options.http) { const port = parseInt(options.http); if (isNaN(port)) { error('Error: HTTP port must be a valid number'); process.exit(1); } transportConfig = { transportType: 'httpStream', httpStream: { port } }; } else { // Auto-detect from environment transportConfig = await detectTransport(); } // Set stdio transport flag for logger setStdioTransport(transportConfig.transportType === 'stdio'); log(`Starting MCP Vitest server with ${getTransportDescription(transportConfig)}...`); // Create the FastMCP server const server = await createVitestMCPServer(transportConfig.transportType); // Start the server with the detected transport configuration log('Starting server...'); switch (transportConfig.transportType) { case 'sse': if (!transportConfig.sse?.port) { error('Error: SSE port not configured'); process.exit(1); } await server.start({ transportType: 'sse', sse: { port: transportConfig.sse.port, endpoint: '/sse' } }); log(`🚀 MCP Vitest server running on SSE port ${transportConfig.sse.port}`); break; case 'httpStream': if (!transportConfig.httpStream?.port) { error('Error: HTTP Stream port not configured'); process.exit(1); } await server.start({ transportType: 'httpStream', httpStream: { port: transportConfig.httpStream.port, endpoint: '/stream' } }); log(`🚀 MCP Vitest server running on HTTP Stream port ${transportConfig.httpStream.port}`); break; case 'stdio': default: await server.start({ transportType: 'stdio' }); log('🚀 MCP Vitest server running on stdio'); break; } // Log helpful information log(''); log('Available MCP tools:'); log(' • get_test_status - Get comprehensive test results'); log(' • get_failing_tests - Get detailed information about failing tests'); log(' • get_vitest_status - Get Vitest manager status'); log(''); log('Server is now ready to accept connections...'); // Keep the process alive - the server is now running and will handle transport communication // No need for manual process.keepAlive since server.start() handles this } catch (err) { error('Failed to start server:', err); process.exit(1); } } // Handle unhandled promise rejections process.on('unhandledRejection', (reason, promise) => { error('Unhandled Rejection at:', promise, 'reason:', reason); process.exit(1); }); // Handle uncaught exceptions process.on('uncaughtException', (err) => { error('Uncaught Exception:', err); process.exit(1); }); // Start the server // Check if this module is being executed directly (works with npm bin wrappers) const isMainModule = process.argv[1].endsWith('/mcp-vitest') || import.meta.url === `file://${process.argv[1]}`; if (isMainModule) { main().catch((err) => { error('Fatal error:', err); process.exit(1); }); } //# sourceMappingURL=index.js.map