Skip to main content
Glama
farukcan
by farukcan

Frag deinen Agenten nach einem Bild, und er bekommt einen Dateipfad zurück – keine Wand aus base64. Der Server erzeugt das Bild mit Gemini oder OpenAI, schreibt es auf die Festplatte und gibt nur den absoluten Pfad zurück. Dein Kontextfenster bleibt sauber, und die Datei ist genau dort, wo der Agent sie öffnen, verschieben oder einem anderen Tool übergeben kann.

Features

  • Ein Tool, ohne Umstände. generate_image(prompt, images, aspect_ratio) – das ist die gesamte API.

  • Pfade, keine Nutzlasten. Gibt einen absoluten Dateipfad zurück, sodass ein 1,5 MB großes PNG dich ~60 Tokens kostet statt ~2 Millionen.

  • Zwei Anbieter, automatisch ausgewählt. Setze den API-Schlüssel, den du hast. Beide gesetzt? IMAGE_PROVIDER entscheidet.

  • Bild-zu-Bild. Übergebe bis zu 4 Referenzbilder, um sie umzugestalten, zu bearbeiten oder zu kombinierten.

  • Flexible Eingaben. Eine Referenz kann ein lokaler Pfad, eine http(s)-URL, ein data:-URI oder nacktes base64 sein – der Server erkennt, um welche es sich handelt.

  • Beide Transporte. stdio für lokale Clients, Streamable-HTTP (an localhost gebunden), wenn du einen Port brauchst.

  • Ehrliche Fehler. Keine Wiederholungen, die einen falschen Schlüssel verschleiern, kein stilles Fallback auf einen anderen Anbieter. Wenn die API 429 sagt, siehst du 429.

  • Klein genug zum Lesen. ~540 Zeilen Quellcode, keine Datei über 100 Zeilen, durchgehend streng typisiert.

Related MCP server: VisionToolMCP

Voraussetzungen

Anforderung

Hinweise

Python 3.11+

3.12 ist die Version, auf der die CI-äquivalenten lokalen Prüfungen laufen

uv

curl -LsSf https://astral.sh/uv/install.sh | sh

Ein API-Schlüssel

Google Gemini oder OpenAI – mindestens einer

Hinweis zur Abrechnung. Bildmodelle sind bei keinem der beiden Anbieter im kostenlosen Tarif entalten. Ein Gemini-Schlüssel ohne aktivierte Abrechnung liefert für jedes Bildmodell 429 ... limit: 0 zurück.

Schnellstart

git clone https://github.com/farukcan/image-generation-mcp.git
cd image-generation-mcp
uv sync

cp .env.example .env      # add OPENAI_API_KEY or GEMINI_API_KEY
uv run pytest -m smoke    # generates a real image into out/

Der letzte Befehl ist der schnellste Weg, um Ende zu Ende zu bestätigen, dass dein Schlüssel funktioniert – er gibt den Pfad des gerade erzeugten Bildes aus.

Füge es deinem Agenten hinzu

Claude Code

claude mcp add image-generation \
  -e OPENAI_API_KEY=sk-... \
  -- uvx --from git+https://github.com/farukcan/image-generation-mcp image-generation-mcp

uvx lädt das Paket beim ersten Lauf herunter, erstellet es und speichert es im Cache – es gibt nichts vorab zu installieren und nichts, das du von Hand aktualisieren müsstest.

Du bevorzugst ein Checkout, das du bearbeiten kannst? Dann zeige stattdessen auf das Verzeichnis:

claude mcp add image-generation \
  -e OPENAI_API_KEY=sk-... \
  -- uv run --directory /absolute/path/to/image-generation-mcp image-generation-mcp

Füge -s user hinzu, um es in allen Projekten verfügbar zu machen statt nur in diesem. Überprüfe es mit claude mcp list und entferne es mit claude mcp remove image-generation.

Gemini CLI

Gleiche Flags, gleiche Form:

gemini mcp add image-generation \
  -e OPENAI_API_KEY=sk-... \
  -- uvx --from git+https://github.com/farukcan/image-generation-mcp image-generation-mcp

Cursor, Windsurf, Claude Desktop und alles andere

Diese lesen eine JSON-Konfigurationsdatei (.cursor/mcp.json, claude_desktop_config.json, …). Der Eintrag ist überall derselbe:

{
  "mcpServers": {
    "image-generation": {
      "command": "uvx",
      "args": [
        "--from", "git+https://github.com/farukcan/image-generation-mcp",
        "image-generation-mcp"
      ],
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "OUT_DIR": "/absolute/path/where/images/should/land"
      }
    }
  }
}

Setze OUT_DIR für GUI-Clients explizit – sie starten oft mit einem Arbeitsverzeichnis, das du nicht erwartet hast, und out/ würde dort landen.

Als HTTP-Dienst

uv run image-generation-mcp --transport http --port 8000

Stellt den Streamable-HTTP-Endpunkt unter http://127.0.0.1:8000/mcp bereit. Er bindet nur an Loopback und hat keine Authentifizierung. Setze ihn also hinter einen Proxy, befor du ihn freigibst.

Das Tool

generate_image(prompt: str, images: list[str] | None = None, aspect_ratio: str = "1:1") -> str

Parameter

Beschreibung

prompt

Was das Bild zeigen soll.

images

Bis zu 4 Referenzbilder. Jedes ist ein lokaler Dateipfad, eine http(s)://-URL (30 s Timeout, wird gestreamt und nach 20 MB abgebrochen), ein data:-URI oder nacktes base64. Eine vorhandene Datei gewinnt immer; andernfalls wird eine base64-förmige Zeichenfolge als solche dekodiert.

aspect_ratio

1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9.

Gibt den absoluten Pfad der geschriebenen Datei zurück, z. B. /path/to/out/20260827-172746-c9b3.png. Die Namen folgen dem Muster YYYYmmdd-HHMMSS-xxxx, sodass Ergebnisse chronologisch sortiert werden und nie kollidieren.

Zu den Seitenverhältnissen: Gemini unterstützt alle zehn. OpenAI akzeptiert nur drei Größen, daher werden die Verhältnisse auf das nächstgelegene von 1024x1024, 1536x1024 oder 1024x1536 reduziert – wer dort 16:9 anfordert, bekommt 3:2.

Konfiguration

Jede Einstellung ist eine Umgebungsvariable. Eine .env- Datei im Arbeitsverzeichnis (oder in einem übergeordneten Verzeichnis) wird als Fallback geladen; echte Umgebungsvariablen haben immer Vorrang.

Variable

Standard

Zweck

GEMINI_API_KEY

Aktiviert den Gemini-Anbieter

OPENAI_API_KEY

Aktiviert den OpenAI-Anbieter

IMAGE_PROVIDER

nicht gesetzt

Erzwingt gemini oder openai. Nicht gesetzt bedeutet: zuerst Geminie, dann OpenAII

GEMINI_IMAGE_MODEL

gemini-3.1-flash-image

Auch gemini-3-pro-image, gemini-3.1-flash-lite-image

OPENAI_IMAGE_MODEL

gpt-image-2

Auch gpt-image-1.5, gpt-image-1, gpt-image-1-mini

OUT_DIR

<cwd>/out

Wohin erzeugte Bilder geschrieben werden

MCP_TRANSPORT

stdio

stdio oder http; --transport überschreibt es

MCP_PORT

8000

HTTP-Port; --port überschreibt ihn

Startest du den Server ganz ohne API-Schlüssel, schlägt die erste Anfrage deutlicch fehl; die gesuchten Variablen werden dabei genannt.

So funktioniert es

flowchart LR
    A([MCP client]) -->|generate_image| B[server.py]
    B --> C[aspect.py<br/>validate ratio]
    B --> D[sources.py + download.py<br/>path / URL / base64 → bytes]
    B --> E{"registry.py<br/>which provider?"}
    E -->|GEMINI_API_KEY| F[gemini_provider.py<br/>Interactions API]
    E -->|OPENAI_API_KEY| G[openai_provider.py<br/>generate / edit]
    F --> H[output.py<br/>write into OUT_DIR]
    G --> H
    H -->|absolute path| A

Jedes Modul macht eine Sache und bleibt unter 100 Zeilen. Anbieter werden pro aufgelöster Konfiguration gecacht, sodass ein SDK-Client und sein Verbindungspool über Aufrufe hinweg wiederverwendet werden, statt bei jeder Anfrage neu aufgebaut zu werden.

Anbieter

Gemini

OpenAI

API

Interactions (client.aio.interactions.create)

Images (images.generate / images.edit)

SDK-Mindestversion

google-genai >= 2.3.0

openai >= 3.0.0

Referenzbilder

Inline als base64-Teile gesendet

Als Multipart-Dateien hochgeladen

Ausgabformat

Was auch immer das Modell zurückgibt – die Dateierweiterung richtet sich danach

Immer PNG (output_format="png")

Zwei bewusste Eigenheiten, die du kennen solltest:

  • Geminis Bild-response_format akzeptiert nur image/jpeg als expliziten MIME-Typ. Der Server fordert daher keinen an und benent die Datei nach dem, was zurückkommt.

  • input_fidelity wird nie an OpenAII gesendet – gpt-image-2 lehnt es mit einem 400 ab und wendet hohe Wiedergabetreue selbst an.

Entwicklung

uv run ruff check . && uv run ruff format --check .
uv run mypy
uv run pytest              # unit tests, all providers mocked
uv run pytest -m smoke -s  # real API calls; costs money, prints the paths

Smoke-Tests sind standardmäßig deaktiviert, sodass ein normaler pytest- Lauf nie Geld kostet. test_edits_a_real_image kostet zwei Generierungen, da es sein eigenes Referenzbild erstellet.

Auch das Logo und der Screenshot werden generiert – bearbeite die Skripte, nicht die SVGs:

uv run python media/generate_logo.py
uv run python media/generate_screenshot.py

Die Obergrenze von 100 Zeilen pro Datei ist eine bewusste Design-Entscheidung, kein Zufall: So bleibt jedes Modul auf einem Bildschirm überprüfbar. Teile auf, statt sie zu strecken.

Fehlerbehebung

Symptom

Ursache

429 ... limit: 0

Das Modell ist nicht im kostenlosen Tarif deines Plans entalten. Aktiviere die Abrechnung für das Projekt des Anbieters.

RuntimeError: No API key configured

Keiner der Schlüssel ist gesetzt, und von Arbeitsverzeichnis aufwärts wurde keine .env gefunden.

Bilde ercheinen an unerwarteter Stelle

OUT_DIR ist nicht gesetzt, und der Client hat den Server aus einem anderen Verzeichnis gestartet. Setze es explizit.

Unsupported aspect_ratio

Nur die zehn aufgelisteten Seitenverhältnisse werden akzeptiert; die Fehlermeldung listet sie auf.

reference images must be one of ...

OpenAII akzeptiert nur PNG-, JPEG- oder WebP-Referenzbilder.

Lizenz

MIT © Ömer Faruk Can

A
license - permissive license
Not graded
quality - not tested
C
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

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

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

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/farukcan/image-generation-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server