UNPKG

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

122 lines (103 loc) • 3.12 kB
const { chromium } = require('playwright'); let browser; let pages = new Map(); // Cleanup handlers process.on('SIGTERM', cleanup); process.on('SIGINT', cleanup); process.on('exit', cleanup); async function cleanup() { try { // Close all pages for (const [id, page] of pages) { await page.close().catch(() => {}); } pages.clear(); // Close browser if (browser) { await browser.close().catch(() => {}); } } catch (error) { // Ignore errors during cleanup } process.exit(0); } async function start() { try { browser = await chromium.launch({ headless: true, // Limit browser resources and prevent AbortSignal accumulation args: [ '--disable-gpu', '--disable-dev-shm-usage', '--disable-setuid-sandbox', '--no-sandbox', '--disable-web-security', '--disable-features=site-per-process', '--max_old_space_size=512', // Limit memory usage '--disable-backgrounding-occluded-windows', '--disable-background-timer-throttling' ] }); // Browser doesn't have setDefaultTimeout, this is set per-page instead console.log('READY'); } catch (error) { console.error('Failed to start browser:', error); process.exit(1); } } async function createPage(url) { const page = await browser.newPage(); const id = Date.now().toString(); // Set timeouts to prevent AbortSignal accumulation page.setDefaultTimeout(30000); page.setDefaultNavigationTimeout(30000); pages.set(id, page); if (url) { await page.goto(url); } return id; } // Simple message protocol process.stdin.on('data', async (data) => { const message = data.toString().trim(); const [command, ...args] = message.split(' '); try { switch (command) { case 'CREATE_PAGE': const pageId = await createPage(args[0]); console.log(`PAGE_CREATED ${pageId}`); break; case 'CLOSE_PAGE': const page = pages.get(args[0]); if (page) { try { // Clear any pending operations before closing await page.close({ runBeforeUnload: false }); } catch (error) { // Page might already be closed, ignore console.debug(`Error closing page ${args[0]}:`, error.message); } pages.delete(args[0]); console.log(`PAGE_CLOSED ${args[0]}`); } break; case 'EXECUTE': const pageForExec = pages.get(args[0]); if (pageForExec) { const scriptBase64 = args[1]; const script = Buffer.from(scriptBase64, 'base64').toString('utf8'); const result = await pageForExec.evaluate(script); console.log(`RESULT ${JSON.stringify(result)}`); } else { console.log(`ERROR Page ${args[0]} not found`); } break; default: console.log(`UNKNOWN_COMMAND ${command}`); } } catch (error) { console.log(`ERROR ${error.message}`); } }); // Start the browser start().catch(console.error);