wrmmax-criativo-mcp

wrmmax-criativo-mcp

Enables an AI assistant to generate and edit brand-compliant marketing images through MCP tools, including creating visuals from prompts, modifying reference photos, and refining results based on prior output.

Category
Visit Server

README

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 (ainda não implementado):

export IMAGE_PROVIDER=gemini
export GEMINI_API_KEY="sua-chave"

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"
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
IMAGE_PROVIDER openai Troca o motor de imagem
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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured