/**
* MCP串口工具主入口文件
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import { logger } from '@/utils/logger';
import { ConfigManager } from '@/utils/config-manager';
import { MCPServer } from '@/mcp/MCPServer';
import { SerialEngine } from '@/core/SerialEngine';
import { PlatformAdapter } from '@/adapters/PlatformAdapter';
import { SerialService } from '@/services/SerialService';
/**
* 解析命令行参数
*/
function parseArgs(): { config?: string } {
const args: { config?: string } = {};
const argv = process.argv.slice(2);
for (let i = 0; i < argv.length; i++) {
if (argv[i] === '--config' && i + 1 < argv.length) {
// 处理可能的引号和Windows路径
let configPath = argv[i + 1];
// 移除引号(如果存在)
configPath = configPath.replace(/^["']|["']$/g, '');
args.config = configPath;
break;
}
}
return args;
}
/**
* 应用程序主类
*/
export class MCP2SerialApp {
private configManager: ConfigManager;
private mcpServer: MCPServer;
private server: Server;
private transport: StdioServerTransport;
private serialEngine: SerialEngine;
private platformAdapter: PlatformAdapter;
private serialService: SerialService;
private isRunning: boolean = false;
constructor() {
this.configManager = new ConfigManager();
// 初始化底层服务
this.platformAdapter = new PlatformAdapter();
this.serialEngine = new SerialEngine();
this.serialService = new SerialService(this.serialEngine, this.platformAdapter);
// 初始化MCPServer并注入依赖
this.mcpServer = new MCPServer(undefined, {
serialService: this.serialService
});
this.server = new Server(
{
name: 'mcp2serial',
version: '1.0.0',
capabilities: {
tools: {},
resources: {},
prompts: {}
}
} as any
);
this.transport = new StdioServerTransport();
}
/**
* 启动应用程序
*/
async start(configPath?: string): Promise<void> {
try {
console.log('Starting MCP2Serial application...');
// 加载配置
console.log('Loading configuration...');
await this.configManager.loadConfig(configPath);
// 初始化底层服务
console.log('Initializing services...');
await this.serialEngine.initialize();
// 启动MCP服务器
console.log('Starting MCP server...');
await this.mcpServer.start();
// 注册所有MCP标准方法到MCP SDK Server
await this.registerAllMcpMethods();
// 连接服务器到传输层
console.log('Connecting to transport layer...');
await this.server.connect(this.transport);
this.isRunning = true;
console.log('MCP2Serial application started successfully and listening...');
} catch (error) {
console.error('Error during application start:', error);
throw error;
}
}
/**
* 注册所有MCP标准方法到SDK Server
*/
private async registerAllMcpMethods(): Promise<void> {
// 注册工具列表
this.server.setRequestHandler(
z.object({ method: z.literal('tools/list') }),
async () => {
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/list',
params: {}
});
return {
tools: response.result.tools || response.result
};
}
);
// 注册工具调用
this.server.setRequestHandler(
z.object({
method: z.literal('tools/call'),
params: z.object({
name: z.string(),
arguments: z.record(z.unknown()).optional()
})
}),
async (request: any) => {
const { name, arguments: args } = request.params;
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: { name, arguments: args || {} }
});
return {
content: [{
type: 'text',
text: JSON.stringify(response.result)
}]
};
}
);
// 注册资源列表
this.server.setRequestHandler(
z.object({ method: z.literal('resources/list') }),
async () => {
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'resources/list',
params: {}
});
return {
resources: response.result.resources || response.result
};
}
);
// 注册资源读取
this.server.setRequestHandler(
z.object({
method: z.literal('resources/read'),
params: z.object({
uri: z.string()
})
}),
async (request: any) => {
const { uri } = request.params;
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'resources/read',
params: { uri }
});
return {
contents: [{
uri,
mimeType: 'application/json',
text: JSON.stringify(response.result)
}]
};
}
);
// 注册提示列表
this.server.setRequestHandler(
z.object({ method: z.literal('prompts/list') }),
async () => {
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'prompts/list',
params: {}
});
return {
prompts: response.result.prompts || response.result
};
}
);
// 注册提示获取
this.server.setRequestHandler(
z.object({
method: z.literal('prompts/get'),
params: z.object({
name: z.string(),
arguments: z.record(z.unknown()).optional()
})
}),
async (request: any) => {
const { name, arguments: args } = request.params;
const response = await this.mcpServer.handleRequest('sdk-client', {
jsonrpc: '2.0',
id: Date.now(),
method: 'prompts/get',
params: { name, arguments: args || {} }
});
return {
messages: response.result
};
}
);
}
/**
* 停止应用程序
*/
async stop(): Promise<void> {
try {
if (!this.isRunning) {
return;
}
// 停止MCP服务器
await this.mcpServer.stop();
// 关闭传输层
await this.transport.close();
this.isRunning = false;
} catch (error) {
throw error;
}
}
/**
* 获取运行状态
*/
isStarted(): boolean {
return this.isRunning;
}
}
/**
* 主函数
*/
async function main(): Promise<void> {
// 解析命令行参数
const args = parseArgs();
const app = new MCP2SerialApp();
// 处理进程信号
process.on('SIGINT', async () => {
await app.stop();
process.exit(0);
});
process.on('SIGTERM', async () => {
await app.stop();
process.exit(0);
});
// 处理未捕获的异常
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection:', reason);
process.exit(1);
});
try {
await app.start(args.config);
console.log('MCP2Serial app started successfully');
console.log('Server is now running and waiting for client connections...');
// 保持程序运行,等待客户端连接
// 对于stdio传输,服务器应该持续运行等待输入
if (app.isStarted()) {
// 监听传输层错误,如果传输层关闭则退出
const appInstance = app as any;
if (appInstance.transport) {
appInstance.transport.onclose = () => {
console.log('Transport connection closed');
process.exit(0);
};
appInstance.transport.onerror = (error: Error) => {
console.error('Transport error:', error);
process.exit(1);
};
}
}
} catch (error) {
console.error('Failed to start MCP2Serial app:', error);
process.exit(1);
}
}
// 如果直接运行此文件,则执行主函数
if (require.main === module) {
main().catch(() => {
process.exit(1);
});
}
export default main;