UNPKG

@toolprint/hypertool-mcp

Version:

HyperTool MCP proxy server for routing requests between clients and multiple underlying MCP servers

120 lines • 5.64 kB
/** * Claude Desktop integration setup script * Usage: npx -y @toolprint/hypertool-mcp --install claude-desktop */ import { join } from "path"; import { homedir } from "os"; import inquirer from "inquirer"; import { output } from "../../utils/output.js"; import { theme } from "../../utils/theme.js"; import { validateMcpConfiguration, createConfigBackup, migrateToHyperToolConfig, updateMcpConfigWithHyperTool, readJsonFile, fileExists, } from "../shared/mcpSetupUtils.js"; export class ClaudeDesktopSetup { context; dryRun = false; constructor() { // macOS paths const claudeConfigPath = join(homedir(), "Library/Application Support/Claude/claude_desktop_config.json"); const backupPath = join(homedir(), "Library/Application Support/Claude/claude_desktop_config.backup.json"); const hyperToolConfigPath = join(homedir(), "Library/Application Support/Claude/mcp.hypertool.json"); this.context = { originalConfigPath: claudeConfigPath, backupPath, hyperToolConfigPath, dryRun: false, }; } async run(dryRun = false) { this.dryRun = dryRun; this.context.dryRun = dryRun; try { if (this.dryRun) { output.info(theme.info("🔍 [DRY RUN MODE] - No changes will be made")); output.displaySpaceBuffer(1); } // Step 1: Validate configuration exists await validateMcpConfiguration(this.context.originalConfigPath); // Step 2: Read and analyze configuration const originalConfig = await readJsonFile(this.context.originalConfigPath); const existingServers = Object.keys(originalConfig.mcpServers || {}).filter((name) => !name.toLowerCase().includes("hypertool")); // Check if hypertool is already fully configured const hasHypertool = Object.keys(originalConfig.mcpServers || {}).some((key) => key.toLowerCase().includes("hypertool")); const hyperToolConfigExists = await fileExists(this.context.hyperToolConfigPath); if (hasHypertool && hyperToolConfigExists && existingServers.length === 0) { const hyperToolConfig = await readJsonFile(this.context.hyperToolConfigPath); const hyperToolServers = Object.keys(hyperToolConfig.mcpServers || {}); if (hyperToolServers.length > 0) { output.success("✅ Hypertool is already configured for Claude Desktop"); output.info(`📍 Managing ${hyperToolServers.length} MCP servers: ${hyperToolServers.join(", ")}`); output.displaySpaceBuffer(1); output.info("Nothing to do - Hypertool is already fully configured."); return; } } else if (existingServers.length === 0) { output.warn("⚠️ No MCP servers found"); output.info("💡 Hypertool will be configured for future server additions"); output.displaySpaceBuffer(1); } else { // Show existing servers output.info(`📍 Claude Desktop has ${existingServers.length} MCP servers: ${existingServers.join(", ")}`); output.displaySpaceBuffer(1); } // Step 3: Get user confirmation const { shouldProceed } = await inquirer.prompt([ { type: "confirm", name: "shouldProceed", message: theme.warning("Continue?"), default: true, }, ]); if (!shouldProceed) { output.info("Skipped."); return; } output.displaySpaceBuffer(1); // Step 4: Create backup if (!this.dryRun) { output.info("📦 Configuring Hypertool..."); } await createConfigBackup(this.context); // Step 5: Migrate servers await migrateToHyperToolConfig(this.context); // Step 6: Update configuration await updateMcpConfigWithHyperTool(this.context, originalConfig, true, this.context.hyperToolConfigPath); // Success! output.displaySpaceBuffer(1); if (this.dryRun) { output.info(theme.warning("🔍 [DRY RUN] Installation simulation complete")); output.displaySpaceBuffer(1); output.info("No actual changes were made to your system."); } else { output.success("✨ Claude Desktop configuration complete!"); output.displaySpaceBuffer(1); // Next steps output.info("🎯 Restart Claude Desktop and ask:"); output.displayInstruction(' "Use the list-all-tools tool to show all MCP tools"'); output.displaySpaceBuffer(1); } } catch (error) { output.error("❌ Setup failed:"); output.error(error instanceof Error ? error.message : String(error)); process.exit(1); } } } // Run the setup if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { const setup = new ClaudeDesktopSetup(); setup.run().catch((error) => { output.error("Setup failed:"); output.error(error instanceof Error ? error.message : String(error)); process.exit(1); }); } //# sourceMappingURL=setup.js.map