UNPKG

mcp-image-server

Version:

Servidor MCP para geração de imagens e ícones, integrado ao Vibecoding.

96 lines (95 loc) 3.87 kB
import 'dotenv/config'; import express from 'express'; import bodyParser from 'body-parser'; import { ImageGenerationService } from './services/image-generation-service.js'; import { IconGenerationService } from './services/icon-generation-service.js'; import config from '../config/default.json' with { type: 'json' }; import path from 'path'; import fs from 'fs/promises'; const app = express(); const port = config.server.port || 3000; // Middleware app.use(bodyParser.json()); // Endpoint para facilitar integração MCP: .well-known/ai-plugin.json app.get('/.well-known/ai-plugin.json', async (req, res) => { const filePath = path.join(process.cwd(), '.well-known', 'ai-plugin.json'); try { const data = await fs.readFile(filePath, 'utf-8'); res.setHeader('Content-Type', 'application/json'); res.send(data); } catch (err) { res.status(404).json({ error: 'ai-plugin.json não encontrado' }); } }); // Endpoint para facilitar integração OpenAPI app.get('/openapi.json', async (req, res) => { const filePath = path.join(process.cwd(), 'public', 'openapi.json'); try { const data = await fs.readFile(filePath, 'utf-8'); res.setHeader('Content-Type', 'application/json'); res.send(data); } catch (err) { res.status(404).json({ error: 'openapi.json não encontrado' }); } }); // Services const imageGenerationService = new ImageGenerationService(); const iconGenerationService = new IconGenerationService(); // Routes // Validação básica de entrada para segurança MCP app.post('/generate-image', (req, res) => { (async () => { const { prompt, width, height, format } = req.body || {}; if (!prompt || typeof prompt !== 'string' || prompt.length < 3) { return res.status(400).json({ error: 'Prompt inválido.' }); } if (width && (typeof width !== 'number' || width <= 0)) { return res.status(400).json({ error: 'Width inválido.' }); } if (height && (typeof height !== 'number' || height <= 0)) { return res.status(400).json({ error: 'Height inválido.' }); } if (format && !['png', 'jpeg', 'webp'].includes(format)) { return res.status(400).json({ error: 'Formato inválido.' }); } try { const result = await imageGenerationService.generateImage(req.body); res.status(200).json(result); } catch (error) { res.status(500).json({ error: error instanceof Error ? error.message : String(error) }); } })(); }); // Validação básica de entrada para segurança MCP app.post('/generate-icon', (req, res) => { (async () => { const { prompt, sizes, format } = req.body || {}; if (!prompt || typeof prompt !== 'string' || prompt.length < 3) { return res.status(400).json({ error: 'Prompt inválido.' }); } if (sizes && (!Array.isArray(sizes) || sizes.some((s) => typeof s !== 'number' || s <= 0))) { return res.status(400).json({ error: 'Sizes inválido.' }); } if (format && !['ico', 'png', 'svg'].includes(format)) { return res.status(400).json({ error: 'Formato inválido.' }); } try { const results = await iconGenerationService.generateIcon(req.body); res.status(200).json({ icons: results }); } catch (error) { res.status(500).json({ error: error instanceof Error ? error.message : String(error) }); } })(); }); // Healthcheck e handshake para MCP/Copilot app.get('/', (req, res) => { res.status(200).json({ status: 'ok', name: 'mcp-image-server', version: '1.0.0' }); }); // Start server app.listen(port, () => { console.log(`MCP Image Server is running on http://localhost:${port}`); });