Skip to main content
Glama

🎨 Image Gen MCP Server

"Fine. I'll do it myself." — Thanos (and also me, after trying five different MCP servers that couldn't mix-and-match image models)
I wanted a single, simple MCP server that lets agents generate and edit images across OpenAI, Google (Gemini/Imagen), Azure, Vertex, and OpenRouter—without yak‑shaving. So… here it is.

PyPI version Python 3.12+ license

A multi‑provider Model Context Protocol (MCP) server for image generation and editing with a unified, type‑safe API. It returns MCP ImageContent blocks plus compact structured JSON so your client can route, log, or inspect results cleanly.

IMPORTANT

ThisREADME.md is the canonical reference for API, capabilities, and usage. Some /docs files may lag behind.


🗺️ Table of Contents


Related MCP server: Universal Image Generator MCP Server

🧠 Why this exists

Because I couldn’t find an MCP server that spoke multiple image providers with one sane schema. Some only generated, some only edited, some required summoning three different CLIs at midnight.
This one prioritizes:

  • One schema across providers (AR & diffusion)

  • Minimal setup (uvx or pip, drop a mcp.json, done)

  • Type‑safe I/O with clear error shapes

  • Discoverability: ask the server what models are live via get_model_capabilities


✨ Features

  • Unified tools: generate_image, edit_image, get_model_capabilities

  • Providers: OpenAI, Azure OpenAI, Google Gemini, Vertex AI (Imagen & Gemini), OpenRouter

  • Output: MCP ImageContent blocks + small JSON metadata

  • Quality/size/orientation normalization

  • Masking support where engines allow it

  • Fail‑soft errors with stable shape: { code, message, details? }


🚀 Quick start (users)

Install and use as a published package.

# With uv (recommended)
uv add image-gen-mcp

# Or with pip
pip install image-gen-mcp

Then configure your MCP client.

Configure mcp.json

Use uvx to run in an isolated env with correct deps:

{
  "mcpServers": {
    "image-gen-mcp": {
      "command": "uvx",
      "args": ["--from", "image-gen-mcp", "image-gen-mcp"],
      "env": {
        "OPENAI_API_KEY": "your-key-here"
      }
    }
  }
}

First call

{
  "tool": "generate_image",
  "params": {
    "prompt": "A vibrant painting of a fox in a sunflower field",
    "provider": "openai",
    "model": "gpt-image-1"
  }
}

🧑‍💻 Quick start (developers)

Run from source for local development or contributions.

Prereqs

  • Python 3.12+

  • uv (recommended)

Install deps

uv sync --all-extras --dev

Environment

cp .env.example .env
# Add your keys

Run the server

# stdio (direct)
python -m image_gen_mcp.main

# via FastMCP CLI
fastmcp run image_gen_mcp/main.py:app

Local VS Code mcp.json for testing

If you use a VS Code extension or local tooling that reads .vscode/mcp.json, here's a safe example to run the local server (do NOT commit secrets):

{
  "servers": {
    "image-gen-mcp": {
      "command": "python",
      "args": ["-m", "image_gen_mcp.main"],
      "env": {
        "# NOTE": "Replace with your local keys for testing; do not commit.",
        "OPENROUTER_API_KEY": "__REPLACE_WITH_YOUR_KEY__"
      }
    }
  },
  "inputs": []
}

Use this to run the server from your workspace instead of installing the package from PyPI. For CI or shared repos, store secrets in the environment or a secret manager and avoid checking them into git.

Dev tasks

uv run pytest -v
uv run ruff check .
uv run black --check .
uv run pyright

🧰 Tools API

All tools take named parameters. Outputs include structured JSON (for metadata/errors) and MCP ImageContent blocks (for actual images).

generate_image

Create one or more images from a text prompt.

Example

{
  "prompt": "A vibrant painting of a fox in a sunflower field",
  "provider": "openai",
  "model": "gpt-image-1",
  "n": 2,
  "size": "M",
  "orientation": "landscape"
}

Parameters

Field

Type

Description

prompt

str

Required. Text description.

provider

enum

Required. openai | openrouter | azure | vertex | gemini.

model

enum

Required. Model id (see matrix).

n

int

Optional. Default 1; provider limits apply.

size

enum

Optional. S | M | L.

orientation

enum

Optional. square | portrait | landscape.

quality

enum

Optional. draft | standard | high.

background

enum

Optional. transparent | opaque (when supported).

negative_prompt

str

Optional. Used when provider supports it.

directory

str

Optional. Filesystem directory where the server should save generated images. If omitted a unique temp directory is used.


edit_image

Edit an image with a prompt and optional mask.

Example

{
  "prompt": "Remove the background and make the subject wear a red scarf",
  "provider": "openai",
  "model": "gpt-image-1",
  "images": ["data:image/png;base64,..."],
  "mask": null
}

Parameters

Field

Type

Description

prompt

str

Required. Edit instruction.

images

list<str>

Required. One or more source images (base64, data URL, or https URL). Most models use only the first image.

mask

str

Optional. Mask as base64/data URL/https URL.

provider

enum

Required. See above.

model

enum

Required. Model id (see matrix).

n

int

Optional. Default 1; provider limits apply.

size

enum

Optional. S | M | L.

orientation

enum

Optional. square | portrait | landscape.

quality

enum

Optional. draft | standard | high.

background

enum

Optional. transparent | opaque.

negative_prompt

str

Optional. Negative prompt.

directory

str

Optional. Filesystem directory where the server should save edited images. If omitted a unique temp directory is used.


get_model_capabilities

Discover which providers/models are actually enabled based on your environment.

Example

{ "provider": "openai" }

Call with no params to list all enabled providers/models.

Output: a CapabilitiesResponse with providers, models, and features.


🧭 Providers & Models

Routing is handled by a ModelFactory that maps model → engine. A compact, curated list keeps things understandable.

Model Matrix

Model

Family

Providers

Generate

Edit

Mask

gpt-image-1

AR

openai, azure

✅ (OpenAI/Azure)

dall-e-3

Diffusion

openai, azure

gemini-2.5-flash-image-preview

AR

gemini, vertex

✅ (maskless)

imagen-4.0-generate-001

Diffusion

vertex

imagen-3.0-generate-002

Diffusion

vertex

imagen-4.0-fast-generate-001

Diffusion

vertex

imagen-4.0-ultra-generate-001

Diffusion

vertex

imagen-3.0-capability-001

Diffusion

vertex

✅ (mask via mask config)

google/gemini-2.5-flash-image-preview

AR

openrouter

✅ (maskless)

Provider Model Support

Provider

Supported Models

openai

gpt-image-1, dall-e-3

azure

gpt-image-1, dall-e-3

gemini

gemini-2.5-flash-image-preview

vertex

imagen-4.0-generate-001, imagen-3.0-generate-002, gemini-2.5-flash-image-preview

openrouter

google/gemini-2.5-flash-image-preview


🐍 Python client example

import asyncio
from fastmcp import Client


async def main():
    # Assumes the server is running via: python -m image_gen_mcp.main
    async with Client("image_gen_mcp/main.py") as client:
        # 1) Capabilities
        caps = await client.call_tool("get_model_capabilities")
        print("Capabilities:", caps.structured_content or caps.text)

        # 2) Generate
        gen_result = await client.call_tool(
            "generate_image",
            {
                "prompt": "a watercolor fox in a forest, soft light",
                "provider": "openai",
                "model": "gpt-image-1",
            },
        )
        print("Generate Result:", gen_result.structured_content)
        print("Image blocks:", len(gen_result.content))


asyncio.run(main())

🔐 Environment variables

Set only what you need:

Variable

Required for

Description

OPENAI_API_KEY

OpenAI

API key for OpenAI.

AZURE_OPENAI_API_KEY

Azure OpenAI

Azure OpenAI key.

AZURE_OPENAI_ENDPOINT

Azure OpenAI

Azure endpoint URL.

AZURE_OPENAI_API_VERSION

Azure OpenAI

Optional; default 2024-02-15-preview.

GEMINI_API_KEY

Gemini

Gemini Developer API key.

OPENROUTER_API_KEY

OpenRouter

OpenRouter API key.

VERTEX_PROJECT

Vertex AI

GCP project id.

VERTEX_LOCATION

Vertex AI

GCP region (e.g. us-central1).

VERTEX_CREDENTIALS_PATH

Vertex AI

Optional path to GCP JSON; ADC supported.


🏃 Running via FastMCP CLI

Supports multiple transports:

  • stdio: fastmcp run image_gen_mcp/main.py:app

  • SSE (HTTP): fastmcp run image_gen_mcp/main.py:app --transport sse --host 127.0.0.1 --port 8000

  • HTTP: fastmcp run image_gen_mcp/main.py:app --transport http --host 127.0.0.1 --port 8000 --path /mcp

Design notes

  • Schema: public contract in image_gen_mcp/schema.py (Pydantic).

  • Engines: modular adapters in image_gen_mcp/engines/, selected by ModelFactory.

  • Capabilities: discovered dynamically via image_gen_mcp/settings.py.

  • Errors: stable JSON error { code, message, details? }.


⚠️ Testing remarks

I tested this project locally using the openrouter-backed model only. I could not access Gemini or OpenAI from my location (Hong Kong) due to regional restrictions — thanks, US government — so I couldn't fully exercise those providers.

Because of that limitation, the gemini/vertex and openai (including Azure) adapters may contain bugs or untested edge cases. If you use those providers and find issues, please open an issue or, even better, submit a pull request with a fix — contributions are welcome.

Suggested info to include when filing an issue:

  • Your provider and model (e.g., openai:gpt-image-1, vertex:imagen-4.0-generate-001)

  • Full stderr/server logs showing the error

  • Minimal reproduction steps or a short test script

Thanks — and PRs welcome!


🤝 Contributing & Releases

PRs welcome! Please run tests and linters locally.

Release process (GitHub Actions)

  1. Automated (recommended)

    • Actions → Manual Release

    • Pick version bump: patch / minor / major

    • The workflow tags, builds the changelog, and publishes to PyPI

  2. Manual

    • git tag vX.Y.Z

    • git push origin vX.Y.Z

    • Create a GitHub Release from the tag


📄 License

Apache-2.0 — see LICENSE.

Available Tools

3 tools
edit_imageEdit ImageA

Edit an image with a prompt and optional mask. Pass images as data URLs/base64/https URLs.

ParametersJSON Schema
NameRequiredDescriptionDefault
nNoCount of images to generate; provider limits apply.
maskNoOptional mask image (same encoding forms as items in 'images').
sizeNoUnified size class: 'S' | 'M' | 'L'.
modelYesModel id to use for editing.
imagesYesOne or more image sources; most edit-capable models use only images[0]. Accepted forms: (1) http(s) URL, (2) local file path or file:// URL (the server will read and inline it), (3) data URL 'data:image/<type>;base64,<payload>', or (4) bare base64 string. Recommended: pass a data URL or base64 for best reliability. Supported types: PNG, JPEG, WEBP, GIF. Invalid or tiny placeholder images may be rejected by providers.
promptYesText instruction describing the edit to perform.
qualityNoQuality preference: 'draft' | 'standard' | 'high'.
providerYesProvider: 'openai' | 'openrouter' | 'azure' | 'vertex' | 'gemini'.
directoryNoOptional directory path to save edited images. If not provided, images will be saved to a temporary directory.
backgroundNoOptional background alpha for AR engines supporting transparency.
orientationNoOrientation preference: 'square' | 'portrait' | 'landscape'.
negative_promptNoOptional negative prompt honored by supporting providers.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are present (readOnlyHint=false, openWorldHint=true) and not contradicted. The description adds value by detailing that images can be passed as data URLs/base64/https URLs, that most edit-capable models use only images[0], and that invalid images may be rejected. This goes beyond the bare annotation to clarify input handling behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences immediately stating the core purpose and input format. No filler or redundancy. Every word contributes to the essential message.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 12 parameters, no output schema, and moderate complexity, the description is too brief. It covers image input format but omits any mention of other parameters (n, size, quality, etc.), return value expectations, model-specific behaviors (like which models support masks), or side effects (directory saving). The agent would have to rely entirely on the schema to understand all options.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema documents all 12 parameters. The description adds minimal parameter context: it only mentions 'prompt' and 'optional mask' generically. It does not explain 'n', 'size', 'quality', 'negative_prompt', 'directory', etc., missing an opportunity to guide usage of these important parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Edit'), the resource ('an image'), and the mechanism ('with a prompt and optional mask'). It also specifies accepted image formats (data URLs/base64/https URLs), which distinctively separates it from sibling tools like 'generate_image' that create new images from scratch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for editing existing images but provides no explicit guidance on when to prefer this over 'generate_image' or 'get_model_capabilities'. It lacks any 'when to use' or 'when not to use' statements, leaving the agent to infer context from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_imageGenerate Image(s)C

Generate image(s) from a text prompt. Prefer explicit provider+model; respect model capabilities.

ParametersJSON Schema
NameRequiredDescriptionDefault
nNoCount of images to generate; provider limits apply.
sizeNoUnified size class: 'S' | 'M' | 'L'.
modelYesModel id (e.g., 'gpt-image-1', 'dall-e-3', 'imagen-4.0-generate-001').
promptYesText description of the desired image.
qualityNoQuality preference: 'draft' | 'standard' | 'high'.
providerYesProvider: 'openai' | 'openrouter' | 'azure' | 'vertex' | 'gemini'.
directoryNoOptional directory path to save generated images. If not provided, images will be saved to a temporary directory.
backgroundNoOptional background alpha for AR engines supporting transparency.
orientationNoOrientation preference: 'square' | 'portrait' | 'landscape'.
negative_promptNoOptional negative prompt honored by supporting providers.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate non-readOnly (write operation) and non-idempotent, but description adds no behavioral context beyond what annotations provide. It does not disclose potential side effects, no mention of auth requirements, rate limits, or what happens with different model choices. Descriptions should add value beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise—one sentence and a short instruction. No wasted words, but could be restructured to include essential guidance. Concision is high, but at the cost of completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has 10 parameters, complex schema with enums, and no output schema. Description fails to explain return values, supported image formats, error handling, or model-specific constraints. Incomplete for a complex generative tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. Description provides minor added guidance regarding explicit provider+model but does not add significant meaning beyond what parameter descriptions already cover. Minimal extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb+resource: 'generate image(s) from a text prompt'. Description states action and input. However, it does not explicitly distinguish from sibling tools like 'edit_image' or 'get_model_capabilities', though the tool name itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides implicit usage guidance ('Prefer explicit provider+model; respect model capabilities') but lacks explicit when-to-use, when-not-to-use, or alternatives. No mention of why one would choose this tool over 'edit_image' or when to use 'get_model_capabilities' instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_model_capabilitiesList CapabilitiesA
Read-onlyIdempotent

Return enabled providers and per-model capability metadata (generation/edit/mask/limits).

ParametersJSON Schema
NameRequiredDescriptionDefault
providerNoOptional provider filter: openai | openrouter | azure | vertex | gemini.

Output Schema

ParametersJSON Schema
NameRequiredDescription
capabilitiesNoList of enabled engines based on credentials.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true, indicating no side effects. The description adds value by specifying the exact content of the returned metadata (generation/edit/mask/limits) and indicating it is per-model, providing useful behavioral context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the key information: the action ('Return') and the target ('enabled providers and per-model capability metadata'). Every part of the sentence is informative and earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (one optional parameter, read-only, has output schema), the description fully explains what the tool returns. The presence of an output schema and detailed parameter documentation means the description does not need to cover return values or parameter details further.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with a detailed description for the optional provider parameter listing the allowed values and their meaning. The tool description adds no additional parameter information, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Return' and clearly identifies the resource: enabled providers and per-model capability metadata including generation, edit, mask, and limits. This distinguishes it from siblings like edit_image and generate_image, which perform edits or generations rather than returning metadata.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for checking capabilities before calling sibling tools, but it does not explicitly state when to use this tool over alternatives. For example, it could say 'Use this to discover available providers and model capabilities before calling edit_image or generate_image.' Without such guidance, the description is adequate but not optimal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.7/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: generating images from text, editing existing images, and querying model capabilities. No overlap.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case (edit_image, generate_image, get_model_capabilities).

Tool Count4/5

With only 3 tools, the server is minimal but covers the core operations for image generation and editing. The count is reasonable for a focused domain.

Completeness4/5

The tool set covers generate, edit, and model discovery. Missing operations like listing or deleting images are not critical, so the surface is mostly complete.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that enables AI applications to access 20+ model providers (including OpenAI, Anthropic, Google) through a unified interface for text and image generation.
    2
    30
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A multi-provider AI image generation server that allows users to create and transform images using Google (Imagen & Gemini), ZHIPU AI CogView-4, or Alibaba Bailian through any MCP-compatible application.
    4
    2
    MIT

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/simonChoi034/image-gen-mcp'

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