Skip to main content
Glama
pvliesdonk

io.github.pvliesdonk/image-generation-mcp

by pvliesdonk

Image Generation MCP

CI codecov PyPI Python License Docker Docs llms.txt Template

Multi-provider image generation MCP server built on FastMCP. Generate images from Claude Desktop, Claude Code, or any MCP client using OpenAI, Google Gemini, Stable Diffusion (SD WebUI), or a zero-cost placeholder provider.

Documentation | Config wizard | PyPI | Docker

Features

  • Multi-provider: OpenAI (gpt-image-2, gpt-image-1.5, dall-e-3), Google Gemini (gemini-3.1-flash-image, gemini-3-pro-image, gemini-3.1-flash-lite-image), SD WebUI (Stable Diffusion / Forge / reForge), and a zero-cost placeholder for testing.

  • Per-model style metadata: every model carries a style_profile (strengths, prompt grammar, lifecycle); list_providers includes a top-level warnings array for deprecated models. See Model Catalog.

  • Keyword-based auto-selection: provider="auto" routes by prompt content (text/logo → OpenAI, photoreal/anime → SD WebUI, draft → placeholder).

  • CDN-style image transforms: image://{id}/view?format=webp&width=512&crop_x=... resizes / re-encodes / crops on demand without re-generating.

  • Hybrid background tasks: long-running SD generations run with task=True (poll for status); short OpenAI calls stream progress in the foreground.

  • MCP Apps gallery + viewer: interactive UI surfaces (browse generated images, edit / crop / rotate) for clients that support app: resources.

  • Production deployment: Docker (multi-arch), .deb/.rpm with hardened systemd, OIDC + bearer auth, persistent EventStore for HTTP session resumability.

Related MCP server: NanoBanana MCP

What you can do with it

With this server mounted in an MCP client, you can ask:

  • "Generate a coffee mug product photo on a worn oak table, 16:9, no text." Routes to gpt-image-1.5 for typography-aware photorealism.

  • "Create three concept-art variations of a cyberpunk alley at dusk." Composes generate_image with provider="sd_webui" and a stylised checkpoint like dreamshaperXL.

  • "Crop this image to a 1:1 square centred on the subject and resize to 512px." Uses image://{id}/view?width=512&height=512&crop_x=... resource transforms.

  • "Show me my recent generations." Browses the gallery via the image://list resource and the MCP Apps gallery viewer.

  • "Save this style as 'cyberpunk-night' so I can apply it to future requests." Uses the style library, whose markdown briefs the LLM interprets per-provider.

  • "Replace the background of my last photo with a sunset sky." Uses transform_image with the gallery image_id as a reference (image-to-image via Gemini).

Installation

From PyPI

pip install image-generation-mcp

If you add optional extras via the PROJECT-EXTRAS-START / PROJECT-EXTRAS-END sentinels in pyproject.toml, document them below:

Extra

Includes

Use when

mcp

fastmcp[tasks]>=3.0,<4

Background-task support (task=True), required for long SD generations.

openai

openai>=1.0

Enables the OpenAI provider.

google-genai

google-genai>=1.0

Enables the Gemini provider.

all

fastmcp[tasks] + openai + google-genai

Everything except SD WebUI (which is HTTP-only, no extra needed).

Example: pip install image-generation-mcp[all].

From source

git clone https://github.com/pvliesdonk/image-generation-mcp.git
cd image-generation-mcp
uv sync --all-extras --all-groups

Docker

docker pull ghcr.io/pvliesdonk/image-generation-mcp:latest

To run the newest merged code instead of the newest release, use the rolling edge tag. It is rebuilt on every merge to main and carries no version identity. See Image tags for the full tag list.

docker pull ghcr.io/pvliesdonk/image-generation-mcp:edge

A compose.yml ships at the repo root as a starting point. Copy .env.example to .env, edit, and docker compose up -d.

To attach a remote Python debugger (development only; the protocol is unauthenticated), see Remote debugging.

Linux packages (.deb / .rpm)

Download .deb or .rpm packages from the GitHub Releases page. Both install a hardened systemd unit; env configuration is sourced from /etc/image-generation-mcp/env (copy from the shipped /etc/image-generation-mcp/env.example).

Claude Desktop (.mcpb bundle)

Download the .mcpb bundle from the GitHub Releases page and double-click to install, or run:

mcpb install image-generation-mcp-<version>.mcpb

Claude Desktop prompts for required env vars via a GUI wizard, with no manual JSON editing needed.

For manual Claude Desktop configuration and setup options, see Claude Desktop deployment.

Release channels

Artifacts ship on three channels. Each row lists exactly what that channel publishes.

Channel

Version identity

Artifacts

edge (rolling)

None; the commit is the identity

Docker image :edge rebuilt on every merge to main; .mcpb bundle as the mcpb-bundle-edge workflow artifact; Claude Code plugin .zip as the plugin-zip-edge artifact; rolling unstable docs version. It leaves no git tag, GitHub release, or PyPI entry behind.

Pre-release

vX.Y.Z-rc.N, computed and reviewed in its release pull request

PyPI (as the pre-release X.Y.ZrcN); GitHub release with wheels, sdist, .deb/.rpm packages, .mcpb bundle, plugin .zip, and SBOM attached; Docker image under its immutable vX.Y.Z-rc.N tag plus the ordering-aware rolling rc tag. Skips the plugin marketplace, the MCP registry, and the docs deploy.

Stable

vX.Y.Z

Everything: PyPI, Docker (version tag plus ordering-aware latest / vX / vX.Y), .deb/.rpm, GitHub release assets (wheels, sdist, .mcpb bundle, plugin .zip, SBOM), plugin marketplace and MCP registry entries (when the release is the newest stable), versioned docs with an ordering-aware latest alias.

Pre-releases reach PyPI so that a candidate's .mcpb bundle installs: the bundle points at PyPI rather than carrying the code. Ordinary installers never see them, because a PEP 440 resolver skips pre-releases unless the requirement pins one or you pass --pre. Ask for a candidate by name with pip install image-generation-mcp==X.Y.ZrcN. PyPI spells it in the PEP 440 canonical form, while tags use SemVer. Rolling pointers are ordering-aware, so a patch release cut from an old release/X.Y branch never moves latest-style tags back to older content, and a candidate for an already-released version never moves rc. See Release process for the full model.

Quick start

image-generation-mcp serve                                # stdio transport
image-generation-mcp serve --transport http --port 8000   # streamable HTTP

For library usage (embedding the domain logic without the MCP transport), import from the image_generation_mcp package directly. See the project's domain modules under src/image_generation_mcp/ for entry points.

Server info

The server registers a built-in get_server_info tool (via fastmcp_pvl_core.register_server_info_tool) so operators can confirm the deployed version with a single MCP call. The default response carries server_name, server_version, and core_version. Servers that talk to a remote upstream wire upstream version reporting inside the DOMAIN-UPSTREAM-START / DOMAIN-UPSTREAM-END sentinel in src/image_generation_mcp/server.py; see CLAUDE.md for the wiring pattern.

Configuration

Core environment variables shared across all fastmcp-pvl-core-based services:

Variable

Default

Description

IMAGE_GENERATION_MCP_KV_STORE_URL

file:///data/state

Persistent-state backend URL shared by every pvl-core subsystem that needs state. memory:// is in-process and lost on restart; file:///path persists on one server; redis://, dynamodb:// and mongodb:// each need their matching extra. When unset, defaults to file:///data/state (the volume family Docker images mount), or to memory://; with a warning; on a host where that directory is not usable.

FASTMCP_LOG_LEVEL

INFO

Log level for FastMCP internals and app loggers (DEBUG / INFO / WARNING / ERROR / CRITICAL). The -v CLI flag overrides to DEBUG.

FASTMCP_ENABLE_RICH_LOGGING

true

Set false for plain or structured JSON log output.

Domain-specific variables go below under Domain configuration.

Authentication

Callers authenticate via a bearer token or OIDC (mutually exclusive). See the Authentication guide for setup, mapped multi-subject tokens, OIDC, and troubleshooting.

Post-scaffold checklist

After copier copy and gh repo create --push:

  1. Fill in the DOMAIN blocks (every section marked with a DOMAIN sentinel comment) in this README and in CLAUDE.md. The GENERATED-ENV-TABLE-* regions are not DOMAIN blocks; the config generator owns them and rewrites them on every run.

  2. Configure GitHub secrets (see below).

  3. Install dev + docs tooling: uv sync --all-extras --all-groups.

  4. Install pre-commit hooks: uv run pre-commit install.

  5. Run the gate locally: uv run pytest -x -q && uv run ruff check --fix . && uv run ruff format . && uv run mypy src/ tests/.

  6. Push the first commit. CI should be green.

GitHub secrets

CI workflows reference three repository secrets. Configure them via Settings → Secrets and variables → Actions or with gh secret set:

Secret

Used by

How to generate

RELEASE_TOKEN

release-prepare.yml, release.yml, release-notes.yml, copier-update.yml, renovate.yml, bootstrap.yml

Fine-grained PAT at https://github.com/settings/personal-access-tokens/new with contents: write, pull_requests: write, and administration: write (bootstrap applies the repository rulesets + auto-merge). Must belong to a repository admin: the shipped rulesets grant bypass to the admin role, and the release tag + GitHub release that knope creates after a release pull request merges rely on it (pull requests the token opens also need it so their CI runs). Scoped to this repo.

CODECOV_TOKEN

ci.yml

https://codecov.io: sign in with GitHub and add the repo. The upload token is on its settings page.

CLAUDE_CODE_OAUTH_TOKEN

claude.yml, claude-code-review.yml, release-notes.yml

Run claude setup-token locally and paste the result.

gh secret set RELEASE_TOKEN
gh secret set CODECOV_TOKEN
gh secret set CLAUDE_CODE_OAUTH_TOKEN

Dependency updates are handled by Renovate (renovate.yml), which reuses RELEASE_TOKEN. It maintains uv.lock and auto-merges patch/minor bumps once the CI Success check is green; bootstrap.yml enables auto-merge and applies the repository rulesets (.github/rulesets/) on first push. See Repository Protection for the per-branch posture and bypass model. GitHub Actions are updated in the copier template and arrive via copier update, not per-repo.

GITHUB_TOKEN is auto-provided; no action needed.

Local development

The PR gate (matches CI):

uv run pytest -x -q                                  # tests
uv run ruff check --fix . && uv run ruff format .    # lint + format
uv run mypy src/ tests/                              # type-check

Pre-commit runs a subset of the gate on each commit; see .pre-commit-config.yaml for details, or CLAUDE.md for the full Hard PR Acceptance Gates.

Troubleshooting

Moving a scaffolded project

uv sync creates .venv/bin/* scripts with absolute shebangs pointing at the venv Python. If you move the repo after scaffolding (mv /old/path /new/path), uv run pytest fails with ModuleNotFoundError: No module named 'fastmcp' because the stale shebang resolves to a different interpreter than the venv's site-packages.

Fix:

rm -rf .venv
uv sync --all-extras --all-groups

uv run python -m pytest also works as a one-shot workaround (bypasses the stale entry-script shim).

uv.lock refresh after copier update

When copier update introduces new dependencies (such as a new extra added to pyproject.toml.jinja), the CI install step runs uv sync --locked, which fails against a stale lockfile. Run uv lock locally and commit the refreshed uv.lock alongside accepting the copier-update PR.

CI installs with --locked (and the review workflow with --frozen) so no job ever rewrites uv.lock in its own workspace: a job that re-locks hides the drift it just repaired, and a dirty workspace breaks any later git checkout in the same job. Lockfile drift then shows up as a red install step with a clear message, not as a silent mutation.

Domain configuration

Domain environment variables use the IMAGE_GENERATION_MCP_ prefix:

Variable

Default

Required

Description

IMAGE_GENERATION_MCP_A1111_HOST

(none)

No

Deprecated alias for IMAGE_GENERATION_MCP_SD_WEBUI_HOST; logs a warning when used.

IMAGE_GENERATION_MCP_A1111_MODEL

(none)

No

Deprecated alias for IMAGE_GENERATION_MCP_SD_WEBUI_MODEL; logs a warning when used.

IMAGE_GENERATION_MCP_READ_ONLY

true

No

When true, write-tagged tools (image generation, transforms, uploads) are hidden from clients. Set false to enable them.

IMAGE_GENERATION_MCP_SCRATCH_DIR

~/.image-generation-mcp/images

No

Directory where generated images are saved. Created automatically on first use.

IMAGE_GENERATION_MCP_OPENAI_API_KEY

(none)

No

OpenAI API key. Enables the OpenAI provider (gpt-image-2, gpt-image-1.5, dall-e-3) when set.

IMAGE_GENERATION_MCP_GOOGLE_API_KEY

(none)

No

Google API key. Enables the Gemini provider (gemini-3.1-flash-image and others) when set. Get a key at https://aistudio.google.com/apikey.

IMAGE_GENERATION_MCP_SD_WEBUI_HOST

(none)

No

SD WebUI base URL (such as http://localhost:7860). Enables the SD WebUI provider when set. Compatible with AUTOMATIC1111, Forge, reForge, and Forge-neo.

IMAGE_GENERATION_MCP_SD_WEBUI_MODEL

(none)

No

SD WebUI checkpoint name, used for model-aware preset detection (SD 1.5 / SDXL / Lightning) and checkpoint override. Unset uses the instance's current model.

IMAGE_GENERATION_MCP_DEFAULT_PROVIDER

auto

No

Provider used when no keyword triggers auto-selection: auto, openai, gemini, sd_webui, or placeholder. auto picks the first configured provider.

IMAGE_GENERATION_MCP_TRANSFORM_CACHE_SIZE

64

No

Maximum number of transformed image results (resize, crop, convert) kept in memory. Set 0 to disable caching.

IMAGE_GENERATION_MCP_PAID_PROVIDERS

openai

No

Comma-separated provider names that cost money; generate_image asks for confirmation (client elicitation) before using them. An empty value falls back to this default; to disable confirmation, set a value that names no provider (such as none).

IMAGE_GENERATION_MCP_STYLES_DIR

~/.image-generation-mcp/styles

No

Directory for style preset files (Markdown with YAML front matter). Created automatically if it does not exist.

IMAGE_GENERATION_MCP_ALLOW_LOCAL_FILE_INPUT

false

No

Allow reading input images from local filesystem paths. Off by default: only URLs and uploads are accepted.

IMAGE_GENERATION_MCP_MAX_INPUT_IMAGE_BYTES

20971520

No

Maximum accepted input image size in bytes.

IMAGE_GENERATION_MCP_FETCH_TIMEOUT_S

30.0

No

HTTP timeout in seconds when fetching remote image URLs (fetch_image and URL inputs).

IMAGE_GENERATION_MCP_TRANSFER_TTL_DEFAULT_S

3600.0

No

Link lifetime in seconds when the caller requests no explicit TTL.

IMAGE_GENERATION_MCP_TRANSFER_TTL_MAX_S

86400.0

No

Ceiling in seconds a caller-requested link TTL is clamped to.

IMAGE_GENERATION_MCP_TRANSFER_GRACE_TTL_S

60.0

No

Post-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it.

IMAGE_GENERATION_MCP_TRANSFER_LEASE_S

60.0

No

Crashed-handler reclaim window in seconds for an in-flight reservation.

IMAGE_GENERATION_MCP_TRANSFER_MAX_UPLOAD_BYTES

104857600

No

Maximum size in bytes of a single upload.

The create_download_link / create_upload_link tools and the /transfer/{token} route register only on an HTTP or SSE transport with BASE_URL set, and store link tokens in IMAGE_GENERATION_MCP_KV_STORE_URL; the IMAGE_GENERATION_MCP_TRANSFER_* knobs above tune link lifetime and upload limits. Security: IMAGE_GENERATION_MCP_ALLOW_LOCAL_FILE_INPUT grants callers server-filesystem read access via reference-image paths; enable it only for trusted callers or local single-user deployments.

Domain-config fields are composed inside src/image_generation_mcp/config.py between the CONFIG-FIELDS-START / CONFIG-FIELDS-END sentinels; env reads go through fastmcp_pvl_core.env(_ENV_PREFIX, "SUFFIX", default) so naming stays consistent, and field invariants go in __post_init__ between the CONFIG-VALIDATE-START / CONFIG-VALIDATE-END sentinels. Each field's metadata help and tags generate the table above directly, so keep them accurate and complete.

Key design decisions

  • Multi-provider with capability discovery, not feature flags. Each provider's discover_capabilities() reports its actual supported aspect ratios / qualities / formats / negative-prompt support at startup; routing logic asks the capability surface, not a hard-coded enum. New providers slot in by satisfying the protocol, with no router edits needed. (See docs/decisions/0001-…, 0002-…, 0007-….)

  • Per-model style_profile metadata, surfaced via list_providers. Closed-list providers (OpenAI, Gemini, placeholder) use exact-key lookup; SD WebUI uses a regex-ordered pattern table. Profiles include lifecycle flags (current / legacy / deprecated) and feed an auto-built top-level warnings array. (See docs/decisions/0009-….)

  • Hybrid background tasks. Short calls (OpenAI ~5 s) stream progress in-line; long calls (SD WebUI 30-180 s) run as background tasks with check_generation_status polling; clients pick the mode via task=True. (See docs/decisions/0005-….)

  • Image asset model: content-addressed registry + sidecar JSON metadata + on-demand transforms. Generated images keep their full-resolution original; image://{id}/view?format=webp&width=512&crop_x=… resources do format conversion / resize / crop on demand without re-generating. Transforms are cached. (See docs/decisions/0006-….)

  • Style library. User-saved markdown briefs (with YAML frontmatter for tags / aspect ratio / quality) that the LLM interprets per-provider, not copy-pasted verbatim. Distinct from per-model style_profile: style library is the brief; style_profile describes the model. (See docs/decisions/0008-… and 0009-… for disambiguation.)

  • Composes fastmcp_pvl_core.ServerConfig, never inherits. Domain config goes between CONFIG-FIELDS-START / CONFIG-FIELDS-END sentinels; env reads route through fastmcp_pvl_core.env(...) to keep prefix naming consistent.

Available Tools

10 tools
check_generation_statusCheck Generation StatusA
Read-onlyIdempotent

Check whether a background image generation has finished.

Call this after generate_image to wait for completion. Returns a short JSON status — no image data, no heavy UI.

  • "completed" → call show_image(uri=original_uri) to display the finished image.

  • "generating" → wait and check again.

  • "failed" → report the error to the user.

ParametersJSON Schema
NameRequiredDescriptionDefault
image_idYesThe ``image_id`` returned by ``generate_image``.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

Even with annotations indicating readOnlyHint and idempotentHint, the description adds valuable behavioral context: it returns a 'short JSON status — no image data, no heavy UI,' which signals lightweight polling. It also enumerates possible return values ('completed', 'generating', 'failed') and the associated next steps. This goes beyond annotations and helps the agent understand expected 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 compact and front-loaded. The first sentence states the purpose, the second gives usage context, and the bulleted list concisely explains the status outcomes. No unnecessary words or repetition; every sentence 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?

For a simple polling tool with one parameter and an output schema, the description is complete. It explains the return statuses, the expected next actions, and notes that it returns no image data. With annotations covering safety and idempotency, and the output schema documenting return structure, the description sufficiently covers all needed context.

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% (image_id is fully described as 'The image_id returned by generate_image'). The description doesn't add extra parameter details beyond referencing generate_image, which is consistent with the schema. Since the schema already documents the parameter well, a 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 clearly states the tool's function: 'Check whether a background image generation has finished.' This is a specific verb+resource (check status of generation) and clearly differentiates from siblings like show_image (display) and edit_image (edit). It also places the tool in the workflow by saying 'Call this after generate_image'.

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

Usage Guidelines5/5

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

The description provides explicit when-to-use guidance: 'Call this after generate_image to wait for completion.' It also gives context on how to handle each returned status, including waiting and re-checking or advancing to show_image. This effectively tells the agent when and how to use the tool in a polling loop.

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

edit_imageEdit ImageA
Read-only

Open an image for interactive editing (crop, rotate, flip).

The user edits in the viewer UI and saves as a new image. Always edits the original image — resource template transforms are ephemeral and LLM-facing; editor transforms are persistent and user-facing.

ParametersJSON Schema
NameRequiredDescriptionDefault
image_idYesID of the image to edit. Use ``image://list`` to browse available image IDs.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already indicate read-only and non-destructive behavior. The description adds valuable context: editor transforms are persistent and user-facing, while resource template transforms are ephemeral and LLM-facing. This clarifies the tool's role without contradicting 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?

Two sentences, front-loaded with the core purpose. The second sentence efficiently distinguishes this tool from resource templates. No filler or redundancy.

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

Completeness4/5

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

For a simple tool with strong annotations and full schema coverage, the description is mostly complete. However, it does not clarify the return behavior after opening the editor or explicitly state that the original image is preserved when saving a new image, leaving slight ambiguity.

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

Parameters4/5

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

The schema fully documents image_id (100% coverage), so the baseline is 3. The description adds the useful point that edits apply to the original image, not a resource template, helping the AI understand the parameter's meaning beyond the schema.

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 states a specific verb+resource: 'Open an image for interactive editing' and includes concrete operations (crop, rotate, flip). It clearly distinguishes this from viewing or browsing tools, and the saving-as-new-image behavior adds clarity.

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

Usage Guidelines4/5

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

The description implies this tool is for persistent, user-facing edits and contrasts it with ephemeral resource template transforms. However, it does not explicitly name alternative tools or say when not to use it, so it misses the full mark.

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

get_server_infoServer InfoA
Read-only

Report wrapper and upstream version info for image-generation-mcp. Returns server_name, server_version, core_version (fastmcp-pvl-core), and (when configured) an upstream version block. Useful for verifying a deployment matches the expected build.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true, so the safety profile is clear. The description adds value by detailing the exact return fields (server_name, server_version, core_version, upstream block) and the condition for upstream, which is beyond 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?

Two sentences, front-loaded with the core action, no unnecessary words. Every sentence adds value.

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?

The tool has no parameters, good annotations, and an output schema exists. The description covers the purpose and return data sufficiently for a simple informational tool.

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

Parameters4/5

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

There are no parameters, and schema coverage is 100% trivially. Following the '0 params = baseline 4' rule, the description does not need to add parameter info, and it doesn't contradict anything.

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 tool reports version info (server_name, server_version, core_version, optional upstream) for image-generation-mcp, which distinguishes it from sibling tools focused on images and generation.

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

Usage Guidelines4/5

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

The description explicitly says it is useful for verifying deployment matches expected build, providing a clear use case. It does not compare to alternatives, but given no similar version-checking siblings, this is sufficient.

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

list_providersList ProvidersA
Read-only

List available image generation providers, models, and capabilities.

Returns provider names, available models, and capability details. Each model includes a prompt_style field: use "clip" for comma-separated CLIP tags (SD 1.5/SDXL) or "natural_language" for descriptive sentences (Flux, OpenAI). Each call includes a refreshed_at timestamp. Pass force_refresh=true if providers may have changed since the last check.

Also available as the info://providers resource for clients that support MCP resources.

ParametersJSON Schema
NameRequiredDescriptionDefault
force_refreshNoWhen ``True``, re-runs capability discovery on all registered providers before returning, updating cached results. Use when providers may have changed (e.g., new SD WebUI checkpoints loaded).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true and destructiveHint=false. The description adds behavioral context beyond annotations, including the caching behavior of force_refresh, the semantic difference between 'clip' and 'natural_language' prompt styles, and the refreshed_at timestamp. However, it doesn't fully detail the response structure, though that is covered by the output schema.

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 compact and well-structured, leading with the core purpose and following with useful details about prompt_style, refreshed_at, and force_refresh. Every sentence earns its place, with no redundant or filler content.

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?

For a list tool with an output schema and robust annotations, the description provides all necessary context: return contents, prompt_style semantics, refresh behavior, and the alternative resource access. It is complete and leaves no critical gaps for an agent to trip over.

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%, so the baseline is 3. The description's mention of force_refresh ('if providers may have changed') echoes the schema's already detailed description rather than adding new meaning. It provides no additional semantics beyond what the schema already explains.

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 opens with a specific verb+resource statement: 'List available image generation providers, models, and capabilities.' This clearly distinguishes the tool from siblings like get_server_info or gallery_page. It also provides additional detail about prompt_style and refreshed_at, further clarifying the tool's purpose.

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

Usage Guidelines5/5

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

The description gives explicit conditional guidance: 'Pass force_refresh=true if providers may have changed since the last check.' It also mentions an alternative representation (info://providers resource), helping an agent decide between tool vs. resource access. This is clear usage guidance with no ambiguity.

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

list_resourcesList ResourcesA
Read-only

List all available resources and resource templates.

Returns JSON with resource metadata. Static resources have a 'uri' field, while templates have a 'uri_template' field with placeholders like {name}.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

The description adds useful behavioral context beyond the readOnlyHint annotation by explaining the output format (JSON with resource metadata) and the difference between static resources (uri) and templates (uri_template). It does not contradict 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 concise, two sentences, front-loaded with the primary purpose, and every sentence provides valuable information without redundancy.

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 (no parameters, output schema present), the description is complete. It explains the two types of resources and the field naming convention, which is all that is needed for selection and invocation.

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

Parameters4/5

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

The input schema has zero parameters, so the baseline is 4. The description does not need to add parameter semantics, and it correctly avoids inventing non-existent 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 uses a specific verb 'List' and clearly identifies the resource as 'resources and resource templates', which distinguishes it from siblings like read_resource. It is clear and unambiguous.

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 states what the tool does but does not explicitly mention when to use it over alternatives like read_resource or list_providers. Usage context is implied by the tool's purpose, but no explicit exclusions or alternatives are given.

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

read_resourceRead ResourceA
Read-only

Read a resource by its URI.

For static resources, provide the exact URI. For templated resources, provide the URI with template parameters filled in.

Returns the resource content as a string. Binary content is base64-encoded.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYesThe URI of the resource to read

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the safe-read nature is covered. The description adds valuable behavioral details beyond that: how templated resources must be handled, that content is returned as a string, and that binary content is base64-encoded. This is meaningful context not present in the annotation.

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 brief and front-loaded, with the core action stated in the first sentence. The subsequent lines provide essential usage details without unnecessary filler, and every sentence earns its place.

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

Completeness4/5

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

Given the tool's simplicity (one parameter) and the presence of an output schema, the description provides enough context for correct invocation. It covers URI construction and return format, so the agent has the key details. It could mention how to discover valid URIs, but that is not critical for this simple read operation.

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

Parameters4/5

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

The schema covers 100% of the parameters with a basic description for uri, giving a baseline of 3. The description adds extra meaning by explaining how to fill in the URI for static versus templated resources, which goes beyond the schema's simple 'URI of the resource to read.'

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?

The description clearly states the tool reads a resource by its URI, which is a specific verb and resource. It distinguishes itself from list_resources by focusing on reading a single resource, though it does not explicitly contrast with show_image, so it misses some sibling differentiation.

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?

The description gives conditional instructions for static vs. templated resources, which is useful for constructing the URI correctly. However, it does not explain when to use this tool versus alternatives like list_resources or show_image, so usage guidance relative to siblings is lacking.

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

show_imageShow ImageA
Read-only

Display a completed image with optional on-demand transforms.

Only call this for completed images — use check_generation_status to poll, then call this once when status is "completed".

Accepts a full image:// resource URI (e.g. image://abc123/view or image://abc123/view?format=webp&width=512). Transforms are encoded in the URI query string — no separate parameters needed.

Read the image://list resource to browse available image IDs.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYesA full ``image://`` resource URI, optionally with query params: ``format`` (``png``, ``webp``, ``jpeg``), ``width`` (pixels), ``height`` (pixels), ``quality`` (1-100, for lossy formats).

TDQS

A4.6/5.0
Behavior4/5

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

The annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds important context about requiring completed images and encoding transforms in the URI query string. It does not contradict the annotations and provides practical guidance on usage constraints beyond the structured data.

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?

The description is well-structured and front-loaded with the primary purpose, followed by concise usage instructions and a resource pointer. It avoids unnecessary fluff, though the 'no separate parameters needed' note is slightly redundant given the schema.

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?

Despite lacking an output schema, the description covers when to use the tool, the prerequisite of completed images, the URI format with examples, and how to discover available images. This is sufficient for a one-parameter display tool with supportive annotations.

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

Parameters4/5

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

The schema provides 100% coverage of the single 'uri' parameter, and the description adds examples of valid URIs and explains the query-string transform mechanism. While not extensive, the examples and explanation help clarify how to construct the URI, exceeding what the schema alone offers.

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 tool displays a completed image with optional on-demand transforms, using a specific verb and resource. It distinguishes itself from sibling tools by explicitly limiting use to completed images and referencing check_generation_status for polling.

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

Usage Guidelines5/5

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

It explicitly states when to call the tool ('Only call this for completed images') and how to coordinate with check_generation_status. It also directs users to the image://list resource for browsing IDs, providing clear exclusions and alternatives.

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

TDQS

A3.9/5.0
Disambiguation4/5

Most tools have clearly distinct purposes (polling, displaying, browsing, editing, listing providers). However, gallery_page and gallery_full_image are app-only helpers that overlap conceptually with browse_gallery and show_image, creating mild ambiguity for an agent.

Naming Consistency3/5

The majority follow a verb_noun pattern (check_generation_status, show_image, browse_gallery, edit_image, list_providers, get_server_info, list_resources, read_resource), but gallery_page and gallery_full_image break the pattern by starting with a noun. This makes the naming convention somewhat inconsistent.

Tool Count5/5

With 10 tools, the count falls within the ideal 3–15 range and feels well-scoped for an image generation server, assuming the missing generate_image tool existed. The number itself is appropriate.

Completeness1/5

The server is named image-generation-mcp, yet there is no generate_image tool among the listed functions; check_generation_status references it but it is absent. This is a severe gap—the core generation capability is missing, leaving only supporting utilities and viewing/browsing tools.

Maintenance

ActivityActive
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

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

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