Skip to main content
Glama

wrmax-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-keys

Importante: 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/apikey

Related 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 exige

Ferramentas 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

cliente-medico

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 custo

Cobre: 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ás

Variáveis de ambiente

Variável

Padrão

Para quê

OPENAI_API_KEY

Obrigatória com o provider openai

GEMINI_API_KEY

Obrigatória com o provider gemini

IMAGE_PROVIDER

openai

Troca o motor de imagem: openai ou gemini

MCP_TRANSPORT

stdio

stdio ou http

PORT

8787

Porta do modo HTTP

MCP_PATH

/mcp

Caminho do endpoint MCP

MCP_TOKEN

Bearer fixo (script e teste; o claude.ai não aceita)

MCP_BASE_URL

Obrigatória com OAuth: é o issuer, e precisa ser fixa

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET

Ligam o OAuth

MCP_EMAILS

Quem pode autorizar. Conta Google válida não é permissão

PERSIST_OUTPUT

false

Salva a resolução cheia em out/ (só dev local)

ARTIFACT_TTL_MS

900000

Validade do link de download

ARTIFACT_MAX_BYTES

134217728

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

  1. Criar serviço → App, com source neste repositório e branch main.

  2. Build: Dockerfile, na raiz.

  3. Environment:

    Variável

    Valor

    PORT

    8787

    MCP_BASE_URL

    https://<seu-dominio> — sem barra no fim

    OPENAI_API_KEY

    a chave da OpenAI

    GOOGLE_CLIENT_ID

    do cliente OAuth (Aplicativo da Web)

    GOOGLE_CLIENT_SECRET

    do mesmo cliente

    MCP_EMAILS

    quem pode autorizar, separado por vírgula

    MCP_TRANSPORT=http já vem do Dockerfile — não defina.

  4. Domains: o subdomínio apontando para a porta 8787, com HTTPS ligado.

  5. Deploy.

  6. Google Cloud Console → Credenciais → seu cliente OAuth, adicione o redirect autorizado, exatamente:

    https://<seu-dominio>/oauth/google/callback
  7. claude.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>/health

O 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 K de image_size é maiúsculo. 2k é rejeitado.

  • gpt-image-2 aceita qualquer WxH divisível por 16; os menores só aceitam três tamanhos fixos. Story/reels final precisa de gpt-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-Agent pró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.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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