image-gen-mcp
Provides image generation through Google's Gemini native image models, supporting configurable aspect ratios and resolutions, with inline delivery or Cloud Storage signed URLs for larger images.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@image-gen-mcpGenerate a 16:9 image of a futuristic city skyline at sunset"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
image-gen-mcp
An MCP server that generates images with Google's Gemini native image models ("Nano Banana"), served over Streamable HTTP.
One tool, generate_image. No state anywhere, and no auth of its own —
in production it runs as a backend behind
mcp-oauth-proxy, deployed by
cloudrun-mcp-deployment.
DESIGN.md explains why it is built this way; this file explains how to run it.
Quick start (local, token auth)
uv sync
export GEMINI_API_KEY="…" # from Google AI Studio
export IMAGE_MCP_TOKEN="$(openssl rand -base64 32)"
uv run python -m image_gen_mcpPoint a client at http://127.0.0.1:8080/mcp with
Authorization: Bearer $IMAGE_MCP_TOKEN. For Claude Code:
claude mcp add --transport http image-gen http://127.0.0.1:8080/mcp \
--header "Authorization: Bearer $IMAGE_MCP_TOKEN"Related MCP server: Imagen MCP Server
The tool
generate_image(prompt, aspect_ratio="1:1", image_size="1K", model=None)Parameter | Values |
| free text, up to |
|
|
|
|
| optional; must be in |
Images at or under IMAGE_MCP_INLINE_MAX_BYTES (default 1.5 MB) come back
inline and render in the chat. Larger ones are uploaded to Cloud Storage and
returned as a signed URL. Structured output always reports the true pixel
dimensions, the model used, and which delivery route was taken.
Model / resolution support
Model | 1K | 2K | 4K |
| ✅ | — | — |
| ✅ | ✅ | ✅ |
| ✅ | ✅ | ✅ |
Unsupported combinations are rejected at the tool boundary, in milliseconds, with a message naming what is supported — rather than after a 30-second round trip.
Configuration
Everything comes from the environment. See .env.example for the annotated
list; the essentials:
Variable | Required | Purpose |
| yes | Google AI Studio key |
| unless proxied | static bearer token |
| default model | |
| models a caller may select | |
| behind proxy | take identity from |
| optional narrowing of the proxy's allowlist | |
| for 2K/4K | bucket for oversized images |
The server refuses to start rather than run misconfigured: no API key, and no auth boundary at all (neither a static token nor proxy mode) are both startup failures.
Auth
Two shapes, and the server refuses to start in neither.
Behind the proxy (production). Set IMAGE_MCP_TRUST_PROXY_HEADERS=1. The
proxy authenticates the user against Google, enforces its allowlist, strips the
client's Authorization header, and forwards the identity as X-Auth-Email /
X-Auth-Subject / X-Auth-Scope. This server reads those and requires no token
of its own — a request without X-Auth-Email gets a 401.
Trusting headers is safe only because nothing else can reach the process: in the Cloud Run multi-container layout the backend declares no ingress port, so the only things that can open a socket to it are the proxy in the same instance and the startup prober. Never enable this on a routable port.
ALLOWED_EMAILS is optional here and narrows the proxy's allowlist — useful
when the proxy admits a whole domain but image generation should cost money for
only a few people. Unset means "whoever the proxy admitted".
Token (local, Claude Code). Leave IMAGE_MCP_TRUST_PROXY_HEADERS unset and
set IMAGE_MCP_TOKEN. Callers send Authorization: Bearer <token>; the
X-Auth-* headers are ignored entirely, since without the proxy they are just
untrusted request data.
The server does not terminate OAuth and has no /authorize, /token or
/register endpoints. Setting GOOGLE_OAUTH_CLIENT_ID or _SECRET is a
startup error rather than a silent no-op — those belong on the proxy.
Building the image
.github/workflows/build.yml runs the tests, builds the image, and publishes
it to GitHub Container Registry. It does not deploy — deployment is handled
by a separate workflow or repository.
Event | Test | Build | Push |
pull request | ✅ | ✅ | — |
push to | ✅ | ✅ |
|
tag | ✅ | ✅ |
|
Published as ghcr.io/ramzpat/image-gen-mcp. Nothing needs configuring: the
workflow authenticates with the built-in GITHUB_TOKEN.
Consuming it from a deploy workflow
Deploy by digest, not by tag. A pull-through cache in front of a mutable
tag like :latest will happily serve a previous image; a digest cannot go
stale. Each run prints the digest to its job summary, and the workflow is
callable if you want to build and deploy in one pipeline:
jobs:
build:
uses: ramzpat/image-gen-mcp/.github/workflows/build.yml@main
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "deploying ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }}"From a separate repository, resolve the digest at deploy time instead:
DIGEST=$(docker buildx imagetools inspect \
ghcr.io/ramzpat/image-gen-mcp:latest --format '{{.Manifest.Digest}}')The GHCR package is private by default. A deploy job in another repository
needs either a PAT with read:packages, or the package set to public under
its GitHub package settings.
Deployment
Deployed by
cloudrun-mcp-deployment
(.github/workflows/deploy-image-gen-mcp.yml), which runs this image as the
backend container of a Cloud Run multi-container service with mcp-oauth-proxy
in front. That repo owns the GCP project, region, allowlist, and secrets; this
one only publishes the image.
What that deployment sets on this container:
|
|
|
|
| from the service's GitHub Environment secret |
entrypoint |
|
HOST=0.0.0.0 rather than loopback is required, not a leak: Cloud Run's
startup prober runs outside the container's network namespace and cannot reach
a loopback-only socket. Only the container declaring --port (the proxy)
receives ingress, so the backend stays unreachable from outside the instance.
Cloud Storage for 2K/4K
gcloud storage buckets create gs://BUCKET --uniform-bucket-level-access
gcloud storage buckets update gs://BUCKET \
--lifecycle-file=<(echo '{"rule":[{"action":{"type":"Delete"},"condition":{"age":30}}]}')
# The runtime service account signs URLs through the IAM Credentials API,
# because it has no private key file. It needs this role *on itself*:
gcloud iam service-accounts add-iam-policy-binding RUNTIME_SA \
--member="serviceAccount:RUNTIME_SA" --role=roles/iam.serviceAccountTokenCreator
gcloud storage buckets add-iam-policy-binding gs://BUCKET \
--member="serviceAccount:RUNTIME_SA" --role=roles/storage.objectAdminOmitting the serviceAccountTokenCreator binding is the most common way signed
URLs ship broken.
Tests
uv run pytest -q57 tests: startup guards, identity resolution in both shapes (proxy headers, static token, and each ignoring the other's credential), tool validation and delivery, and end-to-end smoke tests driving a real MCP client over real HTTP against uvicorn — in token mode and in the proxied production shape.
Cost
Every allowlisted user draws on one API key. The controls, in order of how much
they actually help: --max-instances, IMAGE_MCP_MAX_CONCURRENCY, a GCP
billing budget alert, and IMAGE_MCP_RATE_PER_HOUR. The rate limit is counted
per instance, so its true ceiling is IMAGE_MCP_RATE_PER_HOUR × --max-instances.
This server cannot be installed
Maintenance
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
- FlicenseAqualityDmaintenanceEnables text-to-image generation, image editing, and multi-image composition using Google's Gemini 2.5 Flash Image API. Supports flexible aspect ratios and character consistency across generations.1
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to generate high-quality images using Google's Gemini and Imagen models with support for multiple aspect ratios, dynamic model selection, and direct file saving capabilities.MIT
- AlicenseNot gradedqualityNot gradedmaintenanceEnables image generation using Google's Gemini 2 API with customizable parameters like aspect ratio, number of samples, and person generation settings.189
- AlicenseNot gradedqualityBmaintenanceGenerates images from text prompts using Google's Gemini AI models with customizable aspect ratios and resolutions up to 4K, automatically saving images locally.332MIT
Related MCP Connectors
Generate images with any major model — one API key, one prepaid balance, one MCP.
Generate images, video & speech with Nano Banana, Veo, Omni and Gemini TTS. Pay as you go.
Generate logos, social posts, app screenshots, comic panels & visual-novel assets from prompts.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ramzpat/image-gen-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server