wrmmax-criativo-mcp
Officialwrmax-criativo
Pipeline de generación y edición de imágenes de WRMax. Claude Code es el cerebro; este repo es la mano.
El código no sabe nada de marketing: recibe parámetros y devuelve un archivo. Quien decide formato, ángulo y prompt es Claude, que después mira la pieza generada y decide si la acepta o la rehace. Es ese bucle cerrado lo que caracteriza la orquestación.
El código, los comentarios y los mensajes están en inglés. La documentación y la conversación con el equipo siguen en portugués.
Configuración (5 minutos)
npm install
export OPENAI_API_KEY="sua-chave" # https://platform.openai.com/api-keysImportante: la suscripción a ChatGPT Pro o a la app Gemini no da acceso a la API. Son cobros separados. Se necesita una clave de API con facturación activa.
Motor B (aún no implementado):
export IMAGE_PROVIDER=gemini
export GEMINI_API_KEY="sua-chave"Related MCP server: MCP OpenAI Image Generation Server
Estructura
Cada carpeta tiene una responsabilidad, y ningún archivo acumula dos.
bin/ entradas executáveis
cli.js CLI
mcp-server.js servidor MCP (só escolhe o transporte)
src/
bootstrap/ carga do .env e resolução de caminhos
config/ ÚNICO ponto que lê process.env; tabelas de modelo,
formato e qualidade
brands/ brand kit, compliance e montagem do prompt
media/ entrada, redução e saída de imagem (Drive, download,
arquivo local, preview, upload)
providers/ motores de imagem, por registro
core/ regra de negócio: artwork-service, artifact-store,
delivery
mcp/ servidor MCP, tools e transportes
http/ app Express, middleware, rotas e views
auth/ OAuth com Google
cli/ args, ajuda e orquestração do CLI
test/ node --test, sem chave e sem custo
scripts/ smoke — gasta crédito ou precisa de rede viva
brand/ um JSON por cliente
out/ saída local (só com PERSIST_OUTPUT=true)El diseño central: src/core/artwork-service.js no sabe qué es MCP ni qué es
CLI. Recibe una petición simple y devuelve un resultado simple. Quien
formatea el content block es src/mcp/tool-result.js; quien escribe JSON en stdout es
src/cli/run.js. Por eso los dos frontends comparten un único camino.
Toda dependencia (config, artifact store, directorio de marca) se inyecta, no se importa como singleton — es lo que permite probar la ruta, la tool y el servicio sin tocar el entorno.
Uso
Generar desde cero:
node bin/cli.js --brand forno-paulista --format feed \
--prompt "Studio product shot of a rustic pizza on a wooden board, steam rising"Editar foto real del cliente (cambio de fondo preservando el producto):
node bin/cli.js --brand forno-paulista --format square \
--ref fotos/produto.jpg \
--prompt "Change only the background to a clean warm studio gradient. Keep the product, its label and the lighting on it exactly unchanged."Borrador barato antes de gastar en el final:
node bin/cli.js --quality draft --prompt "..."Siempre borrador antes del final. Cuesta una fracción y evita rehacer caro.
Servidor MCP
npm run mcp # stdio — é o que o Claude Code fala
npm run mcp:http # Streamable HTTP em :8787/mcp — é o que conector remoto exigeHerramientas expuestas: list_brands, generate_image, edit_image.
No existe herramienta que liste, busque o navegue imágenes en el servidor, y esto es intencional: quien elige el archivo es el usuario. Una herramienta de búsqueda convertiría un prompt inyectado en una foto de cliente en un escaneo del entorno.
Los detalles de transporte, autenticación y destino de la resolución completa están en
CLAUDE.md.
Cómo usa Claude Code el CLI
El comando imprime JSON en stdout y log en stderr. Esto es intencional: Claude ejecuta, lee el JSON, abre el PNG, evalúa y encadena la siguiente llamada. Sin humano en medio de cada iteración.
{"ok":true,"file":"out/1755777.png","seconds":6.2,"aspectRatio":"4:5"}Códigos de salida: 0 éxito · 1 fallo técnico · 2 bloqueado por
compliance — el 2 existe para que un hook distinga los dos casos.
Compliance
brand/*.json tiene un array forbidden_terms. El assertPromptAllowed() se ejecuta
antes de la llamada y bloquea — ahorra crédito y, más importante, no
depende de que el modelo obedezca la instrucción.
{
"name": "Forno Paulista",
"visual": {
"style": "appetizing food photography, rustic warmth, artisanal",
"colors": ["wood brown", "tomato red", "warm cream"],
"lighting": "warm golden light, natural window light",
"avoid": ["cold blue tones", "plastic-looking food"]
},
"forbidden_terms": [],
"compliance_reason": ""
}Marca | Bloqueo |
| paciente, antes/después, cuerpo, resultado de procedimiento — CFM 2.336/2023 |
Prueba rápida del guardarraíl, sin clave y sin coste:
node bin/cli.js --brand cliente-medico --prompt "before and after of a patient"
# x BLOCKED by compliance rules for "Cliente médico (template CFM)"Pruebas
npm test # 110 testes, sem chave de API, sem rede externa, sem custoCubre: compliance, brand kit, config, artifact store, conversión de enlace de Drive, todos los modos de fallo de descarga, reducción, subida, tablas de tamaño, el flujo OAuth completo (con un Google falso), el descubrimiento que hace claude.ai, y los dos transportes MCP de extremo a extremo.
Las pruebas que gastan crédito o dependen de red viva quedan fuera de la suite,
en scripts/:
npm run probe # ~US$ 0,005 — separa "chave ruim" de "pipeline ruim"
npm run smoke:drive # ~US$ 0,01 — link do Drive de ponta a ponta
npm run smoke:edit # ~US$ 0,02 — o modelo edita ou só regenera?
npm run smoke:stateless # ~US$ 0,01 — não deixa um byte para trásVariables de entorno
Variable | Por defecto | Para qué |
| — | Obligatoria con el provider |
|
| Cambia el motor de imagen |
|
|
|
|
| Puerto del modo HTTP |
|
| Ruta del endpoint MCP |
| — | Bearer fijo (script y prueba; claude.ai no lo acepta) |
| — | Obligatoria con OAuth: es el issuer, y debe ser fija |
| — | Activan el OAuth |
| — | Quién puede autorizar. Una cuenta de Google válida no es permiso |
|
| Guarda la resolución completa en |
|
| Validez del enlace de descarga |
|
| Tope de memoria del depósito de piezas |
Alojamiento (EasyPanel, o cualquier host de contenedor)
El servidor guarda estado en memoria a propósito: clientes OAuth, tokens y el
depósito de piezas son Map(). Esto exige un proceso vivo y único, y es lo que
descarta la plataforma serverless: allí el POST /register caería en una instancia
y el GET /authorize en otra, que no conoce al cliente. El inicio de sesión fallaría
de forma intermitente, con un síntoma que no parece la causa.
Por eso el despliegue es contenedor, y la regla vale para cualquier host: una réplica solo. Para escalar más allá, cambia los tres almacenamientos en memoria por Redis primero.
El Dockerfile en la raíz sirve para cualquier plataforma de contenedor. Los pasos
siguientes son de EasyPanel; en otro host cambia la interfaz, no el contenido.
El dominio viene antes
Google no acepta dirección IP como redirect de OAuth, y exige HTTPS. Es decir, un dominio es un requisito previo, no un acabado.
Apunta un registro A del subdominio a la IP del servidor. Quien no tenga
dominio puede usar DNS comodín — mcp.<ip-con-guiones>.sslip.io resuelve solo
a la IP incrustada en el nombre, y Let's Encrypt emite normalmente siempre que el
puerto 80 esté abierto.
Servicio
Crear servicio → App, con source en este repositorio y rama
main.Build: Dockerfile, en la raíz.
Environment:
Variable
Valor
PORT8787MCP_BASE_URLhttps://<tu-dominio>— sin barra al finalOPENAI_API_KEYla clave de OpenAI
GOOGLE_CLIENT_IDdel cliente OAuth (Aplicación Web)
GOOGLE_CLIENT_SECRETdel mismo cliente
MCP_EMAILSquién puede autorizar, separado por comas
MCP_TRANSPORT=httpya viene delDockerfile— no lo definas.Domains: el subdominio apuntando al puerto
8787, con HTTPS activado.Deploy.
Google Cloud Console → Credenciales → tu cliente OAuth, añade el redirect autorizado, exactamente:
https://<seu-dominio>/oauth/google/callbackclaude.ai → conectores:
https://<tu-dominio>/mcp.
El MCP_BASE_URL se convierte en el issuer del OAuth y se compara carácter por carácter
con lo que el cliente descubre. Un dominio diferente del configurado, o una barra
sobrante, hace que el vínculo falle sin mensaje útil.
Comprobación
curl https://<seu-dominio>/healthEl campo que importa es "auth":"oauth". Si viene "none", alguna variable de
Google no llegó — y entonces el servidor se levantó abierto, aceptando cualquier
llamada y gastando la clave de quien lo aloja.
Notas de API que ahorran depuración
La
Kdeimage_sizees mayúscula.2kse rechaza.gpt-image-2acepta cualquier WxH divisible por 16; los más pequeños solo aceptan tres tamaños fijos. Story/reels final necesitagpt-image-2.En la edición, la imagen viene antes del texto en el array de input.
No existe refacción encadenada en el provider
openai:previous_interaction_ides de la Interactions API de Gemini. Para ajustar, reenvía la imagen como referencia.Entrada por URL envía
User-Agentpropio: varios orígenes (Wikimedia entre ellos) devuelven 400/403 para una solicitud sin UA identificable.Pieza con texto: define la copy primero, luego pide la imagen con esa copy.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides tools for generating and editing images using OpenAI's gpt-image-1 model via an MCP interface, enabling AI assistants to create and modify images based on text prompts.15Apache 2.0
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to generate and edit images through OpenAI's DALL-E models via MCP tools. Supports text-to-image generation and image-to-image editing with configurable parameters for size, quality, and style.
- AlicenseNot gradedqualityNot gradedmaintenanceEnables image generation, editing, and blending using Gemini 2.5 Flash capabilities, plus text generation for AI-powered creative workflows through MCP tools.
- AlicenseNot gradedqualityDmaintenanceEnables AI-powered image generation and editing using Gemini and Imagen models, supporting text-to-image, image editing, and multi-image composition through MCP tools.MIT
Related MCP Connectors
Generate on-brand images from your AI agent: design, edit, and render templates over MCP.
Generate images with any major model — one API key, one prepaid balance, one MCP.
Generate and manage AI UGC video ads through eleven typed MCP tools
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/WrMaxMarketing/wrmmax-criativo-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server