UNPKG

@genxis/whmrockstar

Version:

šŸŽø GenXis WHMRockStar - AI-powered multi-server WHM/cPanel management via Model Context Protocol (MCP). Enhanced with proper MCP stdio protocol support and multi-server management.

491 lines (423 loc) • 16.7 kB
#!/usr/bin/env node /** * GenXis WHMRockStar CLI * Enhanced multi-server setup and management tool */ const fs = require('fs'); const path = require('path'); const inquirer = require('inquirer'); const chalk = require('chalk'); const { execSync } = require('child_process'); const MultiServerManager = require('../lib/multi-server-manager'); class GenXisCLI { constructor() { this.configDir = path.join(process.env.HOME || process.env.USERPROFILE, '.genxis-whmrockstar'); this.configFile = path.join(this.configDir, 'config.json'); this.mcpFile = path.join(this.configDir, 'mcp-settings.json'); this.serverManager = new MultiServerManager(); } async run() { const args = process.argv.slice(2); const command = args[0] || 'help'; console.log(chalk.blue.bold('šŸŽø GenXis WHMRockStar')); console.log(chalk.gray('AI-powered WHM/cPanel management via MCP\n')); switch (command) { case 'setup': await this.setup(args.includes('--force')); break; case 'add-server': await this.addServer(); break; case 'remove-server': await this.removeServer(args[1]); break; case 'list-servers': await this.listServers(); break; case 'test': await this.test(args[1]); break; case 'test-all': await this.testAllServers(); break; case 'config': await this.showConfig(args[1]); break; case 'start': await this.start(); break; case 'logs': await this.showLogs(); break; case 'help': default: this.showHelp(); break; } } async setup(force = false) { console.log(chalk.yellow('šŸš€ Setting up GenXis WHMRockStar...\n')); // Check if servers already configured if (this.serverManager.hasServers() && !force) { const { overwrite } = await inquirer.prompt([{ type: 'confirm', name: 'overwrite', message: 'Server configurations already exist. Add another server or reconfigure?', default: false }]); if (!overwrite) { console.log(chalk.green('āœ… Setup cancelled. Use --force to overwrite or "add-server" to add more servers.')); return; } } // Create config directory if (!fs.existsSync(this.configDir)) { fs.mkdirSync(this.configDir, { recursive: true }); } // Get server configuration const serverConfig = await this.getServerConfig(); // Test connection console.log(chalk.yellow('šŸ” Testing WHM connection...')); const testResult = await this.testWHMConnection(serverConfig); if (!testResult.success) { console.log(chalk.red('āŒ Connection failed:'), testResult.error); console.log(chalk.yellow('Please check your server IP and API token.')); return; } console.log(chalk.green('āœ… WHM connection successful!')); // Add server to manager const serverId = serverConfig.id || 'default'; try { this.serverManager.addServer(serverId, serverConfig); console.log(chalk.green('āœ… Server configuration saved')); } catch (error) { console.log(chalk.red('āŒ Failed to save server configuration:'), error.message); return; } // Generate MCP settings await this.generateMCPSettings(); console.log(chalk.green('āœ… MCP settings generated')); // Install MCP integration await this.installMCPIntegration(); console.log(chalk.green.bold('\nšŸŽ‰ Setup complete!')); console.log(chalk.white('You can now use WHM management in your AI assistant.')); console.log(chalk.gray('Run "genxis-whm start" to start the MCP server manually.')); console.log(chalk.gray('Use "genxis-whm add-server" to add more servers.')); } async getServerConfig() { const questions = [ { type: 'input', name: 'id', message: 'Server ID (unique identifier):', default: 'server1', validate: (input) => { if (!input || input.trim().length === 0) { return 'Server ID is required'; } if (this.serverManager.servers && this.serverManager.servers.has(input)) { return 'Server ID already exists. Please choose a different ID.'; } return true; } }, { type: 'input', name: 'name', message: 'Server Name (display name):', validate: (input) => input.length > 0 || 'Server name is required' }, { type: 'input', name: 'server', message: 'WHM Server IP Address:', validate: (input) => { const ipRegex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; return ipRegex.test(input) || 'Please enter a valid IP address'; } }, { type: 'input', name: 'apiToken', message: 'WHM API Token:', validate: (input) => input.length > 10 || 'API token seems too short' }, { type: 'input', name: 'port', message: 'WHM Port:', default: '2087' }, { type: 'input', name: 'username', message: 'WHM Username:', default: 'root' } ]; return await inquirer.prompt(questions); } async testWHMConnection(config) { try { const WHMService = require('../lib/whm-service'); const whm = new WHMService(config); await whm.get('version'); return { success: true }; } catch (error) { return { success: false, error: error.message }; } } async generateMCPSettings() { const mcpSettings = { mcpServers: { "genxis-whm": { command: "node", args: [path.join(__dirname, '..', 'mcp-server.js')], disabled: false, alwaysAllow: [], disabledTools: [] } } }; fs.writeFileSync(this.mcpFile, JSON.stringify(mcpSettings, null, 2)); } async installMCPIntegration() { console.log(chalk.yellow('šŸ”§ Installing MCP integration...')); const integrations = [ { name: 'VS Code (Roo-Cline)', path: path.join(process.env.APPDATA || process.env.HOME, 'Code', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'mcp_settings.json'), check: () => fs.existsSync(path.dirname(this.getVSCodePath())) }, { name: 'VS Code (Claude)', path: path.join(process.env.APPDATA || process.env.HOME, 'Code', 'User', 'settings.json'), check: () => fs.existsSync(path.dirname(this.getVSCodePath())) }, { name: 'Windsurf', path: path.join(process.env.APPDATA || process.env.HOME, 'Windsurf', 'mcp.json'), check: () => fs.existsSync(path.dirname(this.getWindsurfPath())) } ]; for (const integration of integrations) { if (integration.check()) { try { await this.updateIDEConfig(integration.path); console.log(chalk.green(`āœ… ${integration.name} integration installed`)); } catch (error) { console.log(chalk.yellow(`āš ļø ${integration.name} integration failed: ${error.message}`)); } } } } getVSCodePath() { const appData = process.env.APPDATA || path.join(process.env.HOME, '.config'); return path.join(appData, 'Code', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'mcp_settings.json'); } getWindsurfPath() { const appData = process.env.APPDATA || path.join(process.env.HOME, '.config'); return path.join(appData, 'Windsurf', 'mcp.json'); } async updateIDEConfig(configPath) { const mcpSettings = JSON.parse(fs.readFileSync(this.mcpFile, 'utf8')); // Ensure directory exists const dir = path.dirname(configPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } // Read existing config or create new let existingConfig = {}; if (fs.existsSync(configPath)) { try { existingConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (error) { // Invalid JSON, start fresh existingConfig = {}; } } // Merge configurations if (!existingConfig.mcpServers) { existingConfig.mcpServers = {}; } Object.assign(existingConfig.mcpServers, mcpSettings.mcpServers); // Write updated config fs.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2)); } async addServer() { console.log(chalk.yellow('āž• Adding new WHM server...\n')); const serverConfig = await this.getServerConfig(); // Test connection console.log(chalk.yellow('šŸ” Testing WHM connection...')); const testResult = await this.testWHMConnection(serverConfig); if (!testResult.success) { console.log(chalk.red('āŒ Connection failed:'), testResult.error); return; } console.log(chalk.green('āœ… WHM connection successful!')); // Add server try { this.serverManager.addServer(serverConfig.id, serverConfig); console.log(chalk.green(`āœ… Server '${serverConfig.id}' added successfully!`)); } catch (error) { console.log(chalk.red('āŒ Failed to add server:'), error.message); } } async removeServer(serverId) { if (!serverId) { console.log(chalk.red('āŒ Server ID is required. Usage: genxis-whm remove-server <server-id>')); return; } try { this.serverManager.removeServer(serverId); console.log(chalk.green(`āœ… Server '${serverId}' removed successfully!`)); } catch (error) { console.log(chalk.red('āŒ Failed to remove server:'), error.message); } } async listServers() { const servers = this.serverManager.listServers(); if (servers.length === 0) { console.log(chalk.yellow('šŸ“‹ No servers configured. Run "genxis-whm setup" to add a server.')); return; } console.log(chalk.blue('šŸ“‹ Configured WHM Servers:\n')); servers.forEach((server, index) => { const status = server.enabled ? chalk.green('āœ… Enabled') : chalk.red('āŒ Disabled'); console.log(chalk.white(`${index + 1}. ${server.name}`)); console.log(chalk.gray(` ID: ${server.id}`)); console.log(chalk.gray(` Server: ${server.server}:${server.port}`)); console.log(chalk.gray(` Username: ${server.username}`)); console.log(` Status: ${status}\n`); }); } async test(serverId) { if (!this.serverManager.hasServers()) { console.log(chalk.red('āŒ No servers configured. Run "genxis-whm setup" first.')); return; } if (serverId) { // Test specific server try { console.log(chalk.yellow(`šŸ” Testing server '${serverId}'...`)); const result = await this.serverManager.testServer(serverId); if (result.success) { console.log(chalk.green(`āœ… Server '${serverId}' connection successful!`)); console.log(chalk.white(`Server: ${result.server}`)); } else { console.log(chalk.red(`āŒ Server '${serverId}' connection failed:`), result.error); } } catch (error) { console.log(chalk.red('āŒ Test failed:'), error.message); } } else { // Test all servers await this.testAllServers(); } } async testAllServers() { console.log(chalk.yellow('šŸ” Testing all configured servers...\n')); const results = await this.serverManager.testAllServers(); results.forEach(result => { if (result.success) { console.log(chalk.green(`āœ… ${result.serverId}: Connection successful`)); } else { console.log(chalk.red(`āŒ ${result.serverId}: ${result.error}`)); } }); } async showConfig(serverId) { if (!this.serverManager.hasServers()) { console.log(chalk.red('āŒ No servers configured. Run "genxis-whm setup" first.')); return; } if (serverId) { // Show specific server config try { const { config } = this.serverManager.getServer(serverId); console.log(chalk.blue(`šŸ“‹ Configuration for '${serverId}':`)); console.log(chalk.white(`Name: ${config.name}`)); console.log(chalk.white(`Server: ${config.server}:${config.port}`)); console.log(chalk.white(`Username: ${config.username}`)); console.log(chalk.white(`API Token: ${config.apiToken.substring(0, 8)}...`)); console.log(chalk.white(`Enabled: ${config.enabled !== false ? 'Yes' : 'No'}`)); } catch (error) { console.log(chalk.red('āŒ Error:'), error.message); } } else { // Show all servers await this.listServers(); } } async start() { if (!this.serverManager.hasServers()) { console.log(chalk.red('āŒ No servers configured. Run "genxis-whm setup" first.')); return; } console.log(chalk.yellow('šŸš€ Starting GenXis WHMRockStar MCP Server...')); try { const WHMRockStarMCPServer = require('../mcp-server.js'); const server = new WHMRockStarMCPServer(); await server.start(); } catch (error) { console.log(chalk.red('āŒ Failed to start server:'), error.message); } } async showLogs() { const logFile = path.join(this.configDir, 'logs', 'whm-operations.log'); if (!fs.existsSync(logFile)) { console.log(chalk.yellow('šŸ“ No logs found yet.')); return; } console.log(chalk.blue('šŸ“ Recent logs:')); try { const logs = fs.readFileSync(logFile, 'utf8'); const lines = logs.split('\n').slice(-20); // Last 20 lines lines.forEach(line => { if (line.includes('[ERROR]')) { console.log(chalk.red(line)); } else if (line.includes('[WARN]')) { console.log(chalk.yellow(line)); } else { console.log(chalk.white(line)); } }); } catch (error) { console.log(chalk.red('āŒ Failed to read logs:'), error.message); } } showHelp() { console.log(chalk.blue('šŸ“– Available Commands:\n')); console.log(chalk.yellow('Setup & Configuration:')); console.log(chalk.white(' setup ') + chalk.gray('Interactive setup wizard for first server')); console.log(chalk.white(' setup --force ') + chalk.gray('Force overwrite existing config')); console.log(chalk.white(' add-server ') + chalk.gray('Add additional WHM server')); console.log(chalk.white(' remove-server <id> ') + chalk.gray('Remove a server configuration')); console.log(chalk.white(' list-servers ') + chalk.gray('List all configured servers')); console.log(chalk.yellow('\nTesting & Monitoring:')); console.log(chalk.white(' test ') + chalk.gray('Test all server connections')); console.log(chalk.white(' test <server-id> ') + chalk.gray('Test specific server connection')); console.log(chalk.white(' test-all ') + chalk.gray('Test all servers with detailed output')); console.log(chalk.yellow('\nConfiguration & Management:')); console.log(chalk.white(' config ') + chalk.gray('Show all server configurations')); console.log(chalk.white(' config <server-id> ') + chalk.gray('Show specific server configuration')); console.log(chalk.white(' start ') + chalk.gray('Start MCP server')); console.log(chalk.white(' logs ') + chalk.gray('Show recent operation logs')); console.log(chalk.white(' help ') + chalk.gray('Show this help message')); console.log(chalk.blue('\nšŸš€ Quick Start:')); console.log(chalk.white(' npx @genxis/whmrockstar setup')); console.log(chalk.white(' npx @genxis/whmrockstar add-server')); console.log(chalk.white(' npx @genxis/whmrockstar test')); console.log(chalk.blue('\nšŸ“š Documentation:')); console.log(chalk.white(' https://www.npmjs.com/package/@genxis/whmrockstar')); } } // Run CLI if (require.main === module) { const cli = new GenXisCLI(); cli.run().catch(error => { console.error(chalk.red('āŒ CLI Error:'), error.message); process.exit(1); }); } module.exports = GenXisCLI;