@hyperliquid-ai/mcp-server
Version:
Hyperliquid MCP Server - AI Trading Agent for Claude Desktop
250 lines (206 loc) • 7.96 kB
JavaScript
/**
* 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
};