platform-health-check.js•12.5 kB
#!/usr/bin/env node
import { promises as fs } from 'fs';
import { join, dirname } from 'path';
import { homedir } from 'os';
import { execSync } from 'child_process';
/**
* Multi-Platform Health Check for Open-Search-MCP
* Verifies installation and configuration across all supported platforms
*/
const PLATFORMS = {
'claude-desktop': {
name: 'Claude Desktop',
configPath: {
win32: join(homedir(), 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json'),
darwin: join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
linux: join(homedir(), '.config', 'Claude', 'claude_desktop_config.json')
},
detectCommand: null,
configKey: 'mcpServers'
},
'cursor': {
name: 'Cursor IDE',
configPath: {
win32: join(homedir(), 'AppData', 'Roaming', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json'),
darwin: join(homedir(), 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json'),
linux: join(homedir(), '.config', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json')
},
detectCommand: 'cursor --version',
configKey: 'mcpServers'
},
'vscode': {
name: 'Visual Studio Code',
configPath: {
win32: join(homedir(), 'AppData', 'Roaming', 'Code', 'User', 'settings.json'),
darwin: join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'settings.json'),
linux: join(homedir(), '.config', 'Code', 'User', 'settings.json')
},
detectCommand: 'code --version',
configKey: 'mcp.servers'
}
};
class PlatformHealthChecker {
constructor() {
this.results = {};
this.summary = {
total: 0,
installed: 0,
configured: 0,
healthy: 0,
errors: []
};
}
/**
* Run comprehensive health check
*/
async runHealthCheck() {
console.log('🏥 Open-Search-MCP Platform Health Check\n');
// Check project prerequisites
await this.checkPrerequisites();
// Check each platform
for (const [platformId, platform] of Object.entries(PLATFORMS)) {
console.log(`🔍 Checking ${platform.name}...`);
await this.checkPlatform(platformId, platform);
console.log('');
}
// Show summary
this.showSummary();
}
/**
* Check project prerequisites
*/
async checkPrerequisites() {
console.log('📋 Checking Prerequisites...\n');
const checks = [
{
name: 'Node.js',
command: 'node --version',
required: true
},
{
name: 'npm',
command: 'npm --version',
required: true
},
{
name: 'Project built',
check: async () => {
try {
await fs.access(join(process.cwd(), 'dist', 'expanded-server.js'));
return { success: true, version: 'Built' };
} catch {
return { success: false, error: 'Run npm run build' };
}
},
required: true
}
];
for (const check of checks) {
try {
let result;
if (check.command) {
const output = execSync(check.command, { encoding: 'utf8', stdio: 'pipe' });
result = { success: true, version: output.trim() };
} else if (check.check) {
result = await check.check();
}
if (result.success) {
console.log(` ✅ ${check.name}: ${result.version}`);
} else {
console.log(` ❌ ${check.name}: ${result.error}`);
if (check.required) {
this.summary.errors.push(`${check.name} is required but not available`);
}
}
} catch (error) {
console.log(` ❌ ${check.name}: Not found`);
if (check.required) {
this.summary.errors.push(`${check.name} is required but not installed`);
}
}
}
console.log('');
}
/**
* Check a specific platform
*/
async checkPlatform(platformId, platform) {
this.summary.total++;
const result = {
platform: platform.name,
installed: false,
configured: false,
healthy: false,
issues: [],
config: null
};
// Check if platform is installed
if (platform.detectCommand) {
try {
execSync(platform.detectCommand, { stdio: 'ignore' });
result.installed = true;
console.log(` ✅ ${platform.name} is installed`);
} catch {
result.installed = false;
result.issues.push('Platform not installed');
console.log(` ❌ ${platform.name} is not installed`);
}
} else {
// For platforms without detect command, check config directory
try {
const configPath = this.getConfigPath(platform);
const configDir = dirname(configPath);
await fs.access(configDir);
result.installed = true;
console.log(` ✅ ${platform.name} directory found`);
} catch {
result.installed = false;
result.issues.push('Platform directory not found');
console.log(` ❌ ${platform.name} directory not found`);
}
}
if (result.installed) {
this.summary.installed++;
}
// Check configuration
await this.checkConfiguration(platformId, platform, result);
// Check server health
if (result.configured) {
await this.checkServerHealth(result);
}
this.results[platformId] = result;
}
/**
* Check platform configuration
*/
async checkConfiguration(platformId, platform, result) {
try {
const configPath = this.getConfigPath(platform);
const configContent = await fs.readFile(configPath, 'utf-8');
const config = JSON.parse(configContent);
// Check if Open-Search-MCP is configured
const servers = config[platform.configKey];
if (servers && servers['open-search-mcp']) {
result.configured = true;
result.config = servers['open-search-mcp'];
console.log(` ✅ Open-Search-MCP is configured`);
// Validate configuration
await this.validateConfiguration(result.config, result);
this.summary.configured++;
} else {
result.configured = false;
result.issues.push('Open-Search-MCP not configured');
console.log(` ❌ Open-Search-MCP not configured`);
}
} catch (error) {
result.configured = false;
if (error.code === 'ENOENT') {
result.issues.push('Configuration file not found');
console.log(` ❌ Configuration file not found`);
} else {
result.issues.push(`Configuration error: ${error.message}`);
console.log(` ❌ Configuration error: ${error.message}`);
}
}
}
/**
* Validate configuration details
*/
async validateConfiguration(config, result) {
// Check command
if (!config.command) {
result.issues.push('Missing command in configuration');
console.log(` ⚠️ Missing command in configuration`);
}
// Check args
if (!config.args || !Array.isArray(config.args)) {
result.issues.push('Missing or invalid args in configuration');
console.log(` ⚠️ Missing or invalid args in configuration`);
} else {
// Check if server file exists
const serverPath = config.args[0];
if (serverPath) {
try {
await fs.access(serverPath);
console.log(` ✅ Server file exists: ${serverPath}`);
} catch {
result.issues.push(`Server file not found: ${serverPath}`);
console.log(` ❌ Server file not found: ${serverPath}`);
}
}
}
// Check environment variables
if (config.env) {
const apiKeys = ['GITHUB_TOKEN', 'ALPHA_VANTAGE_API_KEY'];
const foundKeys = apiKeys.filter(key => config.env[key]);
if (foundKeys.length > 0) {
console.log(` ✅ API keys configured: ${foundKeys.join(', ')}`);
} else {
console.log(` ⚠️ No API keys configured (optional)`);
}
}
}
/**
* Check server health
*/
async checkServerHealth(result) {
try {
// Test server startup (basic check)
const serverPath = result.config.args[0];
const command = `${result.config.command} ${serverPath}`;
// This is a basic check - in a real implementation, you might want to
// start the server and test MCP protocol communication
console.log(` ✅ Server configuration appears valid`);
result.healthy = true;
this.summary.healthy++;
} catch (error) {
result.issues.push(`Server health check failed: ${error.message}`);
console.log(` ❌ Server health check failed`);
}
}
/**
* Get config path for current platform
*/
getConfigPath(platform) {
const platformPaths = platform.configPath;
return platformPaths[process.platform] || platformPaths.linux;
}
/**
* Show summary results
*/
showSummary() {
console.log('📊 Health Check Summary:\n');
console.log(`Total Platforms Checked: ${this.summary.total}`);
console.log(`Platforms Installed: ${this.summary.installed}/${this.summary.total}`);
console.log(`Platforms Configured: ${this.summary.configured}/${this.summary.total}`);
console.log(`Platforms Healthy: ${this.summary.healthy}/${this.summary.total}\n`);
// Show detailed results
Object.entries(this.results).forEach(([platformId, result]) => {
const status = result.healthy ? '🟢' : result.configured ? '🟡' : result.installed ? '🟠' : '🔴';
console.log(`${status} ${result.platform}`);
if (result.issues.length > 0) {
result.issues.forEach(issue => {
console.log(` ⚠️ ${issue}`);
});
}
});
// Show recommendations
console.log('\n💡 Recommendations:\n');
if (this.summary.errors.length > 0) {
console.log('🔧 Prerequisites:');
this.summary.errors.forEach(error => {
console.log(` • ${error}`);
});
console.log('');
}
const unconfiguredPlatforms = Object.entries(this.results)
.filter(([_, result]) => result.installed && !result.configured)
.map(([_, result]) => result.platform);
if (unconfiguredPlatforms.length > 0) {
console.log('⚙️ Install to unconfigured platforms:');
unconfiguredPlatforms.forEach(platform => {
const platformId = Object.keys(PLATFORMS).find(id => PLATFORMS[id].name === platform);
console.log(` • npm run install:${platformId}`);
});
console.log('');
}
if (this.summary.healthy === this.summary.total && this.summary.total > 0) {
console.log('🎉 All platforms are healthy! Open-Search-MCP is ready to use.');
} else if (this.summary.configured > 0) {
console.log('✅ Some platforms are configured. You can start using Open-Search-MCP.');
} else {
console.log('❌ No platforms are configured. Run the installer to get started.');
}
console.log('\n📚 Next Steps:');
console.log('• Run platform-specific installers for missing configurations');
console.log('• Check platform documentation in docs/platforms/');
console.log('• Test tools with your preferred platform');
console.log('• Report issues at: https://github.com/your-username/open-search-mcp/issues');
}
}
// CLI interface
async function main() {
const args = process.argv.slice(2);
if (args.includes('--help') || args.includes('-h')) {
console.log(`
Open-Search-MCP Platform Health Check
Usage:
node scripts/platform-health-check.js [options]
Options:
--help, -h Show this help message
--json Output results in JSON format
--platform Check specific platform only
This tool checks the health and configuration of Open-Search-MCP
across all supported platforms on your system.
`);
return;
}
const checker = new PlatformHealthChecker();
await checker.runHealthCheck();
if (args.includes('--json')) {
console.log('\n' + JSON.stringify(checker.results, null, 2));
}
}
// Run if called directly
if (process.argv[1] && process.argv[1].endsWith('platform-health-check.js')) {
main().catch(error => {
console.error('❌ Health check error:', error);
process.exit(1);
});
}
export { PlatformHealthChecker };