UNPKG

christmas-mcp-image-describe

Version:

MCP server that analyzes images and provides structured metadata for website placement decisions using OpenAI GPT-4o Vision API

263 lines (225 loc) 9.22 kB
#!/usr/bin/env node import { analyzeImage } from '../src/imageAnalyzer.js'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import process from 'process'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); async function startMCPServer() { console.error('[MCP Server] Starting Christmas MCP Image Describe server...'); // Import and start MCP server const { Server } = await import('@modelcontextprotocol/sdk/server/index.js'); const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js'); const { CallToolRequestSchema, ListToolsRequestSchema } = await import('@modelcontextprotocol/sdk/types.js'); const { analyzeImage, analyzeImages } = await import('../src/imageAnalyzer.js'); class ImageAnalysisMCPServer { constructor() { this.server = new Server( { name: 'christmas-mcp-image-describe', version: '1.0.4', }, { capabilities: { tools: {}, }, } ); this.setupHandlers(); console.error('[MCP Server] Server initialized successfully'); } setupHandlers() { // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { console.error('[MCP Server] Listing tools'); return { tools: [ { name: 'analyze_image', description: 'Analyze a single image and return structured metadata for website placement decisions', inputSchema: { type: 'object', properties: { imagePath: { type: 'string', description: 'Path to the image file to analyze' }, context: { type: 'string', description: 'Optional context about where the image will be used (e.g., "homepage hero", "about section")' }, apiKey: { type: 'string', description: 'OpenAI API key (optional if OPENAI_API_KEY environment variable is set)' }, projectId: { type: 'string', description: 'OpenAI project ID (optional)' } }, required: ['imagePath'] } }, { name: 'analyze_images_batch', description: 'Analyze multiple images in batch and return structured metadata for each', inputSchema: { type: 'object', properties: { imagePaths: { type: 'array', items: { type: 'string' }, description: 'Array of paths to image files to analyze' }, context: { type: 'string', description: 'Optional context about where the images will be used' }, apiKey: { type: 'string', description: 'OpenAI API key (optional if OPENAI_API_KEY environment variable is set)' }, projectId: { type: 'string', description: 'OpenAI project ID (optional)' } }, required: ['imagePaths'] } } ] }; }); // Handle tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { console.error(`[MCP Server] Tool called: ${request.params.name}`); try { if (request.params.name === 'analyze_image') { const { imagePath, context, apiKey, projectId } = request.params.arguments; // Use environment variables if not provided in arguments const finalApiKey = apiKey || process.env.OPENAI_API_KEY; const finalProjectId = projectId || process.env.OPENAI_PROJECT; if (!imagePath || !finalApiKey) { throw new Error('Missing required parameters: imagePath and apiKey are required'); } console.error(`[MCP Server] Analyzing image: ${imagePath}`); const result = await analyzeImage(imagePath, context, finalApiKey, finalProjectId); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } if (request.params.name === 'analyze_images_batch') { const { imagePaths, context, apiKey, projectId } = request.params.arguments; // Use environment variables if not provided in arguments const finalApiKey = apiKey || process.env.OPENAI_API_KEY; const finalProjectId = projectId || process.env.OPENAI_PROJECT; if (!imagePaths || !Array.isArray(imagePaths) || !finalApiKey) { throw new Error('Missing required parameters: imagePaths (array) and apiKey are required'); } console.error(`[MCP Server] Analyzing ${imagePaths.length} images in batch`); const results = await analyzeImages(imagePaths, context, finalApiKey, finalProjectId); return { content: [ { type: 'text', text: JSON.stringify(results, null, 2) } ] }; } throw new Error(`Unknown tool: ${request.params.name}`); } catch (error) { console.error(`[MCP Server] Tool execution error:`, error); return { content: [ { type: 'text', text: `Error: ${error.message}` } ], isError: true }; } }); console.error('[MCP Server] Handlers set up successfully'); } async run() { try { console.error('[MCP Server] Starting server transport...'); const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('[MCP Server] Server connected and running'); } catch (error) { console.error('[MCP Server] Failed to start server:', error); process.exit(1); } } } const server = new ImageAnalysisMCPServer(); server.run().catch((error) => { console.error('[MCP Server] Server failed to start:', error); process.exit(1); }); } async function main() { const args = process.argv.slice(2); // Check for MCP server mode if (args.includes('--mcp-server')) { return startMCPServer(); } if (args.length === 0) { console.log(` Christmas MCP Image Describe - CLI Example Usage: node cli.js <image-path> [context] [api-key] [project-id] christmas-mcp-image-describe --mcp-server # Start MCP server for VS Code Arguments: image-path Path to the image file to analyze context Optional context (e.g., "homepage hero", "about section") api-key OpenAI API key (or set OPENAI_API_KEY environment variable) project-id OpenAI project ID (or set OPENAI_PROJECT environment variable) Examples: node cli.js ./sample.jpg node cli.js ./hero.png "homepage hero" node cli.js ./team.jpg "about section" sk-your-api-key christmas-mcp-image-describe --mcp-server # For VS Code MCP integration Environment Variables: OPENAI_API_KEY Your OpenAI API key OPENAI_PROJECT Your OpenAI project ID (optional) `); process.exit(1); } const imagePath = args[0]; const context = args[1] || ''; const apiKey = args[2] || process.env.OPENAI_API_KEY; const project = args[3] || process.env.OPENAI_PROJECT; if (!apiKey) { console.error('Error: OpenAI API key is required. Set OPENAI_API_KEY environment variable or provide as argument.'); process.exit(1); } try { console.log('Analyzing image...'); console.log(`Image: ${imagePath}`); if (context) console.log(`Context: ${context}`); console.log(''); const result = await analyzeImage(imagePath, context, apiKey, project); console.log('Analysis Result:'); console.log('================'); console.log(JSON.stringify(result, null, 2)); console.log('\\nFormatted Output:'); console.log('================='); console.log(`Description: ${result.description}`); console.log(`Suggested Placement: ${result.placement}`); console.log(`Tags: ${result.tags.join(', ')}`); console.log(`Alt Text: ${result.alt}`); } catch (error) { console.error('Error analyzing image:', error.message); process.exit(1); } } main();