UNPKG

openrouter-image-mcp

Version:

MCP server for image analysis using OpenRouter's vision models

97 lines (96 loc) 6.75 kB
import { ImageProcessor } from '../utils/image-processor.js'; export async function handleAnalyzeMobileApp(args, config, openRouterClient, logger) { const imageProcessor = ImageProcessor.getInstance(); try { const imageInput = { type: args.type, data: args.data, mimeType: args.mimeType, }; const platform = args.platform || 'auto-detect'; const focusArea = args.focusArea; const includeUXHeuristics = args.includeUXHeuristics !== false; const format = args.format || 'json'; const maxTokens = args.maxTokens || 4000; logger.info(`Starting mobile app screenshot analysis for type: ${imageInput.type}, platform: ${platform}, focus: ${focusArea}`); // Process the image const processedImage = await imageProcessor.processImage(imageInput); // Validate image type if (!imageProcessor.isValidImageType(processedImage.mimeType)) { throw new Error(`Unsupported image type: ${processedImage.mimeType}`); } // Check file size const serverConfig = config.getServerConfig(); const maxImageSize = serverConfig.maxImageSize || 10485760; if (processedImage.size > maxImageSize) { throw new Error(`Image size ${processedImage.size} exceeds maximum allowed size ${maxImageSize}`); } // Build specialized prompt for mobile app analysis let prompt = 'Analyze this mobile app screenshot and provide comprehensive insights about its design, user experience, and platform adherence.'; if (platform !== 'auto-detect') { prompt += ` This appears to be an ${platform.toUpperCase()} app, so please evaluate it against ${platform.toUpperCase()} design guidelines and conventions.`; } else { prompt += ' Please identify the platform (iOS or Android) and evaluate it accordingly.'; } if (focusArea) { switch (focusArea) { case 'ui-design': prompt += ' Focus specifically on UI design elements, visual hierarchy, color usage, typography, spacing, and component design.'; break; case 'user-experience': prompt += ' Focus specifically on user experience, flow efficiency, usability, and user journey optimization.'; break; case 'navigation': prompt += ' Focus specifically on navigation patterns, menu structures, tab bars, and user movement through the app.'; break; case 'accessibility': prompt += ' Focus specifically on accessibility features, contrast ratios, touch targets, screen reader compatibility, and inclusive design.'; break; case 'performance': prompt += ' Focus specifically on performance indicators, loading states, progress feedback, and perceived responsiveness.'; break; case 'onboarding': prompt += ' Focus specifically on onboarding elements, tutorials, first-time user experience, and feature discovery.'; break; } } prompt += ' Include specific details about:'; if (includeUXHeuristics) { prompt += ' Nielsen\'s 10 usability heuristics evaluation; visibility of system status; match between system and real world; user control and freedom; consistency and standards; error prevention; recognition rather than recall; flexibility and efficiency of use; aesthetic and minimalist design; help users diagnose and recover from errors; help and documentation;'; } prompt += ' platform-specific UI components and patterns; compliance with platform design guidelines (Human Interface Guidelines for iOS, Material Design for Android); gesture support and interaction patterns; information architecture and content organization; state management and feedback mechanisms; responsive design and device compatibility; visual design polish and attention to detail; potential usability issues and improvement recommendations; accessibility compliance and inclusive design practices; technical implementation observations and potential optimizations.'; if (format === 'json') { prompt += ' Provide your analysis in a structured JSON format with the following schema: {"app_name": "string (if visible)", "platform": "ios/android/auto-detected", "screen_type": "description", "ui_design": {"visual_hierarchy": "evaluation", "color_scheme": "description", "typography": "evaluation", "spacing_and_layout": "evaluation", "components": "description"}, "navigation": {"pattern": "description", "ease_of_use": "evaluation", "platform_compliance": "evaluation"}, "content": {"organization": "evaluation", "clarity": "evaluation", "density": "evaluation"}, "interactions": {"gestures": "description", "feedback": "evaluation", "responsiveness": "evaluation"}, "platform_guidelines": {"compliance_score": "1-10", "violations": ["list"], "best_practices": ["list"]}, "accessibility": {"score": "1-10", "issues": ["list"], "positive_aspects": ["list"]}, "ux_heuristics": {"visibility_of_status": "evaluation", "match_real_world": "evaluation", "user_control": "evaluation", "consistency": "evaluation", "error_prevention": "evaluation", "recognition_recall": "evaluation", "flexibility_efficiency": "evaluation", "aesthetic_design": "evaluation", "error_recovery": "evaluation", "help_documentation": "evaluation"}, "usability": {"strengths": ["list"], "issues": ["list"], "recommendations": ["list"]}, "technical_notes": "technical observations"}'; } // Analyze the mobile app screenshot const result = await openRouterClient.analyzeImage(processedImage.data, processedImage.mimeType, prompt, { format, maxTokens }); if (!result.success) { throw new Error(result.error || 'Failed to analyze mobile app screenshot'); } logger.info(`Mobile app screenshot analysis completed successfully`, { model: result.model, usage: result.usage, }); return { content: [ { type: 'text', text: result.analysis || 'No analysis available', }, ], }; } catch (error) { logger.error('Mobile app screenshot analysis failed', error); return { content: [ { type: 'text', text: `Error: ${error.message}`, }, ], isError: true, }; } }