Skip to main content
Glama
health-check.jsโ€ข8.33 kB
#!/usr/bin/env node import { spawn } from 'child_process'; import { setTimeout } from 'timers/promises'; /** * Health Check Tool for MCP Self-Learning Server * * Tests server functionality and reports status */ class HealthCheck { constructor() { this.results = { startup: false, tools: {}, persistence: false, logging: false, performance: {} }; } async run() { console.log('๐Ÿฅ MCP Self-Learning Server Health Check\n'); await this.checkStartup(); await this.checkPersistence(); await this.checkLogging(); await this.checkPerformance(); this.printResults(); // Ensure output is flushed before exit await new Promise(resolve => setTimeout(resolve, 100)); process.exit(this.allPassed() ? 0 : 1); } async checkStartup() { console.log('๐Ÿš€ Testing server startup...'); try { const server = spawn('node', ['mcp-self-learning-server.js'], { stdio: 'pipe', cwd: process.cwd() }); let output = ''; server.stdout.on('data', (data) => { output += data.toString(); }); server.stderr.on('data', (data) => { output += data.toString(); }); // Wait for server to start await setTimeout(3000); // Send SIGTERM to shut down server.kill('SIGTERM'); // Wait for process to exit await new Promise((resolve) => { server.on('exit', resolve); }); if (output.includes('MCP Self-Learning Server started') && output.includes('Learning engine initialized')) { this.results.startup = true; console.log(' โœ… Server startup successful'); } else { console.log(' โŒ Server startup failed'); console.log(' Output:', output.substring(0, 200)); } } catch (error) { console.log(' โŒ Server startup error:', error.message); } } async checkPersistence() { console.log('\n๐Ÿ’พ Testing data persistence...'); try { const fs = await import('fs/promises'); const path = await import('path'); const dataDir = path.join(process.cwd(), 'data'); const learningFile = path.join(dataDir, 'learning-engine.json'); // Check if data directory exists try { await fs.access(dataDir); console.log(' โœ… Data directory exists'); // Check if learning data file exists try { await fs.access(learningFile); const content = await fs.readFile(learningFile, 'utf8'); const data = JSON.parse(content); if (data.patterns && data.knowledge && data.metrics) { this.results.persistence = true; console.log(' โœ… Learning data file valid'); console.log(` - Patterns: ${Array.isArray(data.patterns) ? data.patterns.length : 0}`); console.log(` - Knowledge entries: ${Array.isArray(data.knowledge) ? data.knowledge.length : 0}`); console.log(` - Learning cycles: ${data.metrics?.learningCycles || 0}`); } else { console.log(' โŒ Learning data file structure invalid'); } } catch (error) { console.log(' โš ๏ธ Learning data file not found (expected on first run)'); this.results.persistence = true; // Not an error on first run } } catch (error) { console.log(' โŒ Data directory not accessible'); } } catch (error) { console.log(' โŒ Persistence check error:', error.message); } } async checkLogging() { console.log('\n๐Ÿ“ Testing logging system...'); try { const fs = await import('fs/promises'); const path = await import('path'); const logsDir = path.join(process.cwd(), 'logs'); const logFile = path.join(logsDir, 'mcp-server.log'); // Check if logs directory exists try { await fs.access(logsDir); console.log(' โœ… Logs directory exists'); // Check if log file exists try { await fs.access(logFile); const stats = await fs.stat(logFile); if (stats.size > 0) { this.results.logging = true; console.log(' โœ… Log file exists and has content'); console.log(` - File size: ${Math.round(stats.size / 1024 * 10) / 10}KB`); console.log(` - Modified: ${stats.mtime.toLocaleString()}`); } else { console.log(' โš ๏ธ Log file exists but is empty'); } } catch (error) { console.log(' โš ๏ธ Log file not found'); } } catch (error) { console.log(' โš ๏ธ Logs directory not found'); } } catch (error) { console.log(' โŒ Logging check error:', error.message); } } async checkPerformance() { console.log('\nโšก Testing performance...'); try { const startTime = process.hrtime.bigint(); // Test server startup time const server = spawn('node', ['mcp-self-learning-server.js'], { stdio: 'pipe', cwd: process.cwd() }); let startupComplete = false; server.stdout.on('data', (data) => { if (data.toString().includes('MCP Self-Learning Server started') && !startupComplete) { const endTime = process.hrtime.bigint(); const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds this.results.performance.startupTime = duration; startupComplete = true; if (duration < 5000) { // Less than 5 seconds console.log(` โœ… Startup time: ${Math.round(duration)}ms`); } else { console.log(` โš ๏ธ Slow startup time: ${Math.round(duration)}ms`); } // Shut down the server server.kill('SIGTERM'); } }); // Wait for startup or timeout await setTimeout(10000); if (!startupComplete) { console.log(' โŒ Server startup timeout (>10s)'); server.kill('SIGKILL'); } // Wait for process to exit await new Promise((resolve) => { server.on('exit', resolve); }); // Check memory usage const memUsage = process.memoryUsage(); this.results.performance.memoryUsage = { rss: Math.round(memUsage.rss / 1024 / 1024), heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) }; console.log(` ๐Ÿ“Š Health check memory usage: ${this.results.performance.memoryUsage.heapUsed}MB heap`); } catch (error) { console.log(' โŒ Performance check error:', error.message); } } printResults() { console.log('\n๐Ÿ“‹ Health Check Results:'); console.log('========================'); const status = (passed) => passed ? 'โœ… PASS' : 'โŒ FAIL'; console.log(`Startup: ${status(this.results.startup)}`); console.log(`Persistence: ${status(this.results.persistence)}`); console.log(`Logging: ${status(this.results.logging)}`); if (this.results.performance.startupTime) { const perfStatus = this.results.performance.startupTime < 5000 ? 'โœ… GOOD' : 'โš ๏ธ SLOW'; console.log(`Performance: ${perfStatus} (${Math.round(this.results.performance.startupTime)}ms startup)`); } console.log('\n๐ŸŽฏ Overall Status:', this.allPassed() ? 'โœ… HEALTHY' : 'โŒ ISSUES DETECTED'); if (!this.allPassed()) { console.log('\n๐Ÿ’ก Recommendations:'); if (!this.results.startup) { console.log(' - Check server dependencies and configuration'); } if (!this.results.persistence) { console.log(' - Verify file system permissions for data directory'); } if (!this.results.logging) { console.log(' - Check logging configuration and permissions'); } } } allPassed() { return this.results.startup && this.results.persistence && this.results.logging; } } // Run health check if executed directly if (import.meta.url === `file://${process.argv[1]}`) { const healthCheck = new HealthCheck(); healthCheck.run().catch((error) => { console.error('Health 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/saralegui-solutions/mcp-self-learning-server'

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