Skip to main content
Glama

SystemPrompt Coding Agent

Official
status.ts9.4 kB
#!/usr/bin/env node /** * System Status Script * Shows the health and status of all services */ import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; import * as dotenv from 'dotenv'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.join(__dirname, '..'); // Load environment variables from .env file dotenv.config({ path: path.join(projectRoot, '.env') }); // Colors for output const colors = { reset: '\x1b[0m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', gray: '\x1b[90m' }; class SystemStatus { private log(message: string, color: string = colors.reset): void { console.log(`${color}${message}${colors.reset}`); } private success(message: string): void { this.log(`✓ ${message}`, colors.green); } private error(message: string): void { this.log(`✗ ${message}`, colors.red); } private warning(message: string): void { this.log(`⚠ ${message}`, colors.yellow); } private info(message: string): void { this.log(`ℹ ${message}`, colors.blue); } private header(title: string): void { this.log(`\n==== ${title} ====\n`, colors.blue); } checkDaemonStatus(): { running: boolean; pid?: number; port?: number } { this.header('Host Bridge Daemon Status'); const pidFile = path.join(projectRoot, 'daemon', 'logs', 'daemon.pid'); if (!fs.existsSync(pidFile)) { this.error('Daemon is not running (no PID file)'); return { running: false }; } try { const pid = parseInt(fs.readFileSync(pidFile, 'utf-8')); // Check if process exists try { execSync(`ps -p ${pid}`, { stdio: 'pipe' }); this.success(`Daemon is running (PID: ${pid})`); // Check if port is listening try { execSync(`lsof -i :9876 -P -n | grep LISTEN`, { stdio: 'pipe' }); this.success('Listening on port 9876'); // Check daemon logs const logFile = path.join(projectRoot, 'daemon', 'logs', 'host-bridge.log'); if (fs.existsSync(logFile)) { const stats = fs.statSync(logFile); const lastModified = new Date(stats.mtime); const minutesAgo = Math.floor((Date.now() - lastModified.getTime()) / 1000 / 60); this.info(`Log file last updated: ${minutesAgo} minutes ago`); } return { running: true, pid, port: 9876 }; } catch { this.warning('Daemon process exists but not listening on port 9876'); return { running: true, pid }; } } catch { this.error(`Daemon PID ${pid} is not running`); return { running: false }; } } catch (error) { this.error('Failed to read daemon PID file'); return { running: false }; } } checkDockerStatus(): { running: boolean; containers?: string[] } { this.header('Docker Services Status'); try { // Check if Docker is running execSync('docker info', { stdio: 'pipe' }); // Check our containers const containers = execSync('docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(mcp-server|cloudflared)" || true', { encoding: 'utf-8' }).trim(); if (!containers) { this.error('No Docker containers running'); return { running: false }; } const lines = containers.split('\n'); const runningContainers: string[] = []; lines.forEach(line => { if (line.includes('mcp-server')) { if (line.includes('Up')) { this.success('MCP Server container is running'); const port = process.env.PORT || '3000'; if (line.includes(port)) { this.success(` → Exposed on port ${port}`); } runningContainers.push('mcp-server'); } else { this.error('MCP Server container is not healthy'); } } if (line.includes('cloudflared')) { if (line.includes('Up')) { this.info('Cloudflare tunnel is running'); runningContainers.push('cloudflared'); } } }); // Check Docker logs for recent activity try { const projectName = process.env.COMPOSE_PROJECT_NAME || 'systemprompt-coding-agent'; const expectedContainerName = `${projectName}-mcp-server-1`; // First try the expected name, then fall back to grep let containerName = ''; try { execSync(`docker ps --format "{{.Names}}" | grep -q "^${expectedContainerName}$"`, { encoding: 'utf-8' }); containerName = expectedContainerName; } catch { // Fall back to grep for any mcp-server container containerName = execSync('docker ps --format "{{.Names}}" | grep mcp-server | head -1', { encoding: 'utf-8' }).trim(); } if (containerName) { const recentLogs = execSync(`docker logs ${containerName} --tail 1 2>&1`, { encoding: 'utf-8' }).trim(); if (recentLogs) { this.info('Recent Docker log: ' + recentLogs.substring(0, 80) + '...'); } } } catch { // Ignore log errors } return { running: runningContainers.length > 0, containers: runningContainers }; } catch { this.error('Docker is not running or not accessible'); return { running: false }; } } checkServiceConnectivity(): void { this.header('Service Connectivity'); // Check if MCP server responds const port = process.env.PORT || '3000'; try { execSync(`curl -s http://localhost:${port}/health || curl -s http://localhost:${port}/`, { timeout: 5000, stdio: 'pipe' }); this.success(`MCP Server is responding on http://localhost:${port}`); } catch { this.warning(`MCP Server is not responding on port ${port}`); } // Check daemon connectivity from host const daemonPort = process.env.CLAUDE_PROXY_PORT || '9876'; try { execSync(`nc -zv localhost ${daemonPort}`, { timeout: 2000, stdio: 'pipe' }); this.success(`Host Bridge Daemon is accessible on localhost:${daemonPort}`); } catch { this.warning('Host Bridge Daemon is not accessible'); } } checkEnvironment(): void { this.header('Environment Check'); // Check .env file const envFile = path.join(projectRoot, '.env'); if (fs.existsSync(envFile)) { this.success('.env file exists'); const env = fs.readFileSync(envFile, 'utf-8'); if (env.includes('CLAUDE_PATH=')) { const claudePath = env.match(/CLAUDE_PATH=([^\n]+)/)?.[1]; if (claudePath && fs.existsSync(claudePath)) { this.success(`Claude CLI configured: ${claudePath}`); } else { this.warning('Claude CLI path configured but not found'); } } if (env.includes('HOST_FILE_ROOT=')) { this.success('HOST_FILE_ROOT is configured'); } else { this.warning('HOST_FILE_ROOT is not set in .env'); } } else { this.error('.env file not found - run npm setup'); } // Check Node version const nodeVersion = process.version; const majorVersion = parseInt(nodeVersion.split('.')[0].substring(1)); if (majorVersion >= 18) { this.info(`Node.js ${nodeVersion}`); } else { this.error(`Node.js ${nodeVersion} (18+ required)`); } } showSummary(daemonStatus: any, dockerStatus: any): void { this.header('Summary'); const allGood = daemonStatus.running && daemonStatus.port && dockerStatus.running; if (allGood) { this.success('All systems operational! 🚀'); this.log('\nQuick commands:', colors.gray); this.log(' npm test # Run tests', colors.gray); this.log(' npm run logs # View logs', colors.gray); this.log(' npm stop # Stop everything', colors.gray); } else { this.warning('Some services are not running'); this.log('\nTo start all services:', colors.gray); this.log(' npm start', colors.gray); if (!daemonStatus.running) { this.log('\nTo start just the daemon:', colors.gray); this.log(' npm run daemon:start', colors.gray); } if (!dockerStatus.running) { this.log('\nTo start just Docker:', colors.gray); this.log(' npm run docker:up', colors.gray); } } } async run(): Promise<void> { this.log('System Status Report', colors.green); this.log('=' . repeat(50), colors.green); const daemonStatus = this.checkDaemonStatus(); const dockerStatus = this.checkDockerStatus(); this.checkServiceConnectivity(); this.checkEnvironment(); this.showSummary(daemonStatus, dockerStatus); } } // Main entry point if (process.argv[1] === fileURLToPath(import.meta.url)) { const status = new SystemStatus(); status.run().catch(error => { console.error('Status check failed:', error); process.exit(1); }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systempromptio/systemprompt-code-orchestrator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server