mcp-image-server
Version:
Servidor MCP para geração de imagens e ícones, integrado ao Vibecoding.
96 lines (95 loc) • 3.87 kB
JavaScript
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}`);
});