orchestry-mcp
Version:
Orchestry MCP Server for multi-session task management
138 lines (113 loc) • 3.76 kB
text/typescript
import { spawn } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { createServer } from 'http';
import express from 'express';
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';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
async function startWebDashboard() {
const app = express();
app.use(cors());
app.use(express.json());
const httpServer = createServer(app);
const io = new SocketIOServer(httpServer, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
const db = new Database();
await db.initialize();
const dbManager = new DatabaseManager();
const tools = new OrchestryTools(dbManager, io);
setupAPI(app, db, io);
// WebSocket setup
io.on('connection', (socket) => {
console.error('Client connected:', socket.id);
socket.on('disconnect', () => {
console.error('Client disconnected:', socket.id);
});
});
const API_PORT = parseInt(process.env.API_PORT || '7531');
return new Promise((resolve) => {
httpServer.listen(API_PORT, () => {
console.error(`✅ Web API Server started at http://localhost:${API_PORT}`);
resolve(httpServer);
});
});
}
async function startViteDevServer() {
const WEB_PORT = parseInt(process.env.WEB_PORT || '7530');
// Vite dev server 시작
const viteProcess = spawn('npm', ['run', 'dev'], {
cwd: path.join(__dirname, '..', '..', 'web'),
stdio: ['ignore', 'pipe', 'pipe'],
});
return new Promise((resolve) => {
viteProcess.stdout?.on('data', (data) => {
const output = data.toString();
if (output.includes('Local:')) {
console.error(`✅ Web UI started at http://localhost:${WEB_PORT}`);
resolve(viteProcess);
}
});
viteProcess.stderr?.on('data', (data) => {
console.error(`[Vite Error] ${data}`);
});
// Timeout after 10 seconds
setTimeout(() => {
console.error(`✅ Web UI should be available at http://localhost:${WEB_PORT}`);
resolve(viteProcess);
}, 10000);
});
}
async function openBrowser(url: string) {
const platform = process.platform;
let command: string;
if (platform === 'darwin') {
command = `open ${url}`;
} else if (platform === 'win32') {
command = `start ${url}`;
} else {
command = `xdg-open ${url}`;
}
spawn(command, [], { shell: true, detached: true }).unref();
}
async function startOrchestry() {
console.error('🚀 Starting Orchestry with Web UI...');
try {
// 1. Start Web API Server
await startWebDashboard();
// 2. Start Vite Dev Server
await startViteDevServer();
// 3. Open browser
const WEB_PORT = parseInt(process.env.WEB_PORT || '7530');
await openBrowser(`http://localhost:${WEB_PORT}`);
// 4. Start MCP Server
process.env.RUN_MODE = 'stdio';
await import('./index.js');
console.error('\n✅ Orchestry is fully running:');
console.error(' - MCP Server: Active (stdio)');
console.error(' - Web UI: http://localhost:7530');
console.error(' - API: http://localhost:7531');
} catch (error) {
console.error('Failed to start Orchestry:', error);
process.exit(1);
}
}
// Handle shutdown
process.on('SIGINT', () => {
console.error('\n🛑 Shutting down Orchestry...');
process.exit(0);
});
startOrchestry().catch(error => {
console.error('Failed to start Orchestry:', error);
process.exit(1);
});