UNPKG

orchestry-mcp

Version:

Orchestry MCP Server for multi-session task management

155 lines (133 loc) 4.15 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import express from 'express'; import { createServer } from 'http'; import { Server as SocketIOServer } from 'socket.io'; import cors from 'cors'; import { Database } from './database.js'; import { DatabaseManager } from './database-manager.js'; import { OrchestryTools } from './tools/index.js'; import { setupAPI } from './api/index.js'; import { z } from 'zod'; export class OrchestryServer { private mcpServer: Server; private expressApp: express.Application; private httpServer: any; private io: SocketIOServer; private db: Database; private dbManager: DatabaseManager; private tools: OrchestryTools; private port: number; constructor(port?: number) { this.port = port || parseInt(process.env.API_PORT || '7531'); // MCP 서버 초기화 this.mcpServer = new Server( { name: 'orchestry', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); // Express 앱 초기화 this.expressApp = express(); this.expressApp.use(cors()); this.expressApp.use(express.json()); // HTTP 서버와 Socket.IO 초기화 this.httpServer = createServer(this.expressApp); this.io = new SocketIOServer(this.httpServer, { cors: { origin: '*', methods: ['GET', 'POST'], }, }); // 데이터베이스 초기화 this.db = new Database(); this.dbManager = new DatabaseManager(); // 도구 초기화 (DatabaseManager 사용) this.tools = new OrchestryTools(this.dbManager, this.io); } async initialize() { // 데이터베이스 초기화 await this.db.initialize(); // MCP 도구 등록 this.registerMCPTools(); // REST API 설정 setupAPI(this.expressApp, this.db, this.io); // WebSocket 연결 처리 this.setupWebSocket(); // 웹 서버 시작 (웹 모드일 때만) if (process.env.RUN_MODE === 'web') { this.httpServer.listen(this.port, () => { console.error(`Web UI available at http://localhost:${this.port}`); }); } } private registerMCPTools() { // 도구 목록 제공 this.mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: this.tools.getToolDefinitions(), })); // 도구 실행 처리 this.mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { const result = await this.tools.executeTool(name, args); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } }); } private setupWebSocket() { this.io.on('connection', (socket) => { console.error('Client connected:', socket.id); socket.on('subscribe', (projectId: string) => { socket.join(`project:${projectId}`); }); socket.on('unsubscribe', (projectId: string) => { socket.leave(`project:${projectId}`); }); socket.on('disconnect', () => { console.error('Client disconnected:', socket.id); }); }); } async run() { await this.initialize(); // stdio 모드로 MCP 서버 실행 (기본값) if (process.env.RUN_MODE !== 'web') { const transport = new StdioServerTransport(); await this.mcpServer.connect(transport); console.error('Orchestry MCP Server running in stdio mode'); } } } // 메인 실행 const server = new OrchestryServer(); server.run().catch((error) => { console.error('Server error:', error); process.exit(1); });