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
JavaScript
/**
* 企业级分层架构的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();