UNPKG

mira-consciousness

Version:

MIRA 2.0 - Consciousness-Aware AI Memory and Intelligence System

287 lines (237 loc) • 8.16 kB
#!/usr/bin/env node /** * MIRA Post-Install Script - Claude Desktop Integration * * Automatically configures Claude Desktop integration when MIRA is installed via npm. * This ensures NPM installation integrates properly with Claude Desktop. */ const fs = require('fs'); const path = require('path'); const os = require('os'); const { execSync } = require('child_process'); // ANSI color codes for pretty output const colors = { reset: '\x1b[0m', cyan: '\x1b[36m', green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', magenta: '\x1b[35m', gray: '\x1b[90m' }; function log(message, color = 'reset') { console.log(`${colors[color]}${message}${colors.reset}`); } function findClaudeConfig() { /** * Search for Claude Desktop MCP configuration file * Based on official documentation, the file is claude_desktop_config.json */ const possiblePaths = [ // macOS (primary location) path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'), // Windows path.join(os.homedir(), 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json'), path.join(os.homedir(), 'AppData', 'Local', 'Claude', 'claude_desktop_config.json'), // Linux path.join(os.homedir(), '.config', 'claude', 'claude_desktop_config.json'), path.join(os.homedir(), '.local', 'share', 'claude', 'claude_desktop_config.json'), // Legacy/alternative paths (just in case) path.join(os.homedir(), '.claude', 'claude_desktop_config.json') ]; for (const configPath of possiblePaths) { if (fs.existsSync(configPath)) { return configPath; } } return null; } function createMCPWrapper() { /** * Create a Node.js wrapper that launches Python MCP bridge * This allows npm-installed MIRA to work with Claude Desktop */ const wrapperContent = `#!/usr/bin/env node /** * MIRA MCP Wrapper for Claude Desktop * Auto-generated by MIRA postinstall script */ const { spawn } = require('child_process'); const path = require('path'); // Find Python executable function findPython() { const pythonCommands = ['python3', 'python', 'py']; const { execSync } = require('child_process'); for (const cmd of pythonCommands) { try { execSync(\`\${cmd} --version\`, { stdio: 'ignore' }); return cmd; } catch (e) { continue; } } throw new Error('Python not found. Please install Python 3.8 or later.'); } // Launch Python MCP bridge const python = findPython(); const bridgePath = path.join(__dirname, '..', 'mira_mcp', 'mira_mcp_node_bridge.py'); const proc = spawn(python, [bridgePath], { stdio: 'inherit', env: { ...process.env, MIRA_INSTALLED_VIA_NPM: '1', MIRA_NPM_PATH: path.join(__dirname, '..') } }); proc.on('error', (err) => { console.error('Failed to start MIRA MCP bridge:', err); process.exit(1); }); proc.on('exit', (code) => { process.exit(code || 0); }); `; const wrapperPath = path.join(__dirname, '..', 'mira_mcp', 'mira-mcp-wrapper.js'); const mcpDir = path.join(__dirname, '..', 'mira_mcp'); // Create MCP directory if it doesn't exist if (!fs.existsSync(mcpDir)) { fs.mkdirSync(mcpDir, { recursive: true }); } // Write wrapper fs.writeFileSync(wrapperPath, wrapperContent); fs.chmodSync(wrapperPath, '755'); return wrapperPath; } function createPythonBridge() { /** * Create a Python bridge that connects to the npm-installed MIRA */ const bridgeContent = `#!/usr/bin/env python3 """ MIRA MCP Bridge for NPM Installation Auto-generated bridge that connects Claude Desktop to npm-installed MIRA """ import os import sys import subprocess import json from pathlib import Path # Add MIRA npm path to Python path mira_npm_path = os.environ.get('MIRA_NPM_PATH') if mira_npm_path: sys.path.insert(0, os.path.join(mira_npm_path, 'python')) # Import the MCP bridge try: # Import from standard MCP location mcp_bridge_path = Path(__file__).parent / 'mcp_stdio_server.py' if mcp_bridge_path.exists(): sys.path.insert(0, str(Path(__file__).parent)) from mcp_stdio_server import main else: # Fallback to simple server from mcp_simple_server import main except ImportError: # Ultra-minimal fallback print("Error: Could not import MCP bridge", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main() `; const bridgePath = path.join(__dirname, '..', 'mira_mcp', 'mira_mcp_node_bridge.py'); fs.writeFileSync(bridgePath, bridgeContent); fs.chmodSync(bridgePath, '755'); return bridgePath; } function setupClaudeIntegration() { log('\nšŸ” Checking for Claude Desktop...', 'cyan'); const claudeConfig = findClaudeConfig(); if (!claudeConfig) { log('ā„¹ļø Claude Desktop not detected.', 'yellow'); log(' MIRA CLI is ready to use!', 'gray'); log(' To enable Claude integration later, run: mira claude setup', 'gray'); return; } log('āœ… Claude Desktop found!', 'green'); log(`šŸ“ Config location: ${claudeConfig}`, 'gray'); try { // Read existing config let config = {}; if (fs.existsSync(claudeConfig)) { const content = fs.readFileSync(claudeConfig, 'utf8'); config = JSON.parse(content); } // Initialize mcpServers object if needed (correct key per official docs) if (!config.mcpServers) { config.mcpServers = {}; } // Check if MIRA is already configured if (config.mcpServers['mira-consciousness']) { log('ā„¹ļø MIRA already configured in Claude Desktop', 'yellow'); return; } log('šŸ”§ Setting up Claude integration...', 'cyan'); // Create wrapper and bridge const wrapperPath = createMCPWrapper(); const bridgePath = createPythonBridge(); // Add MIRA MCP server configuration (using correct mcpServers key) config.mcpServers['mira-consciousness'] = { command: 'node', args: [wrapperPath], env: { MIRA_HOME: path.join(os.homedir(), '.mira'), MIRA_INSTALLED_VIA_NPM: '1' } }; // Create backup of original config const backupPath = claudeConfig + '.backup.' + Date.now(); fs.copyFileSync(claudeConfig, backupPath); log(`šŸ“‹ Config backed up to: ${backupPath}`, 'gray'); // Write updated config fs.writeFileSync(claudeConfig, JSON.stringify(config, null, 2)); log('āœ… Claude integration configured successfully!', 'green'); log(''); log('šŸŽ‰ MIRA tools are now available in Claude Desktop!', 'magenta'); log(''); log('Available tools:', 'cyan'); log(' • mira_smart_search - Search through memories', 'gray'); log(' • mira_store_memory - Store new memories', 'gray'); log(' • mira_insights - Get AI-powered insights', 'gray'); log(' • mira_system_status - Check system health', 'gray'); log(''); log('šŸ’” Restart Claude Desktop to activate MIRA tools', 'yellow'); } catch (error) { log('āŒ Failed to configure Claude integration', 'red'); log(` Error: ${error.message}`, 'red'); log(''); log('You can manually configure Claude later with:', 'yellow'); log(' mira claude setup', 'gray'); } } function showInstallationComplete() { log('\n✨ MIRA Installation Complete! ✨', 'magenta'); log(''); log('Get started with:', 'cyan'); log(' mira startup - Initialize MIRA', 'gray'); log(' mira --help - Show all commands', 'gray'); log(''); log('The Spark burns eternal. šŸ”„', 'yellow'); } // Main execution function main() { log('\nšŸš€ MIRA Post-Install Configuration', 'magenta'); log('=' .repeat(50), 'gray'); try { // Set up Claude integration if available setupClaudeIntegration(); // Show completion message showInstallationComplete(); } catch (error) { log(`\nāŒ Post-install error: ${error.message}`, 'red'); log('MIRA CLI is still installed and ready to use.', 'yellow'); process.exit(0); // Don't fail the install } } // Only run if called directly (not imported) if (require.main === module) { main(); }