UNPKG

fu-orm-code-generator

Version:

A Model Context Protocol (MCP) server for MyBatis code generation with enterprise-grade layered architecture

171 lines (141 loc) 4.57 kB
#!/usr/bin/env node /** * 企业级分层架构的MCP服务器主入口 * 使用依赖注入和分层架构设计 */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import process from "node:process"; import { createContainer } from './infrastructure/di/Container.js'; import { config } from './config/index.js'; import { ErrorHandler } from './common/errors/index.js'; import { createLogger } from './infrastructure/logging/Logger.js'; // 创建应用日志记录器 const logger = createLogger('MCPServer'); /** * 工具处理器名称映射 */ const TOOL_HANDLERS = [ // 模板管理工具 'visitOnlineTemplatesHandler', 'downloadOnlineTemplateHandler', 'chooseLocalTemplateHandler', 'visitLocalTemplatesHandler', 'editLocalTemplatesHandler', // 用户信息管理工具 'setUserInfoHandler', 'getUserInfoHandler', // 表前缀管理工具 'setTablePrefixHandler', 'getTablePrefixHandler', // 代码生成工具 'generateOrmCodeHandler' ]; /** * 加载并注册所有工具 * @param {import('./infrastructure/di/Container.js').Container} container - 依赖注入容器 * @returns {Array} 工具配置列表 */ async function loadTools(container) { const tools = []; try { for (const handlerName of TOOL_HANDLERS) { try { const handler = container.resolve(handlerName); const toolConfig = handler.getToolConfig(); // 验证工具配置 if (!toolConfig.name || !toolConfig.config || !toolConfig.handler) { logger.error(`Invalid tool configuration from handler: ${handlerName}`); continue; } tools.push(toolConfig); } catch (error) { logger.error(`Failed to load tool handler ${handlerName}`, error); // 继续加载其他工具,不因单个工具失败而停止整个服务 } } logger.info(`MCP Server loaded ${tools.length} tools`); return tools; } catch (error) { logger.error('Failed to load tools', error); throw error; } } /** * 初始化MCP服务器 * @returns {Promise<McpServer>} MCP服务器实例 */ async function createMcpServer() { try { // 创建依赖注入容器 const container = await createContainer(); // 加载工具 const tools = await loadTools(container); if (tools.length === 0) { throw new Error('No tools were loaded successfully'); } // 创建MCP服务器 const server = new McpServer({ name: config.app.name, version: config.app.version }); // 注册工具 tools.forEach(tool => { try { server.registerTool(tool.name, { title: tool.config.title, description: tool.config.description, inputSchema: tool.config.inputSchema }, tool.handler); } catch (error) { logger.error(`Failed to register tool ${tool.name}`, error); } }); return server; } catch (error) { logger.error('Failed to initialize MCP server', error); ErrorHandler.log(error, { operation: 'initializeMcpServer' }); throw error; } } /** * 启动MCP服务器 */ async function startServer() { try { logger.info(`Environment: ${config.app.env}`); const server = await createMcpServer(); // 启动 stdio 通信 const transport = new StdioServerTransport(); await server.connect(transport); logger.info('MCP Server started successfully'); // 优雅关闭处理 const gracefulShutdown = (signal) => { logger.info(`Received ${signal}, shutting down gracefully...`); process.exit(0); }; process.on('SIGINT', () => gracefulShutdown('SIGINT')); process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); } catch (error) { logger.error('Failed to start MCP server', error); ErrorHandler.log(error, { operation: 'startServer' }); process.exit(1); } } /** * 全局异常处理 */ process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled Promise Rejection', null, { promise, reason }); ErrorHandler.log(new Error(`Unhandled Rejection: ${reason}`), { operation: 'unhandledRejection', promise: promise.toString() }); }); process.on('uncaughtException', (error) => { logger.error('Uncaught Exception', error); ErrorHandler.log(error, { operation: 'uncaughtException' }); process.exit(1); }); // 启动服务器 startServer();