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

1,478 lines (1,323 loc) โ€ข 111 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from '@modelcontextprotocol/sdk/types.js'; import { chromium, Browser, Page } from 'playwright'; import { nanoid } from 'nanoid'; import { APIKeyManager, APIKeyInfo } from './utils/api-key-manager.js'; import { CloudAIService } from './utils/cloud-ai-service.js'; import { LocalDebugEngine } from './engines/local-debug-engine.js'; import { DebugSession as BaseDebugSession } from './types.js'; import { tidewave } from './utils/tidewave-integration.js'; import { AuditEngine } from './engines/audit-engine.js'; import { VersionChecker } from './utils/version-checker.js'; import { CICDIntegration } from './utils/ci-cd-integration.js'; interface DebugSession { id: string; sessionId: string; browser: Browser; page: Page; url: string; framework: string; startTime: Date; state: any; events: any[]; } /** * AI Debug Local MCP Server * * Revolutionary local debugging with freemium cloud AI features. * * Architecture: * - Runs locally (works with localhost apps) * - Basic debugging (free tier) * - Advanced AI analysis (paid tier with API key) * - Compiled binary distribution (IP protection) */ export class AIDebugLocalMCPServer { private server: Server; private sessions: Map<string, DebugSession> = new Map(); private apiKeyManager: APIKeyManager; private cloudAI: CloudAIService; private localEngine: LocalDebugEngine; private auditEngine: AuditEngine; private versionChecker: VersionChecker; private cicdIntegration: CICDIntegration; constructor() { this.versionChecker = new VersionChecker(); this.server = new Server( { name: 'ai-debug-local', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); this.apiKeyManager = new APIKeyManager(); this.cloudAI = new CloudAIService(); this.localEngine = new LocalDebugEngine(); this.auditEngine = new AuditEngine(); this.cicdIntegration = new CICDIntegration(); this.setupToolHandlers(); this.initializeServices(); } private async initializeServices() { // Initialize API key manager await this.apiKeyManager.initialize(); // Set API key for cloud service if available const apiKey = process.env.AI_DEBUG_API_KEY; if (apiKey) { this.cloudAI.setApiKey(apiKey); } } private setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'inject_debugging', description: 'Inject AI debugging capabilities into a local web application. Launches a browser, navigates to your app, and injects revolutionary debugging code. Works with localhost and private applications.', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL of the web application to debug (e.g., http://localhost:3000)' }, framework: { type: 'string', enum: ['auto', 'nextjs', 'remix', 'astro', 'nuxt', 'qwik', 'solidjs', 'sveltekit', 'rails', 'django', 'phoenix', 'react', 'vue', 'angular', 'svelte', 'flutter-web'], description: 'Web framework to optimize for (auto-detect if not specified)', default: 'auto' }, headless: { type: 'boolean', description: 'Run browser in headless mode (default: false)', default: false } }, required: ['url'] } }, { name: 'monitor_realtime', description: 'Monitor real-time application events. FREE: Basic event collection. PREMIUM: AI-powered pattern analysis and insights.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, duration: { type: 'number', description: 'Monitoring duration in seconds (default: 30)', default: 30 }, aiAnalysis: { type: 'boolean', description: 'Enable AI-powered analysis (requires API key)', default: false } }, required: ['sessionId'] } }, { name: 'simulate_user_action', description: 'Simulate user interactions in the local browser. FREE: Basic actions. PREMIUM: AI-optimized interaction patterns.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, action: { type: 'string', enum: ['click', 'type', 'submit', 'scroll', 'hover'], description: 'Type of user action' }, selector: { type: 'string', description: 'CSS selector for target element' }, value: { type: 'string', description: 'Value for type actions' } }, required: ['sessionId', 'action', 'selector'] } }, { name: 'take_screenshot', description: 'Capture screenshots of your local application for visual debugging.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, fullPage: { type: 'boolean', description: 'Capture full page (default: true)', default: true } }, required: ['sessionId'] } }, { name: 'analyze_with_ai', description: 'PREMIUM: Get revolutionary AI insights about your application. Requires API key.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, analysisType: { type: 'string', enum: ['performance', 'ux', 'accessibility', 'security', 'comprehensive'], description: 'Type of AI analysis', default: 'comprehensive' } }, required: ['sessionId'] } }, { name: 'get_debug_report', description: 'Generate debugging report. FREE: Basic report. PREMIUM: AI-enhanced with insights and recommendations.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, includeAI: { type: 'boolean', description: 'Include AI analysis (requires API key)', default: false } }, required: ['sessionId'] } }, { name: 'close_session', description: 'Close debugging session and clean up browser resources.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'get_subscription_info', description: 'Get information about AI Debug subscription and API key status.', inputSchema: { type: 'object', properties: {}, additionalProperties: false } }, { name: 'run_audit', description: 'Run comprehensive audits on the web page for accessibility, performance, SEO, security, and best practices. Returns detailed scores and actionable recommendations.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, categories: { type: 'array', items: { type: 'string', enum: ['all', 'accessibility', 'performance', 'seo', 'security', 'bestPractices'] }, description: 'Audit categories to run (default: all)', default: ['all'] } }, required: ['sessionId'] } }, { name: 'mock_network', description: 'Mock network responses to test different scenarios. Useful for testing error handling, slow responses, or specific data conditions.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, action: { type: 'string', enum: ['add', 'remove', 'clear', 'list'], description: 'Mock action to perform' }, urlPattern: { type: 'string', description: 'URL pattern to mock (supports * wildcards)' }, response: { type: 'object', properties: { status: { type: 'number', description: 'HTTP status code (default: 200)' }, body: { description: 'Response body (string or JSON)' }, headers: { type: 'object', description: 'Response headers' }, delay: { type: 'number', description: 'Delay in milliseconds before responding' } } } }, required: ['sessionId', 'action'] } }, { name: 'flutter_widget_tree', description: 'Get the Flutter widget tree for debugging Flutter Web applications. Shows widget hierarchy, properties, and render objects.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'flutter_performance', description: 'Get Flutter performance metrics including FPS, frame times, and widget build performance.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'flutter_inspect_widget', description: 'Inspect a specific Flutter widget by ID to see its properties and state.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, widgetId: { type: 'string', description: 'Widget ID to inspect' }, highlight: { type: 'boolean', description: 'Highlight the widget in the UI', default: false } }, required: ['sessionId', 'widgetId'] } }, { name: 'tidewave_query', description: 'Execute Tidewave AI-powered queries against Phoenix/Rails applications for enhanced debugging and testing. Access logs, execute SQL, trace processes, and more.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' }, tool: { type: 'string', enum: ['logs', 'eval', 'sql', 'processes', 'documentation', 'dependencies'], description: 'Tidewave tool to execute' }, params: { type: 'object', description: 'Parameters for the Tidewave tool', additionalProperties: true } }, required: ['sessionId', 'tool'] } }, { name: 'debug_hydration', description: 'Detect SSR/CSR hydration mismatches that cause React, Next.js, Remix, and other framework errors. Shows server vs client HTML differences.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'analyze_bundles', description: 'Analyze JavaScript bundle sizes, loading patterns, and code coverage. Helps identify performance bottlenecks and unused code.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'track_route_changes', description: 'Monitor SPA route changes, navigation performance, and history state. Works with any client-side router.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'detect_problems', description: 'Automatically detect common web app problems: hydration errors, large bundles, slow routes, poor caching, and more.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'nextjs_page_info', description: 'Get Next.js page information including rendering type (SSR/SSG/ISR), data fetching methods, and app directory usage.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'nextjs_image_audit', description: 'Audit Next.js image optimization. Detects unoptimized images, suggests next/image usage, and identifies oversized images.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'nextjs_detect_issues', description: 'Detect Next.js specific problems: hydration errors, large RSC payloads, slow transitions, unnecessary SSR.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'rails_turbo_analysis', description: 'Analyze Rails Turbo/Hotwire performance: cache hit rates, frame loading, navigation timing.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'csrf_security_check', description: 'Check CSRF token configuration for Rails/Django apps. Detects missing tokens in forms and AJAX requests.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'stimulus_controllers', description: 'List and analyze Stimulus controllers in Rails applications. Shows actions, targets, and potential issues.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'meta_framework_info', description: 'Get information about detected meta-framework (Remix, Astro, Nuxt, Qwik, SolidJS, SvelteKit) including version, features, and build tool.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'remix_loader_analysis', description: 'Analyze Remix loader performance including execution times, data sizes, and caching behavior.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'astro_islands_audit', description: 'Audit Astro islands for hydration strategies, component usage, and performance optimization opportunities.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'nuxt_payload_analysis', description: 'Analyze Nuxt payload size, hydration state, and server-side data to identify optimization opportunities.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'qwik_resumability_check', description: 'Check Qwik resumability performance including serialized state size, QRL loading, and lazy execution metrics.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'vite_hmr_monitor', description: 'Monitor Vite HMR (Hot Module Replacement) events, update times, and errors during development.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'detect_meta_framework_issues', description: 'Detect framework-specific issues in Remix, Astro, Nuxt, Qwik, SolidJS, or SvelteKit applications.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Debug session ID' } }, required: ['sessionId'] } }, { name: 'init_ci_cd', description: 'Initialize CI/CD pipeline templates with AI debugging integration. Generates GitHub Actions, GitLab CI, or other CI/CD configurations with automated testing and debugging capabilities.', inputSchema: { type: 'object', properties: { projectDir: { type: 'string', description: 'Project directory path' }, provider: { type: 'string', enum: ['github', 'gitlab', 'circleci', 'jenkins'], description: 'CI/CD provider', default: 'github' }, appUrl: { type: 'string', description: 'Application URL for testing', default: 'http://localhost:3000' }, framework: { type: 'string', enum: ['auto', 'react', 'vue', 'angular', 'nextjs', 'phoenix', 'rails', 'node'], description: 'Project framework (auto-detect if not specified)', default: 'auto' }, tools: { type: 'array', items: { type: 'string', enum: ['debug_page', 'performance_audit', 'run_accessibility_check', 'tidewave_query'] }, description: 'AI debugging tools to include in CI/CD', default: ['debug_page', 'performance_audit'] } }, required: ['projectDir'] } } ] as Tool[] }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { switch (request.params.name) { case 'inject_debugging': return await this.injectDebugging(request.params.arguments); case 'monitor_realtime': return await this.monitorRealtime(request.params.arguments); case 'simulate_user_action': return await this.simulateUserAction(request.params.arguments); case 'take_screenshot': return await this.takeScreenshot(request.params.arguments); case 'analyze_with_ai': return await this.analyzeWithAI(request.params.arguments); case 'get_debug_report': return await this.getDebugReport(request.params.arguments); case 'close_session': return await this.closeSession(request.params.arguments); case 'get_subscription_info': return await this.getSubscriptionInfo(); case 'run_audit': return await this.runAudit(request.params.arguments); case 'mock_network': return await this.mockNetwork(request.params.arguments); case 'flutter_widget_tree': return await this.getFlutterWidgetTree(request.params.arguments); case 'flutter_performance': return await this.getFlutterPerformance(request.params.arguments); case 'flutter_inspect_widget': return await this.inspectFlutterWidget(request.params.arguments); case 'tidewave_query': return await this.executeTidewaveQuery(request.params.arguments); case 'debug_hydration': return await this.debugHydration(request.params.arguments); case 'analyze_bundles': return await this.analyzeBundles(request.params.arguments); case 'track_route_changes': return await this.trackRouteChanges(request.params.arguments); case 'detect_problems': return await this.detectProblems(request.params.arguments); case 'nextjs_page_info': return await this.getNextJSPageInfo(request.params.arguments); case 'nextjs_image_audit': return await this.getNextJSImageAudit(request.params.arguments); case 'nextjs_detect_issues': return await this.detectNextJSIssues(request.params.arguments); case 'rails_turbo_analysis': return await this.analyzeTurbo(request.params.arguments); case 'csrf_security_check': return await this.checkCSRFSecurity(request.params.arguments); case 'stimulus_controllers': return await this.getStimulusControllers(request.params.arguments); case 'meta_framework_info': return await this.getMetaFrameworkInfo(request.params.arguments); case 'remix_loader_analysis': return await this.analyzeRemixLoaders(request.params.arguments); case 'astro_islands_audit': return await this.auditAstroIslands(request.params.arguments); case 'nuxt_payload_analysis': return await this.analyzeNuxtPayload(request.params.arguments); case 'qwik_resumability_check': return await this.checkQwikResumability(request.params.arguments); case 'vite_hmr_monitor': return await this.monitorViteHMR(request.params.arguments); case 'detect_meta_framework_issues': return await this.detectMetaFrameworkIssues(request.params.arguments); case 'init_ci_cd': return await this.initCICD(request.params.arguments); default: throw new Error(`Unknown tool: ${request.params.name}`); } } catch (error) { return this.createErrorResponse(error); } }); } private async injectDebugging(args: any) { const { url, framework = 'auto', headless = false } = args; const sessionId = nanoid(); try { // Launch local browser const browser = await chromium.launch({ headless, devtools: !headless }); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle' }); // Attach local engine to page await this.localEngine.attachToPage(page); // Detect Tidewave capabilities const tidewaveCapabilities = await tidewave.detectTidewave(url); // Detect framework let detectedFramework = framework; if (framework === 'auto') { detectedFramework = await this.localEngine.detectFramework(page); // If Tidewave detected, use its framework info if (tidewaveCapabilities) { detectedFramework = tidewaveCapabilities.framework === 'unknown' ? detectedFramework : tidewaveCapabilities.framework; } } // Inject our revolutionary debugging code (local version) await this.localEngine.injectDebugging(page, detectedFramework); // Capture initial state with Tidewave enhancement let state = await this.localEngine.captureState(); if (tidewaveCapabilities) { state = await tidewave.enhanceDebugState(url, state); } // Store session const session: DebugSession = { id: sessionId, sessionId, browser, page, url, framework: detectedFramework, startTime: new Date(), state, events: [] }; this.sessions.set(sessionId, session); // Wait for initialization await page.waitForTimeout(1000); return { content: [{ type: 'text', text: `๐Ÿ”ฌ **AI Debug Session Started** **Session ID:** \`${sessionId}\` **URL:** ${url} **Framework:** ${detectedFramework} **Browser:** Local browser launched **๐Ÿš€ Debugging Capabilities Injected:** - โœ… Real-time event monitoring - โœ… User interaction simulation - โœ… Visual debugging with screenshots - โœ… Framework-specific hooks (${detectedFramework}) - โœ… Local performance analysis ${detectedFramework === 'flutter-web' ? `- โœ… Flutter widget tree inspection - โœ… Flutter performance metrics (FPS, frame times) - โœ… Flutter widget property inspection - โœ… Flutter DevTools integration${this.localEngine.isFlutterConnected() ? ' (Connected!)' : ' (Attempting connection...)'}` : ''} **๐Ÿ’ก Available Features:** - **FREE:** Basic debugging, screenshots, event monitoring - **PREMIUM:** AI insights, advanced analysis, recommendations **Next Steps:** 1. Use \`monitor_realtime\` to observe behavior 2. Use \`simulate_user_action\` to test interactions 3. Use \`analyze_with_ai\` for revolutionary AI insights (Premium) ${this.apiKeyManager.hasValidKey() ? '๐Ÿ”‘ **Premium features available** with your API key!' : '๐Ÿ’ก **Upgrade:** Get API key at https://ai-debug.com/pricing for AI features' } **Local debugging is now active! ๐ŸŽฏ**` }] }; } catch (error) { throw new Error(`Failed to inject debugging: ${error instanceof Error ? error.message : error}`); } } private async monitorRealtime(args: any) { const { sessionId, duration = 30, aiAnalysis = false } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } // Always do local monitoring const events = await this.localEngine.monitorEvents(session.page, duration); session.events.push(...events); // Get console messages with smart truncation const consoleMessages = this.localEngine.getConsoleMessages({ maxTokens: 2000 // Reserve tokens for console output }); let analysis = this.localEngine.basicAnalysis(events); // Premium AI analysis if requested and available if (aiAnalysis) { if (!this.apiKeyManager.hasValidKey()) { return this.createPremiumFeatureResponse('AI Analysis'); } try { const aiInsights = await this.cloudAI.analyzeEvents(events); analysis = { ...analysis, ...aiInsights }; } catch (error) { // Fallback to local analysis if cloud fails console.error('Cloud AI analysis failed, using local analysis'); } } return { content: [{ type: 'text', text: `๐Ÿ“Š **Real-time Monitoring Complete** (${duration}s) **Events Captured:** ${events.length} **User Interactions:** ${events.filter(e => e.type === 'userInteraction').length} **Network Requests:** ${events.filter(e => e.type === 'networkRequest').length} **DOM Changes:** ${events.filter(e => e.type === 'domMutation').length} **Errors:** ${events.filter(e => e.type === 'error').length} **๐Ÿ“ˆ Basic Analysis:** - **Most Active Element:** ${analysis.mostActiveElement || 'N/A'} - **Performance Score:** ${analysis.performanceScore || 'N/A'}/100 - **Error Rate:** ${analysis.errorRate || 0}% ${aiAnalysis && analysis.aiInsights ? `**๐Ÿง  AI Insights:**\n${analysis.aiInsights.map((insight: string) => `๐Ÿ’ก ${insight}`).join('\n')}` : '๐Ÿ’ก **Enable AI analysis** with `aiAnalysis: true` for revolutionary insights!' } ${events.filter(e => e.type === 'error').length > 0 ? `โš ๏ธ **Errors Detected:**\n${events.filter(e => e.type === 'error').map(e => `- ${e.data.message}`).slice(0, 3).join('\n')}` : 'โœ… No errors detected' }` }] }; } private async simulateUserAction(args: any) { const { sessionId, action, selector, value } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } const result = await this.localEngine.simulateAction(session.page, action, selector, value); // Capture events triggered by the action const postActionEvents = await this.localEngine.captureRecentEvents(session.page, 2000); session.events.push(...postActionEvents); return { content: [{ type: 'text', text: `๐ŸŽฏ **User Action Simulation** **Action:** ${result.description} **Success:** ${result.success ? 'โœ…' : 'โŒ'} **Duration:** ${result.duration}ms **๐Ÿ“Š Response Analysis:** - **Events Triggered:** ${postActionEvents.length} - **DOM Changes:** ${postActionEvents.filter(e => e.type === 'domMutation').length} - **Network Activity:** ${postActionEvents.filter(e => e.type === 'networkRequest').length} ${result.success ? 'โœ… Action completed successfully' : `โŒ Action failed: ${result.error}` } ${postActionEvents.length > 0 ? `**Recent Events:**\n${postActionEvents.slice(0, 3).map(e => `- ${e.type}: ${e.data.target || e.data.url || 'N/A'}`).join('\n')}` : 'โš ๏ธ No response detected - action may have been ignored' }` }] }; } private async takeScreenshot(args: any) { const { sessionId, fullPage = true } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } const screenshot = await session.page.screenshot({ type: 'png', fullPage }); return { content: [ { type: 'text', text: `๐Ÿ“ธ **Screenshot Captured** **Type:** ${fullPage ? 'Full page' : 'Viewport'} **Timestamp:** ${new Date().toLocaleTimeString()} **URL:** ${session.url} *Visual debugging via local browser*` }, { type: 'image', data: screenshot.toString('base64'), mimeType: 'image/png' } ] }; } private async analyzeWithAI(args: any) { const { sessionId, analysisType = 'comprehensive' } = args; if (!this.apiKeyManager.hasValidKey()) { return this.createPremiumFeatureResponse('AI Analysis'); } const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } try { // Get current page state const pageState = await this.localEngine.extractPageState(session.page); // Send to cloud AI for revolutionary analysis const aiAnalysis = await this.cloudAI.comprehensiveAnalysis( session.events, pageState, analysisType ); await this.apiKeyManager.recordUsage('ai_analysis'); return { content: [{ type: 'text', text: `๐Ÿง  **Revolutionary AI Analysis** (${analysisType}) ## ๐ŸŽฏ Overall Assessment **Health Score:** ${aiAnalysis.healthScore}/100 **User Experience:** ${aiAnalysis.uxScore}/100 **Performance:** ${aiAnalysis.performanceScore}/100 ## ๐Ÿ” Key Findings ${aiAnalysis.findings.map((finding: any) => `**${finding.severity.toUpperCase()}:** ${finding.title}\n ${finding.description}` ).join('\n\n')} ## ๐Ÿ’ก AI Recommendations ${aiAnalysis.recommendations.map((rec: any) => `**${rec.priority}:** ${rec.title}\n ${rec.description}\n *Impact:* ${rec.impact}` ).join('\n\n')} ## โšก Quick Fixes ${aiAnalysis.quickFixes.map((fix: string) => `- ${fix}`).join('\n')} ## ๐Ÿ—๏ธ Framework-Specific Insights ${aiAnalysis.frameworkInsights.map((insight: string) => `๐Ÿ’ก ${insight}`).join('\n')} *Powered by revolutionary AI debugging engine*` }] }; } catch (error) { throw new Error(`AI analysis failed: ${error instanceof Error ? error.message : error}`); } } private async getDebugReport(args: any) { const { sessionId, includeAI = false } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } // Always generate basic report const basicReport = this.localEngine.generateBasicReport(session); let aiEnhancements = null; if (includeAI) { if (!this.apiKeyManager.hasValidKey()) { return this.createPremiumFeatureResponse('AI-Enhanced Reports'); } try { aiEnhancements = await this.cloudAI.enhanceReport(basicReport, session.events); await this.apiKeyManager.recordUsage('ai_report'); } catch (error) { console.error('AI enhancement failed, using basic report'); } } const duration = Math.round((Date.now() - session.startTime.getTime()) / 1000); return { content: [{ type: 'text', text: `๐Ÿ“‹ **AI Debug Report** - Session ${sessionId} ## ๐ŸŒ Session Information **URL:** ${session.url} **Framework:** ${session.framework} **Duration:** ${duration}s **Events Captured:** ${session.events.length} ## ๐Ÿ“Š Activity Summary **User Interactions:** ${session.events.filter(e => e.type === 'userInteraction').length} **Network Requests:** ${session.events.filter(e => e.type === 'networkRequest').length} **DOM Changes:** ${session.events.filter(e => e.type === 'domMutation').length} **Console Messages:** ${session.events.filter(e => e.type === 'console').length} **Errors:** ${session.events.filter(e => e.type === 'error').length} ## ๐Ÿ” Basic Analysis ${basicReport.findings.map((finding: string) => `- ${finding}`).join('\n')} ${aiEnhancements ? ` ## ๐Ÿง  AI-Enhanced Insights **Performance Rating:** ${aiEnhancements.performanceRating}/10 **Code Quality:** ${aiEnhancements.codeQuality}/10 **User Experience:** ${aiEnhancements.uxRating}/10 **Key Recommendations:** ${aiEnhancements.recommendations.map((rec: string) => `๐Ÿ’ก ${rec}`).join('\n')} **Optimization Opportunities:** ${aiEnhancements.optimizations.map((opt: string) => `โšก ${opt}`).join('\n')} ` : ` ๐Ÿ’ก **Upgrade for AI Insights:** Add \`includeAI: true\` and get revolutionary AI analysis! ๐Ÿ”— **Get API Key:** https://ai-debug.com/pricing `} ## ๐Ÿ•’ Recent Activity ${session.events.slice(-5).map(e => `**${new Date(e.data.timestamp).toLocaleTimeString()}** - ${e.type}` ).join('\n')} --- *Generated by AI Debug Local MCP Server*` }] }; } private async closeSession(args: any) { const { sessionId } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } const duration = Math.round((Date.now() - session.startTime.getTime()) / 1000); const eventCount = session.events.length; await session.browser.close(); this.sessions.delete(sessionId); return { content: [{ type: 'text', text: `๐Ÿ”’ **Debug Session Closed** **Session ID:** ${sessionId} **Duration:** ${duration}s **Events Captured:** ${eventCount} **URL:** ${session.url} Browser resources cleaned up successfully. โœ… *Session managed locally for complete privacy*` }] }; } private async getSubscriptionInfo() { const keyStatus = this.apiKeyManager.getKeyStatus(); const usage = this.apiKeyManager.getUsageStats(); return { content: [{ type: 'text', text: `๐Ÿ’ณ **AI Debug Subscription Status** ## ๐Ÿ”‘ API Key Status **Status:** ${keyStatus.valid ? 'โœ… Valid' : 'โŒ Invalid/Missing'} **Tier:** ${keyStatus.tier || 'Free'} ${keyStatus.valid ? `**Expires:** ${keyStatus.expiresAt || 'Never'}` : ''} ## ๐Ÿ“Š Usage Statistics **This Month:** - **AI Analysis:** ${usage.aiAnalysis}/${usage.limits.aiAnalysis === -1 ? 'โˆž' : usage.limits.aiAnalysis} - **AI Reports:** ${usage.aiReports}/${usage.limits.aiReports === -1 ? 'โˆž' : usage.limits.aiReports} - **Premium Features:** ${usage.premiumFeatures}/${usage.limits.premiumFeatures === -1 ? 'โˆž' : usage.limits.premiumFeatures} ## ๐Ÿš€ Available Features **FREE Tier:** - โœ… Local debugging and monitoring - โœ… User action simulation - โœ… Screenshots and basic reports - โœ… Framework detection ${keyStatus.valid ? ` **${keyStatus.tier?.toUpperCase()} Tier:** - โœ… Revolutionary AI analysis - โœ… AI-enhanced reports - โœ… Advanced insights and recommendations - โœ… Performance optimization suggestions - โœ… Priority support ` : ` **PREMIUM Features (Requires API Key):** - ๐Ÿ”’ Revolutionary AI analysis - ๐Ÿ”’ AI-enhanced reports - ๐Ÿ”’ Advanced insights and recommendations - ๐Ÿ”’ Performance optimization suggestions **๐Ÿ”— Upgrade:** https://ai-debug.com/pricing `} ## ๐Ÿ”— Quick Links - **Dashboard:** https://ai-debug.com/dashboard - **Documentation:** https://docs.ai-debug.com - **Support:** https://ai-debug.com/support *Revolutionary debugging technology for modern developers*` }] }; } // Helper methods private createPremiumFeatureResponse(featureName: string) { return { content: [{ type: 'text', text: `๐Ÿ”’ **Premium Feature: ${featureName}** This feature requires an AI Debug API key. **๐Ÿš€ Why Upgrade?** - ๐Ÿง  Revolutionary AI analysis powered by advanced algorithms - ๐Ÿ’ก Intelligent insights and recommendations - โšก Performance optimization suggestions - ๐Ÿ”ง Framework-specific debugging intelligence - ๐Ÿ“Š Advanced reporting and analytics **๐Ÿ’ณ Pricing:** - **Pro:** $29/month - 100 AI analyses - **Enterprise:** $299/month - Unlimited + priority support **๐Ÿ”— Get API Key:** https://ai-debug.com/pricing **โš™๏ธ Setup:** 1. Purchase API key at https://ai-debug.com/dashboard 2. Set environment variable: \`export AI_DEBUG_API_KEY=your_key\` 3. Restart your MCP server 4. Enjoy revolutionary AI debugging! *Local debugging remains completely free forever.*` }] }; } private async runAudit(args: any) { const { sessionId, categories = ['all'] } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } // Run the audit const auditResults = await this.auditEngine.performAudit(session.page, categories); // Calculate overall score const scores = Object.values(auditResults).map(r => r.score); const overallScore = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length); // Count issues by severity const issueCounts = { error: 0, warning: 0, info: 0 }; Object.values(auditResults).forEach(result => { result.issues.forEach(issue => { issueCounts[issue.severity]++; }); }); // Format the results let reportText = `๐Ÿ” **Comprehensive Audit Report** **Overall Score:** ${overallScore}/100 ${getScoreEmoji(overallScore)} **URL:** ${session.url} **๐Ÿ“Š Summary:** - ๐Ÿ”ด Errors: ${issueCounts.error} - ๐ŸŸก Warnings: ${issueCounts.warning} - โ„น๏ธ Info: ${issueCounts.info} `; // Add results for each category for (const [category, result] of Object.entries(auditResults)) { reportText += `\n## ${getCategoryIcon(category)} ${formatCategoryName(category)} - ${result.score}/100\n\n`; if (result.issues.length > 0) { reportText += '**Issues:**\n'; result.issues.forEach(issue => { const icon = issue.severity === 'error' ? 'โŒ' : issue.severity === 'warning' ? 'โš ๏ธ' : 'โ„น๏ธ'; reportText += `${icon} ${issue.message}\n`; }); reportText += '\n'; } if (result.suggestions.length > 0) { reportText += '**Recommendations:**\n'; result.suggestions.forEach(suggestion => { reportText += `๐Ÿ’ก ${suggestion}\n`; }); } } // Add AI insights if premium if (this.apiKeyManager.hasValidKey()) { reportText += `\n## ๐Ÿง  AI Insights (Premium) โœจ Based on the audit results, consider focusing on ${getTopPriority(auditResults)} ๐Ÿ“ˆ Fixing all errors could improve your score by up to ${calculatePotentialImprovement(issueCounts)}% ๐ŸŽฏ Quick wins: Start with accessibility and performance optimizations`; } else { reportText += `\n๐Ÿ’ก **Upgrade to Premium** for AI-powered insights and recommendations tailored to your specific issues.`; } return { content: [{ type: 'text', text: reportText }] }; function getScoreEmoji(score: number): string { if (score >= 90) return '๐ŸŸข'; if (score >= 70) return '๐ŸŸก'; if (score >= 50) return '๐ŸŸ '; return '๐Ÿ”ด'; } function getCategoryIcon(category: string): string { const icons: Record<string, string> = { accessibility: 'โ™ฟ', performance: 'โšก', seo: '๐Ÿ”', security: '๐Ÿ”’', bestPractices: 'โœ…' }; return icons[category] || '๐Ÿ“‹'; } function formatCategoryName(category: string): string { const names: Record<string, string> = { accessibility: 'Accessibility', performance: 'Performance', seo: 'SEO', security: 'Security', bestPractices: 'Best Practices' }; return names[category] || category; } function getTopPriority(results: Record<string, any>): string { let lowestScore = 100; let priority = ''; for (const [category, result] of Object.entries(results)) { if (result.score < lowestScore) { lowestScore = result.score; priority = formatCategoryName(category); } } return priority || 'general improvements'; } function calculatePotentialImprovement(counts: Record<string, number>): number { return Math.min(counts.error * 10 + counts.warning * 5, 50); } } private async mockNetwork(args: any) { const { sessionId, action, urlPattern, response } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } switch (action) { case 'add': if (!urlPattern) { throw new Error('URL pattern required for add action'); } await this.localEngine.addNetworkMock(urlPattern, response || {}); return { content: [{ type: 'text', text: `๐ŸŽญ **Network Mock Added** **Pattern:** \`${urlPattern}\` **Status:** ${response?.status || 200} **Delay:** ${response?.delay ? `${response.delay}ms` : 'None'} The following URLs will be intercepted: ${this.getMatchingExamples(urlPattern)} **Active Mocks:** ${this.localEngine.getMockedUrls().length} ๐Ÿ’ก **Usage Tips:** - Test error scenarios with status codes like 404, 500 - Simulate slow networks with delay - Mock specific JSON responses for edge cases` }] }; case 'remove': if (!urlPattern) { throw new Error('URL pattern required for remove action'); } const removed = this.localEngine.removeNetworkMock(urlPattern); return { content: [{ type: 'text', text: removed ? `โœ… Removed mock for pattern: \`${urlPattern}\`` : `โŒ No mock found for pattern: \`${urlPattern}\`` }] }; case 'clear': this.localEngine.clearAllMocks(); return { content: [{ type: 'text', text: '๐Ÿงน All network mocks cleared' }] }; case 'list': const mocks = this.localEngine.getMockedUrls(); return { content: [{ type: 'text', text: mocks.length > 0 ? `๐Ÿ“‹ **Active Network Mocks:**\n${mocks.map(m => `- \`${m}\``).join('\n')}` : '๐Ÿ“‹ No active network mocks' }] }; default: throw new Error(`Unknown mock action: ${action}`); } } private getMatchingExamples(pattern: string): string { const examples = []; if (pattern.includes('*')) { if (pattern === '*') { examples.push('- All requests'); } else if (pattern.startsWith('*/')) { examples.push(`- Any domain with path ${pattern.substring(1)}`); } else if (pattern.endsWith('/*')) { examples.push(`- All paths under ${pattern.substring(0, pattern.length - 2)}`); } else { examples.push(`- URLs matching pattern ${pattern}`); } } else { examples.push(`- Exact URL: ${pattern}`); } return examples.join('\n'); } private async getFlutterWidgetTree(args: any) { const { sessionId } = args; const session = this.sessions.get(sessionId); if (!session) { throw new Error(`Debug session ${sessionId} not found`); } if (session.framework !== 'flutter-web') { throw new Error('This tool only works with Flutter Web applications'); } try { const widgetTree = await this.localEngine.getFlutterWidgetTree(); if (!widgetTree) {