ai-debug-local-mcp
Version:
šÆ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
456 lines (378 loc) ⢠13.2 kB
JavaScript
/**
* AI-Debug Automated Setup Script
* Configures AI-Debug for various AI coding environments
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');
// Colors for terminal output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
blue: '\x1b[34m'
};
function log(message, color = '') {
console.log(color + message + colors.reset);
}
function success(message) {
log('ā
' + message, colors.green);
}
function warn(message) {
log('ā ļø ' + message, colors.yellow);
}
function error(message) {
log('ā ' + message, colors.red);
}
function info(message) {
log('ā¹ļø ' + message, colors.blue);
}
// Get AI-Debug command path
function getAiDebugPath() {
try {
const npmBin = execSync('npm bin -g', { encoding: 'utf8' }).trim();
const aiDebugPath = path.join(npmBin, 'ai-debug-mcp');
if (fs.existsSync(aiDebugPath)) {
return aiDebugPath;
}
// Fallback to which command
const whichPath = execSync('which ai-debug-mcp', { encoding: 'utf8' }).trim();
if (whichPath) return whichPath;
} catch (e) {
// Try common locations
const commonPaths = [
'/usr/local/bin/ai-debug-mcp',
'/usr/bin/ai-debug-mcp',
path.join(os.homedir(), '.npm/bin/ai-debug-mcp'),
'ai-debug-mcp' // Let system resolve it
];
for (const p of commonPaths) {
if (fs.existsSync(p)) return p;
}
}
return 'ai-debug-mcp'; // Default fallback
}
// Claude Desktop setup
function setupClaude() {
log('\nš¤ Setting up AI-Debug for Claude Desktop...', colors.bright);
const platform = process.platform;
let configPath;
if (platform === 'darwin') {
configPath = path.join(os.homedir(), 'Library/Application Support/Claude/claude_desktop_config.json');
} else if (platform === 'win32') {
configPath = path.join(process.env.APPDATA || '', 'Claude/claude_desktop_config.json');
} else {
configPath = path.join(os.homedir(), '.config/Claude/claude_desktop_config.json');
}
// Create directory if it doesn't exist
const configDir = path.dirname(configPath);
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
let config = {};
// Read existing config
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, 'utf8');
config = JSON.parse(content);
info(`Found existing Claude config at: ${configPath}`);
// Backup existing config
const backupPath = configPath + '.backup.' + Date.now();
fs.copyFileSync(configPath, backupPath);
info(`Created backup: ${backupPath}`);
} catch (e) {
error(`Failed to parse existing config: ${e.message}`);
return false;
}
}
// Add AI-Debug configuration
if (!config.mcpServers) {
config.mcpServers = {};
}
const aiDebugPath = getAiDebugPath();
config.mcpServers['ai-debug'] = {
command: aiDebugPath,
args: []
};
// Write updated config
try {
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
success('Claude Desktop configuration updated!');
info(`Config location: ${configPath}`);
info(`AI-Debug command: ${aiDebugPath}`);
// Check if Claude is running
if (platform === 'darwin') {
try {
execSync('pgrep -x Claude', { stdio: 'ignore' });
warn('Claude Desktop is running. Please restart it for changes to take effect.');
} catch (e) {
// Claude not running, that's fine
}
}
return true;
} catch (e) {
error(`Failed to write config: ${e.message}`);
return false;
}
}
// Cursor setup
function setupCursor() {
log('\nāļø Setting up AI-Debug for Cursor...', colors.bright);
const platform = process.platform;
let settingsPath;
// Find Cursor settings path
if (platform === 'darwin') {
settingsPath = path.join(os.homedir(), 'Library/Application Support/Cursor/User/settings.json');
} else if (platform === 'win32') {
settingsPath = path.join(process.env.APPDATA || '', 'Cursor/User/settings.json');
} else {
settingsPath = path.join(os.homedir(), '.config/Cursor/User/settings.json');
}
if (!fs.existsSync(settingsPath)) {
warn('Cursor settings not found. Is Cursor installed?');
info('Expected location: ' + settingsPath);
info('\nManual setup instructions:');
info('1. Open Cursor');
info('2. Press Cmd+, (Mac) or Ctrl+, (Windows/Linux)');
info('3. Search for "MCP"');
info('4. Add this configuration:');
console.log(JSON.stringify({
"mcp.servers": {
"ai-debug": {
"command": getAiDebugPath(),
"args": []
}
}
}, null, 2));
return false;
}
try {
// Read existing settings
let settings = {};
if (fs.existsSync(settingsPath)) {
const content = fs.readFileSync(settingsPath, 'utf8');
settings = JSON.parse(content);
// Backup
const backupPath = settingsPath + '.backup.' + Date.now();
fs.copyFileSync(settingsPath, backupPath);
info(`Created backup: ${backupPath}`);
}
// Add MCP configuration
if (!settings['mcp.servers']) {
settings['mcp.servers'] = {};
}
settings['mcp.servers']['ai-debug'] = {
command: getAiDebugPath(),
args: []
};
// Write updated settings
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
success('Cursor configuration updated!');
info('Please restart Cursor for changes to take effect.');
return true;
} catch (e) {
error(`Failed to update Cursor settings: ${e.message}`);
return false;
}
}
// Project-specific setup for Claude Code
function setupProject() {
log('\nš Setting up AI-Debug for this project (Claude Code)...', colors.bright);
const projectRoot = process.cwd();
const claudeDir = path.join(projectRoot, '.claude');
const configPath = path.join(claudeDir, 'claude_desktop_config.json');
// Check if we're in a project directory
if (!fs.existsSync(path.join(projectRoot, 'package.json')) &&
!fs.existsSync(path.join(projectRoot, '.git'))) {
warn('This doesn\'t appear to be a project directory.');
warn('Run this command from your project root (where package.json or .git exists)');
return false;
}
try {
// Create .claude directory
if (!fs.existsSync(claudeDir)) {
fs.mkdirSync(claudeDir, { recursive: true });
info('Created .claude directory');
}
let config = {};
// Check if config already exists
if (fs.existsSync(configPath)) {
const content = fs.readFileSync(configPath, 'utf8');
config = JSON.parse(content);
info('Found existing project config');
// Backup
const backupPath = configPath + '.backup.' + Date.now();
fs.copyFileSync(configPath, backupPath);
info(`Created backup: ${backupPath}`);
}
// Add AI-Debug
if (!config.mcpServers) {
config.mcpServers = {};
}
config.mcpServers['ai-debug'] = {
command: getAiDebugPath(),
args: []
};
// Write config
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
success('Project-specific AI-Debug configuration created!');
info(`Config location: ${configPath}`);
// Check if .gitignore exists and offer to add .claude
const gitignorePath = path.join(projectRoot, '.gitignore');
if (fs.existsSync(gitignorePath)) {
const gitignore = fs.readFileSync(gitignorePath, 'utf8');
if (!gitignore.includes('.claude')) {
info('\nTip: Add .claude/ to .gitignore if you don\'t want to commit this config');
info('Or commit it to share the debugging setup with your team');
}
}
info('\nNext steps:');
info('1. Open this project in Claude Code');
info('2. AI-Debug will be available for this project only');
info('3. Test with: await get_current_mode()');
return true;
} catch (e) {
error(`Failed to setup project config: ${e.message}`);
return false;
}
}
// Windsurf setup
function setupWindsurf() {
log('\nš Setting up AI-Debug for Windsurf...', colors.bright);
// Windsurf uses a different configuration approach
// It stores MCP servers in a separate config file
const platform = process.platform;
let configPath;
if (platform === 'darwin') {
configPath = path.join(os.homedir(), 'Library/Application Support/Windsurf/mcp-servers.json');
} else if (platform === 'win32') {
configPath = path.join(process.env.APPDATA || '', 'Windsurf/mcp-servers.json');
} else {
configPath = path.join(os.homedir(), '.config/Windsurf/mcp-servers.json');
}
const configDir = path.dirname(configPath);
if (!fs.existsSync(configDir)) {
warn('Windsurf configuration directory not found. Is Windsurf installed?');
info('\nManual setup instructions:');
info('1. Open Windsurf');
info('2. Go to Preferences ā Extensions ā MCP');
info('3. Add new MCP server:');
info(' - Name: ai-debug');
info(' - Command: ' + getAiDebugPath());
info(' - Arguments: (leave empty)');
return false;
}
try {
let servers = {};
if (fs.existsSync(configPath)) {
const content = fs.readFileSync(configPath, 'utf8');
servers = JSON.parse(content);
// Backup
const backupPath = configPath + '.backup.' + Date.now();
fs.copyFileSync(configPath, backupPath);
info(`Created backup: ${backupPath}`);
}
// Add AI-Debug
servers['ai-debug'] = {
name: 'AI-Debug MCP Server',
command: getAiDebugPath(),
args: [],
enabled: true
};
// Write config
fs.writeFileSync(configPath, JSON.stringify(servers, null, 2));
success('Windsurf configuration updated!');
info('Please restart Windsurf for changes to take effect.');
return true;
} catch (e) {
error(`Failed to update Windsurf config: ${e.message}`);
return false;
}
}
// Verify installation
function verifyInstallation() {
log('\nš Verifying AI-Debug installation...', colors.bright);
const aiDebugPath = getAiDebugPath();
// Check if command exists
try {
const version = execSync(`${aiDebugPath} --version`, { encoding: 'utf8' }).trim();
success(`AI-Debug installed: ${aiDebugPath}`);
info(`Version: ${version}`);
// Check Playwright
try {
execSync('npx playwright --version', { stdio: 'ignore' });
success('Playwright is installed');
} catch (e) {
warn('Playwright not found. Installing browser dependencies...');
try {
execSync('npx playwright install chromium', { stdio: 'inherit' });
success('Playwright chromium installed');
} catch (e) {
error('Failed to install Playwright. You may need to run: npx playwright install chromium');
}
}
return true;
} catch (e) {
error('AI-Debug command not found. Please ensure it\'s installed globally:');
info('npm install -g ai-debug-local-mcp');
return false;
}
}
// Main setup function
function main() {
const args = process.argv.slice(2);
const target = args[0] || 'all';
log('š AI-Debug Automated Setup', colors.bright + colors.blue);
log('===========================\n', colors.bright);
// First verify installation
if (!verifyInstallation()) {
error('\nPlease install AI-Debug first:');
info('npm install -g ai-debug-local-mcp');
process.exit(1);
}
let setupCount = 0;
let successCount = 0;
if (target === 'all' || target === 'claude') {
setupCount++;
if (setupClaude()) successCount++;
}
if (target === 'all' || target === 'cursor') {
setupCount++;
if (setupCursor()) successCount++;
}
if (target === 'all' || target === 'windsurf') {
setupCount++;
if (setupWindsurf()) successCount++;
}
if (target === 'project') {
setupCount++;
if (setupProject()) successCount++;
}
if (setupCount === 0) {
error(`\nUnknown target: ${target}`);
info('Usage: npx ai-debug-setup [claude|cursor|windsurf|project|all]');
process.exit(1);
}
// Summary
log('\n' + '='.repeat(50), colors.bright);
if (successCount === setupCount) {
success(`\nSetup complete! ${successCount}/${setupCount} environments configured.`);
info('\nNext steps:');
info('1. Restart your AI coding environment');
info('2. Test with: await get_current_mode()');
info('3. Start debugging with: await inject_debugging({ url: "..." })');
} else {
warn(`\nSetup partially complete: ${successCount}/${setupCount} succeeded.`);
info('Check the errors above and try manual setup for failed environments.');
}
info('\nFor help: https://github.com/yourusername/ai-debug-mcp');
}
// Run if called directly
if (require.main === module) {
main();
}
module.exports = { setupClaude, setupCursor, setupWindsurf };