UNPKG

@hyperliquid-ai/mcp-server

Version:

Hyperliquid MCP Server - AI Trading Agent for Claude Desktop

250 lines (206 loc) 7.96 kB
#!/usr/bin/env node /** * Claude Desktop MCP Server Uninstaller * Removes Hyperliquid MCP Server from Claude Desktop configuration */ const fs = require('fs'); const path = require('path'); const os = require('os'); const readline = require('readline'); // Colors for console output const colors = { green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', blue: '\x1b[34m', reset: '\x1b[0m', bold: '\x1b[1m' }; function log(message, color = colors.reset) { console.log(`${color}${message}${colors.reset}`); } function success(message) { log(`✅ ${message}`, colors.green); } function warning(message) { log(`⚠️ ${message}`, colors.yellow); } function error(message) { log(`❌ ${message}`, colors.red); } function info(message) { log(`ℹ️ ${message}`, colors.blue); } // Get Claude Desktop config directory based on OS function getClaudeConfigDir() { const platform = os.platform(); const homeDir = os.homedir(); switch (platform) { case 'darwin': // macOS return path.join(homeDir, 'Library', 'Application Support', 'Claude'); case 'win32': // Windows return path.join(process.env.APPDATA || path.join(homeDir, 'AppData', 'Roaming'), 'Claude'); case 'linux': // Linux return path.join(process.env.XDG_CONFIG_HOME || path.join(homeDir, '.config'), 'Claude'); default: throw new Error(`Unsupported platform: ${platform}`); } } // Create readline interface for user input function createReadlineInterface() { return readline.createInterface({ input: process.stdin, output: process.stdout }); } // Prompt user for confirmation function confirmAction(question) { const rl = createReadlineInterface(); return new Promise((resolve) => { rl.question(`${question} (y/N): `, (answer) => { rl.close(); resolve(answer.toLowerCase().startsWith('y')); }); }); } // Load existing Claude config function loadClaudeConfig(configPath) { try { if (fs.existsSync(configPath)) { const content = fs.readFileSync(configPath, 'utf8'); return JSON.parse(content); } } catch (err) { throw new Error(`Could not parse Claude config: ${err.message}`); } return null; } // Find Hyperliquid MCP servers in config function findHyperliquidServers(config) { if (!config || !config.mcpServers) { return []; } const hyperliquidServers = []; for (const [name, serverConfig] of Object.entries(config.mcpServers)) { // Check if this is a Hyperliquid MCP server if ( serverConfig.args && serverConfig.args.some(arg => arg.includes('hyperliquid') || arg.includes('hlmcp')) || serverConfig.env && serverConfig.env.API_KEY && serverConfig.env.API_KEY.startsWith('hlmcp_') || name.toLowerCase().includes('hyperliquid') ) { hyperliquidServers.push(name); } } return hyperliquidServers; } // Backup existing config function backupConfig(configPath) { if (fs.existsSync(configPath)) { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const backupPath = configPath.replace('.json', `.backup-${timestamp}.json`); fs.copyFileSync(configPath, backupPath); success(`Backed up existing config to: ${backupPath}`); return backupPath; } return null; } // Write Claude config function writeClaudeConfig(configPath, config) { fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); success(`Updated Claude Desktop configuration: ${configPath}`); } // Main uninstallation process async function main() { try { log('🗑️ Hyperliquid MCP Server Uninstaller for Claude Desktop', colors.bold + colors.red); log('=' .repeat(60)); // Get Claude config directory const claudeConfigDir = getClaudeConfigDir(); const configPath = path.join(claudeConfigDir, 'claude_desktop_config.json'); info(`Claude Desktop config path: ${configPath}`); // Check if config file exists if (!fs.existsSync(configPath)) { warning('Claude Desktop config file not found.'); warning('Either Claude Desktop is not installed or no MCP servers are configured.'); return; } // Load existing Claude config log('\n📝 Reading Claude Desktop configuration...'); const config = loadClaudeConfig(configPath); if (!config) { error('Could not read Claude Desktop configuration file.'); return; } // Find Hyperliquid servers const hyperliquidServers = findHyperliquidServers(config); if (hyperliquidServers.length === 0) { info('No Hyperliquid MCP servers found in configuration.'); info('The server may have already been removed or was never installed.'); return; } // Show found servers log('\n🔍 Found Hyperliquid MCP servers:', colors.bold); hyperliquidServers.forEach((serverName, index) => { log(` ${index + 1}. ${serverName}`); }); // Confirm removal const shouldRemove = await confirmAction('\n❓ Do you want to remove all Hyperliquid MCP servers?'); if (!shouldRemove) { info('Uninstallation cancelled by user.'); return; } // Backup existing config log('\n💾 Creating backup...'); backupConfig(configPath); // Remove Hyperliquid servers log('\n🔄 Removing Hyperliquid MCP servers...'); hyperliquidServers.forEach(serverName => { delete config.mcpServers[serverName]; success(`Removed server: ${serverName}`); }); // Clean up empty mcpServers object if (Object.keys(config.mcpServers).length === 0) { delete config.mcpServers; info('Removed empty mcpServers configuration.'); } // Write updated config writeClaudeConfig(configPath, config); // Success message log('\n' + '='.repeat(60), colors.green); success('Uninstallation completed successfully!'); log('='.repeat(60), colors.green); log('\nNext steps:', colors.bold); log('1. 🔄 Restart Claude Desktop application'); log('2. 💬 Hyperliquid MCP features will no longer be available in Claude'); log('\nTo reinstall:', colors.bold); log('• Run: npm run install-claude'); log('• Or: node scripts/install-claude-config.js'); log('\n📚 Need help?'); log('• GitHub: https://github.com/hyperliquid-ai/hyperliquid-ai-mcp'); log('• Support: support@hyperliquid-ai.xyz'); } catch (err) { error(`Uninstallation failed: ${err.message}`); log('\nFor troubleshooting help, visit:'); log('https://github.com/hyperliquid-ai/hyperliquid-ai-mcp/issues'); process.exit(1); } } // Handle script termination process.on('SIGINT', () => { log('\n\nUninstallation cancelled by user.'); process.exit(0); }); process.on('unhandledRejection', (err) => { error(`Unhandled error: ${err.message}`); process.exit(1); }); // Run uninstaller if called directly if (require.main === module) { main(); } module.exports = { main, getClaudeConfigDir, findHyperliquidServers };