orchestry-mcp
Version:
Orchestry MCP Server for multi-session task management
122 lines (101 loc) ⢠3.7 kB
text/typescript
import { OrchestryServer } from './index.js';
import { exec, execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import net from 'net';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Check if port is in use
function isPortInUse(port: number): Promise<boolean> {
return new Promise((resolve) => {
const server = net.createServer();
server.once('error', () => resolve(true));
server.once('listening', () => {
server.close();
resolve(false);
});
server.listen(port);
});
}
async function startUnifiedServer() {
const API_PORT = parseInt(process.env.API_PORT || '7531');
const WEB_PORT = parseInt(process.env.WEB_PORT || '7530');
console.log('š Starting Orchestry (Unified Mode)...\n');
console.log(` API Port: ${API_PORT}`);
console.log(` Web Port: ${WEB_PORT}\n`);
// Check if port is already in use
const portInUse = await isPortInUse(API_PORT);
if (portInUse) {
console.log(`ā ļø Port ${API_PORT} is already in use.`);
// If we're being launched by the launcher, it should have already cleaned ports
// So if port is still in use, something else is using it
if (process.env.LAUNCHED_BY_ORCHESTRY) {
console.error(`Port ${API_PORT} is being used by another process`);
process.exit(1);
}
console.log(' Attempting to clean up...\n');
try {
// Kill existing processes on port
if (process.platform === 'darwin' || process.platform === 'linux') {
execSync(`lsof -ti :${API_PORT} | xargs kill -9 2>/dev/null || true`);
console.log('ā
Cleaned up existing processes\n');
// Wait a moment for port to be released
await new Promise(resolve => setTimeout(resolve, 1000));
}
} catch (error) {
console.error('Could not clean up port. Please manually stop the process using port', API_PORT);
process.exit(1);
}
}
// Start the server with web mode
process.env.RUN_MODE = 'web';
process.env.NODE_ENV = 'development';
const server = new OrchestryServer(API_PORT);
// Initialize and run server
await server.run();
// Auto-open browser after a short delay
setTimeout(() => {
console.log('š Opening browser...');
const url = `http://localhost:${WEB_PORT}`; // Vite dev server port
// Cross-platform browser opening
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}`;
}
exec(command, (error) => {
if (error) {
console.log('Please open your browser and navigate to:', url);
}
});
}, 2000);
// Also start Vite dev server for React app
console.log('š¦ Starting React development server...\n');
const viteProcess = exec('npm run dev', {
cwd: path.join(__dirname, '../web')
});
viteProcess.stdout?.on('data', (data) => {
console.log(`[Vite] ${data}`);
});
viteProcess.stderr?.on('data', (data) => {
console.error(`[Vite Error] ${data}`);
});
// Handle shutdown
process.on('SIGINT', () => {
console.log('\nš Shutting down...');
viteProcess.kill();
process.exit(0);
});
console.log('ā
Orchestry is running!');
console.log(` API Server: http://localhost:${API_PORT}/api`);
console.log(` Web UI: http://localhost:${WEB_PORT}\n`);
console.log('Press Ctrl+C to stop\n');
}
// Run the unified server
startUnifiedServer().catch((error) => {
console.error('Failed to start server:', error);
process.exit(1);
});