Skip to main content
Glama

wrmax-criativo

Pipeline zur Bilderzeugung und -bearbeitung von WRMax. Claude Code ist das Gehirn; dieses Repo ist die Hand.

Der Code weiß nichts über Marketing – er erhält Parameter und liefert eine Datei. Wer Format, Winkel und Prompt bestimmt, ist Claude, der danach das erzeugte Werkstück betrachtet und entscheidet, ob er es akzeptiert oder neu macht. Genau diese geschlossene Schleife kennzeichnet die Orchestrierung.

Der Code, die Kommentare und die Nachrichten sind auf Englisch. Die Dokumentation und die Kommunikation mit dem Team erfolgen auf Portugiesisch.


Setup (5 Minuten)

npm install
export OPENAI_API_KEY="sua-chave"      # https://platform.openai.com/api-keys

Wichtig: Ein Abo von ChatGPT Pro oder der Gemini-App gewährt keinen Zugriff auf die API. Das sind getrennte Abrechnungen. Du benötigst einen API-Schlüssel mit aktivem Billing.

Motor B (noch nicht implementiert):

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

Related MCP server: MCP OpenAI Image Generation Server

Struktur

Jeder Ordner hat eine Verantwortung, und keine Datei übernimmt zwei.

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)

Das zentrale Design: src/core/artwork-service.js weiß nicht, was MCP oder CLI ist. Es erhält eine einfache Anfrage und liefert ein einfaches Ergebnis. Wer den Content-Block formatiert, ist src/mcp/tool-result.js; wer JSON auf stdout schreibt, ist src/cli/run.js. Deshalb teilen sich die beiden Frontends einen einzigen Pfad.

Jede Abhängigkeit (Config, Artifact Store, Markenverzeichnis) wird injiziert, nicht als Singleton importiert – das ermöglicht es, die Route, das Tool und den Dienst zu testen, ohne die Umgebung anzufassen.


Verwendung

Von Grund auf erzeugen:

node bin/cli.js --brand forno-paulista --format feed \
  --prompt "Studio product shot of a rustic pizza on a wooden board, steam rising"

Echtes Kundenfoto bearbeiten (Hintergrund wechseln, Produkt erhalten):

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."

Günstiger Entwurf, bevor du für das Finale ausgibst:

node bin/cli.js --quality draft --prompt "..."

Immer erst Entwurf, dann Finale. Das kostet einen Bruchteil und vermeidet teures Neumachen.


MCP-Server

npm run mcp          # stdio — é o que o Claude Code fala
npm run mcp:http     # Streamable HTTP em :8787/mcp — é o que conector remoto exige

Verfügbare Tools: list_brands, generate_image, edit_image.

Es gibt kein Tool, das Bilder auf dem Server auflistet, durchsucht oder navigiert, und das ist absichtlich so: Wer die Datei auswählt, ist der Benutzer. Ein Suchtool würde einen injizierten Prompt in ein Kundenfoto in eine Umgebungsabtastung verwandeln.

Details zu Transport, Authentifizierung und Ziel der vollen Auflösung stehen in CLAUDE.md.


Wie Claude Code das CLI verwendet

Der Befehl gibt JSON auf stdout und Logs auf stderr aus. Das ist beabsichtigt: Claude führt aus, liest das JSON, öffnet das PNG, bewertet und verkettet den nächsten Aufruf. Kein Mensch in jeder Iteration.

{"ok":true,"file":"out/1755777.png","seconds":6.2,"aspectRatio":"4:5"}

Exit-Codes: 0 Erfolg · 1 technischer Fehler · 2 durch Compliance blockiert – das 2 existiert, damit ein Hook die beiden Fälle unterscheiden kann.


Compliance

brand/*.json enthält ein Array forbidden_terms. assertPromptAllowed() läuft vor dem Aufruf und blockiert – spart Credits und, wichtiger, hängt nicht davon ab, dass das Modell Anweisungen befolgt.

{
  "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": ""
}

Marke

Blockierung

cliente-medico

Patient, vorher/nachher, Körper, Verfahrensergebnis – CFM 2.336/2023

Schneller Test des Schutzmechanismus, ohne Schlüssel und ohne Kosten:

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)"

Tests

npm test          # 110 testes, sem chave de API, sem rede externa, sem custo

Abgedeckt: Compliance, Brand Kit, Config, Artifact Store, Konvertierung von Drive-Links, alle Fehlermodi beim Download, Reduzierung, Upload, Größentabellen, der gesamte OAuth-Ablauf (mit einem Fake-Google), die Erkennung, die claude.ai durchführt, und die beiden MCP-Transporte Ende-zu-Ende.

Die Tests, die Credits verbrauchen oder von einem Live-Netzwerk abhängen, bleiben außerhalb der Suite, in 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

Umgebungsvariablen

Variable

Standard

Zweck

OPENAI_API_KEY

Erforderlich mit dem Provider openai

IMAGE_PROVIDER

openai

Wechselt die Bild-Engine

MCP_TRANSPORT

stdio

stdio oder http

PORT

8787

Port des HTTP-Modus

MCP_PATH

/mcp

Pfad des MCP-Endpunkts

MCP_TOKEN

Fester Bearer (Skript und Test; claude.ai akzeptiert ihn nicht)

MCP_BASE_URL

Erforderlich mit OAuth: ist der Issuer und muss fest sein

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET

Aktivieren OAuth

MCP_EMAILS

Wer autorisieren darf. Ein gültiges Google-Konto ist keine Berechtigung

PERSIST_OUTPUT

false

Speichert die volle Auflösung in out/ (nur lokale Entwicklung)

ARTIFACT_TTL_MS

900000

Gültigkeit des Download-Links

ARTIFACT_MAX_BYTES

134217728

Speicherlimit des Werkstück-Depots


Hosting (EasyPanel oder jeder Container-Host)

Der Server speichert den Zustand absichtlich im Speicher – OAuth-Clients, Tokens und das Werkstück-Depot sind Map(). Das erfordert einen lebenden und einzigen Prozess, und genau das schließt serverlose Plattformen aus: Dort würde POST /register auf eine Instanz fallen und GET /authorize auf eine andere, die den Client nicht kennt. Der Login würde intermittierend fehlschlagen, mit einem Symptom, das nicht wie die Ursache aussieht.

Deshalb ist das Deployment ein Container, und die Regel gilt für jeden Host: nur eine Replik. Um darüber hinaus zu skalieren, ersetze zuerst die drei In-Memory-Speicher durch Redis.

Das Dockerfile im Root funktioniert für jede Container-Plattform. Die Schritte unten sind für EasyPanel; auf einem anderen Host ändert sich die Oberfläche, nicht der Inhalt.

Die Domain kommt zuerst

Google akzeptiert keine IP-Adresse als OAuth-Redirect und verlangt HTTPS. Das heißt, eine Domain ist eine Voraussetzung, kein Feinschliff.

Weise einen A-Record der Subdomain auf die IP des Servers. Wer keine Domain hat, kann Wildcard-DNS verwenden – mcp.<ip-mit-bindestrichen>.sslip.io löst sich von selbst zur eingebetteten IP im Namen auf, und Let's Encrypt stellt normal aus, solange Port 80 offen ist.

Dienst

  1. Dienst erstellen → App, mit Quelle in diesem Repository und Branch main.

  2. Build: Dockerfile, im Root.

  3. Environment:

    Variable

    Wert

    PORT

    8787

    MCP_BASE_URL

    https://<deine-domain> – ohne Schrägstrich am Ende

    OPENAI_API_KEY

    der OpenAI-Schlüssel

    GOOGLE_CLIENT_ID

    vom OAuth-Client (Webanwendung)

    GOOGLE_CLIENT_SECRET

    vom selben Client

    MCP_EMAILS

    wer autorisieren darf, durch Komma getrennt

    MCP_TRANSPORT=http kommt bereits aus dem Dockerfile – nicht definieren.

  4. Domains: die Subdomain, die auf Port 8787 zeigt, mit aktiviertem HTTPS.

  5. Deploy.

  6. Google Cloud Console → Anmeldedaten → dein OAuth-Client, füge den autorisierten Redirect hinzu, exakt:

    https://<seu-dominio>/oauth/google/callback
  7. claude.ai → Konnektoren: https://<deine-domain>/mcp.

MCP_BASE_URL wird zum OAuth-Issuer und wird Zeichen für Zeichen mit dem verglichen, was der Client entdeckt. Eine andere Domain als konfiguriert oder ein überflüssiger Schrägstrich lässt die Verbindung ohne hilfreiche Meldung fehlschlagen.

Überprüfen

curl https://<seu-dominio>/health

Das entscheidende Feld ist "auth":"oauth". Wenn "none" kommt, hat eine Google-Variable nicht erreicht – und dann ist der Server offen hochgefahren, akzeptiert jeden Aufruf und verbraucht den Schlüssel des Hosters.


API-Hinweise, die Debugging sparen

  • Das K von image_size ist großgeschrieben. 2k wird abgelehnt.

  • gpt-image-2 akzeptiert jedes WxH, das durch 16 teilbar ist; die kleineren akzeptieren nur drei feste Größen. Story/Reels-Finale benötigt gpt-image-2.

  • Bei der Bearbeitung kommt das Bild vor dem Text im Input-Array.

  • Es gibt keine verkettete Refaktion beim Provider openai: previous_interaction_id stammt aus der Interactions API von Gemini. Zum Anpassen sende das Bild erneut als Referenz.

  • Eingabe per URL sendet einen eigenen User-Agent: mehrere Quellen (darunter Wikimedia) geben 400/403 für Anfragen ohne identifizierbaren UA zurück.

  • Werkstück mit Text: Definiere zuerst den Copy, dann fordere das Bild mit diesem Copy an.

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