const fs = require('fs'); const path = require('path'); const os = require('os'); const readline = require('readline'); const homeDir = os.homedir(); const appDataDir = process.env.APPDATA || path.join(homeDir, 'AppData', 'Roaming'); // Map of IDE name to its config file path(s) const IDE_CONFIGS = { '1': { name: 'Gemini / Antigravity IDE', paths: [ path.join(homeDir, '.gemini', 'config', 'mcp_config.json'), path.join(homeDir, '.gemini', 'antigravity-ide', 'mcp_config.json') ] }, '2': { name: 'Cursor', paths: [path.join(homeDir, '.cursor', 'mcp.json')] }, '3': { name: 'Windsurf', paths: [path.join(homeDir, '.codeium', 'windsurf', 'mcp_config.json')] }, '4': { name: 'Cline (VS Code Extension)', paths: [ path.join(appDataDir, 'Code', 'User', 'globalStorage', 'saoudrizwan.cline', 'settings', 'cline_mcp_settings.json'), path.join(appDataDir, 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json') ] }, '5': { name: 'All of the above', paths: [] // Will be populated dynamically } }; // Populate the "All" option paths IDE_CONFIGS['5'].paths = [ ...IDE_CONFIGS['1'].paths, ...IDE_CONFIGS['2'].paths, ...IDE_CONFIGS['3'].paths, ...IDE_CONFIGS['4'].paths ]; function setupConfigForPaths(serverPath, targetPaths) { let configUpdated = false; for (const configPath of targetPaths) { const configDir = path.dirname(configPath); // Ensure directory exists if (!fs.existsSync(configDir)) { try { fs.mkdirSync(configDir, { recursive: true }); } catch (err) { continue; } } let config = { mcpServers: {} }; // Read existing config if it exists if (fs.existsSync(configPath)) { try { const raw = fs.readFileSync(configPath, 'utf8'); config = JSON.parse(raw); if (!config.mcpServers) { config.mcpServers = {}; } } catch (err) { console.warn(`[setup-mcp] Warning: Failed to parse existing config at ${configPath}. Creating new one.`); } } // Add or update the figma-bridge server config config.mcpServers['figma-bridge'] = { command: 'node', args: [serverPath] }; // Write updated config back to disk try { fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8'); console.log(`[setup-mcp] Successfully updated configuration at: ${configPath}`); configUpdated = true; } catch (err) { console.error(`[setup-mcp] Error: Failed to write to config path ${configPath}: ${err.message}`); } } if (configUpdated) { console.log('[setup-mcp] Setup complete! Please reload or restart your chosen AI IDE to start using the bridge.'); } else { console.error('[setup-mcp] Failed to update any configuration files.'); } } function promptUser() { console.log('\n=================================================='); console.log(' Figma MCP Bridge Auto Setup '); console.log('==================================================\n'); // Resolve absolute path to the compiled server.js file const serverPath = path.resolve(__dirname, '..', 'bridge-server', 'dist', 'server.js') .replace(/\\/g, '/'); // Use forward slashes for cross-platform safety in JSON configs if (!fs.existsSync(serverPath)) { console.error(`[setup-mcp] Error: Compiled server file not found at ${serverPath}`); console.error('[setup-mcp] Please make sure to compile the project first by running "npm run build"'); process.exit(1); } const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); console.log('Select the AI IDE you want to configure:'); Object.keys(IDE_CONFIGS).forEach(key => { console.log(` ${key}) ${IDE_CONFIGS[key].name}`); }); console.log(' 6) Skip (Configure manually later)\n'); rl.question('Enter option number (1-6): ', (answer) => { rl.close(); const cleanAnswer = answer.trim(); if (cleanAnswer === '6') { console.log('[setup-mcp] Setup skipped. You can configure your IDE manually later using instructions in README.md.'); process.exit(0); } const selectedOption = IDE_CONFIGS[cleanAnswer]; if (selectedOption) { console.log(`\n[setup-mcp] Configuring for: ${selectedOption.name}...`); setupConfigForPaths(serverPath, selectedOption.paths); } else { console.log('\n[setup-mcp] Invalid option selected. Setup skipped. Run "npm run setup-mcp" to try again.'); } }); } promptUser();