christmas-mcp-image-describe
Version:
MCP server that analyzes images and provides structured metadata for website placement decisions using OpenAI GPT-4o Vision API
170 lines (152 loc) • 5.11 kB
JavaScript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { analyzeImage, analyzeImages } from './src/imageAnalyzer.js';
class ImageAnalysisMCPServer {
constructor() {
this.server = new Server(
{
name: 'christmas-mcp-image-describe',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
this.setupErrorHandling();
}
setupErrorHandling() {
this.server.onerror = (error) => console.error('[MCP Error]', error);
process.on('SIGINT', async () => {
await this.server.close();
process.exit(0);
});
}
setupToolHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'analyze_image',
description: 'Analyze an image and provide structured metadata for website placement decisions',
inputSchema: {
type: 'object',
properties: {
imagePath: {
type: 'string',
description: 'Path to the local image file'
},
context: {
type: 'string',
description: 'Optional context like "about section" or "homepage hero"'
},
apiKey: {
type: 'string',
description: 'OpenAI API key'
},
project: {
type: 'string',
description: 'OpenAI project ID (optional)'
}
},
required: ['imagePath', 'apiKey']
}
},
{
name: 'analyze_images_batch',
description: 'Analyze multiple images in batch and provide structured metadata',
inputSchema: {
type: 'object',
properties: {
images: {
type: 'array',
items: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'Path to the image file'
},
context: {
type: 'string',
description: 'Optional context for this image'
}
},
required: ['path']
},
description: 'Array of image objects to analyze'
},
apiKey: {
type: 'string',
description: 'OpenAI API key'
},
project: {
type: 'string',
description: 'OpenAI project ID (optional)'
}
},
required: ['images', 'apiKey']
}
}
]
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
if (name === 'analyze_image') {
const { imagePath, context = '', apiKey, project } = args;
if (!imagePath || !apiKey) {
throw new Error('imagePath and apiKey are required');
}
const result = await analyzeImage(imagePath, context, apiKey, project);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
}
if (name === 'analyze_images_batch') {
const { images, apiKey, project } = args;
if (!images || !Array.isArray(images) || !apiKey) {
throw new Error('images array and apiKey are required');
}
const results = await analyzeImages(images, apiKey, project);
return {
content: [
{
type: 'text',
text: JSON.stringify(results, null, 2)
}
]
};
}
throw new Error(`Unknown tool: ${name}`);
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error: ${error.message}`
}
],
isError: true
};
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('Christmas MCP Image Describe server running on stdio');
}
}
const server = new ImageAnalysisMCPServer();
server.run().catch(console.error);