wrmmax-criativo-mcp
Officialwrmax-criativo
Pipeline de geração e edição de imagem da WRMax. Claude Code é o cérebro; este repo é a mão.
O código não sabe nada sobre marketing — ele recebe parâmetros e devolve arquivo. Quem decide formato, ângulo e prompt é o Claude, que depois olha a peça gerada e decide se aceita ou refaz. É esse loop fechado que caracteriza a orquestração.
O código, os comentários e as mensagens estão em inglês. A documentação e a conversa com o time seguem em português.
Setup (5 minutos)
npm install
export OPENAI_API_KEY="sua-chave" # https://platform.openai.com/api-keysImportante: assinatura do ChatGPT Pro ou do app Gemini não dá acesso à API. São cobranças separadas. Precisa de chave de API com billing ativo.
Motor B, via IMAGE_PROVIDER=gemini (padrão é openai):
export IMAGE_PROVIDER=gemini
export GEMINI_API_KEY="sua-chave" # https://aistudio.google.com/apikeyRelated MCP server: MCP OpenAI Image Generation Server
Estrutura
Cada pasta tem uma responsabilidade, e nenhum arquivo acumula duas.
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)O desenho central: src/core/artwork-service.js não sabe o que é MCP nem o
que é CLI. Ele recebe um pedido simples e devolve um resultado simples. Quem
formata content block é src/mcp/tool-result.js; quem escreve JSON no stdout é
src/cli/run.js. Por isso os dois frontends compartilham um caminho só.
Toda dependência (config, artifact store, diretório de brand) é injetada, não importada como singleton — é o que permite testar a rota, a tool e o serviço sem tocar no ambiente.
Uso
Gerar do zero:
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 do cliente (troca de fundo preservando o produto):
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."Rascunho barato antes de gastar no final:
node bin/cli.js --quality draft --prompt "..."Sempre rascunho antes do final. Custa uma fração e evita refazer 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 exigeFerramentas expostas: list_brands, generate_image, edit_image.
Não existe ferramenta que liste, busque ou navegue imagens no servidor, e isso é proposital: quem escolhe o arquivo é o usuário. Uma ferramenta de busca transformaria um prompt injetado numa foto de cliente em varredura do ambiente.
Detalhes de transporte, autenticação e destino da resolução cheia estão em
CLAUDE.md.
Como o Claude Code usa o CLI
O comando imprime JSON no stdout e log no stderr. Isso é proposital: o Claude roda, lê o JSON, abre o PNG, avalia e encadeia a próxima chamada. Sem humano no meio de cada iteração.
{"ok":true,"file":"out/1755777.png","seconds":6.2,"aspectRatio":"4:5"}Códigos de saída: 0 sucesso · 1 falha técnica · 2 bloqueado por
compliance — o 2 existe para um hook distinguir os dois casos.
Compliance
brand/*.json tem um array forbidden_terms. O assertPromptAllowed() roda
antes da chamada e bloqueia — economiza crédito e, mais importante, não
depende do modelo obedecer instrução.
{
"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 | Bloqueio |
| paciente, antes/depois, corpo, resultado de procedimento — CFM 2.336/2023 |
Teste rápido do guarda-corpo, sem chave e sem custo:
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)"Testes
npm test # 110 testes, sem chave de API, sem rede externa, sem custoCobre: compliance, brand kit, config, artifact store, conversão de link do Drive, todos os modos de falha de download, redução, upload, tabelas de tamanho, o fluxo OAuth inteiro (com um Google de mentira), a descoberta que o claude.ai faz, e os dois transportes MCP de ponta a ponta.
Os testes que gastam crédito ou dependem de rede viva ficam fora da suíte,
em scripts/:
npm run probe # ~US$ 0,005 — separa "chave ruim" de "pipeline ruim" (openai)
npm run probe:gemini # idem, para o provider gemini
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ásVariáveis de ambiente
Variável | Padrão | Para quê |
| — | Obrigatória com o provider |
| — | Obrigatória com o provider |
|
| Troca o motor de imagem: |
|
|
|
|
| Porta do modo HTTP |
|
| Caminho do endpoint MCP |
| — | Bearer fixo (script e teste; o claude.ai não aceita) |
| — | Obrigatória com OAuth: é o issuer, e precisa ser fixa |
| — | Ligam o OAuth |
| — | Quem pode autorizar. Conta Google válida não é permissão |
|
| Salva a resolução cheia em |
|
| Validade do link de download |
|
| Teto de memória do depósito de peças |
Hospedagem (EasyPanel, ou qualquer host de container)
O servidor guarda estado em memória de propósito — clientes OAuth, tokens e o
depósito de peças são Map(). Isso exige um processo vivo e único, e é o
que descarta plataforma serverless: lá o POST /register cairia numa instância
e o GET /authorize em outra, que não conhece o cliente. O login falharia de
forma intermitente, com sintoma que não parece com a causa.
Por isso o deploy é container, e a regra vale para qualquer host: uma réplica só. Para escalar além disso, troque os três armazenamentos em memória por Redis primeiro.
O Dockerfile na raiz serve a qualquer plataforma de container. Os passos
abaixo são do EasyPanel; em outro host muda a interface, não o conteúdo.
O domínio vem antes
O Google não aceita endereço IP como redirect de OAuth, e exige HTTPS. Ou seja, um domínio é pré-requisito, não acabamento.
Aponte um registro A do subdomínio para o IP do servidor. Quem não tiver
domínio pode usar DNS curinga — mcp.<ip-com-hifens>.sslip.io resolve sozinho
para o IP embutido no nome, e o Let's Encrypt emite normalmente desde que a
porta 80 esteja aberta.
Serviço
Criar serviço → App, com source neste repositório e branch
main.Build: Dockerfile, na raiz.
Environment:
Variável
Valor
PORT8787MCP_BASE_URLhttps://<seu-dominio>— sem barra no fimOPENAI_API_KEYa chave da OpenAI
GOOGLE_CLIENT_IDdo cliente OAuth (Aplicativo da Web)
GOOGLE_CLIENT_SECRETdo mesmo cliente
MCP_EMAILSquem pode autorizar, separado por vírgula
MCP_TRANSPORT=httpjá vem doDockerfile— não defina.Domains: o subdomínio apontando para a porta
8787, com HTTPS ligado.Deploy.
Google Cloud Console → Credenciais → seu cliente OAuth, adicione o redirect autorizado, exatamente:
https://<seu-dominio>/oauth/google/callbackclaude.ai → conectores:
https://<seu-dominio>/mcp.
O MCP_BASE_URL vira o issuer do OAuth e é comparado caractere por caractere
com o que o cliente descobre. Domínio diferente do configurado, ou barra
sobrando, faz o vínculo falhar sem mensagem útil.
Conferindo
curl https://<seu-dominio>/healthO campo que importa é "auth":"oauth". Se vier "none", alguma variável do
Google não chegou — e aí o servidor subiu aberto, aceitando qualquer
chamada e gastando a chave de quem hospeda.
Notas de API que economizam debug
O
Kdeimage_sizeé maiúsculo.2ké rejeitado.gpt-image-2aceita qualquer WxH divisível por 16; os menores só aceitam três tamanhos fixos. Story/reels final precisa degpt-image-2.Na edição, a imagem vem antes do texto no array de input.
Não existe refação encadeada no provider
openai:previous_interaction_idé da Interactions API do Gemini. Para ajustar, reenvie a imagem como referência.Entrada por URL manda
User-Agentpróprio: várias origens (Wikimedia entre elas) devolvem 400/403 para requisição sem UA identificável.Peça com texto: defina a copy primeiro, depois peça a imagem com aquela 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