Skip to main content
Glama

Gemini Image MCP

A tiny remote MCP server that lets Claude (or any MCP client) generate images with Google Gemini. Claude can't create images on its own — connect this and it can. The generated image is stored on Vercel Blob and returned as a public URL you can drop straight into an <img src>, an OG tag, or a blog post.

  • Six tools: generate_image (text → image, exact sizing + webp/jpeg compression), edit_image (image(s) + prompt → new image), list_models, list_images, fetch_image (bytes as base64 for sandboxed clients), delete_image

  • Zero framework, one serverless function (api/mcp.js), one dependency (@vercel/blob)

  • Bring your own API key. Nothing is hard-coded; every secret is read from env.

  • Works as a claude.ai / Claude Cowork custom connector (streamable-HTTP + SSE + token auth).


Deploy your own (5 minutes)

Deploy with Vercel

The button clones this repo into your own GitHub account and deploys that copy — no manual fork needed.

Or manually: Fork this repo on GitHub first, then Vercel → Add New → Project → import your fork (Framework preset: Other). Vercel's import list only shows repos in your own account, so a fork is required for the manual path.

1. Create a Vercel Blob store

Project → Storage → Create Database → BlobConnect to this project. This injects BLOB_READ_WRITE_TOKEN automatically — you don't set it by hand.

2. Set two environment variables

Project → Settings → Environment Variables:

Variable

Value

GOOGLE_AI_API_KEY

Your Gemini API key from Google AI Studio (billing-enabled project)

MCP_AUTH_TOKEN

A secret you invent — it guards the endpoint. Generate one with openssl rand -base64 32

BLOB_READ_WRITE_TOKEN is added for you in step 1. The endpoint fails closed if MCP_AUTH_TOKEN is unset.

3. Turn off Deployment Protection

Project → Settings → Deployment Protection → Vercel Authentication: OFF. (Otherwise MCP clients get a 401 from Vercel's auth wall, before they ever reach the server.)

4. Redeploy

Deployments → latest → Redeploy so the env vars take effect.


Related MCP server: gemini-nano-banana-mcp

Connect it to Claude

In claude.ai → Settings → Connectors → Add custom connector, use:

https://<your-project>.vercel.app/api/mcp?token=<MCP_AUTH_TOKEN>

The ?token= query param is how claude.ai passes auth (it has no custom-header field). Once connected, the generate_image tool appears in Claude and Cowork.

You can also use it from Claude Code by adding it to .mcp.json / your MCP config as an HTTP server with an Authorization: Bearer <MCP_AUTH_TOKEN> header.


The tools

generate_image — text → image

Arg

Type

Required

Notes

prompt

string

Describe subject, style, lighting. Add "no text, no logos" for clean results.

aspect_ratio

string

Soft composition hint, e.g. 16:9, 1:1, 9:16 (use width/height for a hard crop).

width / height

integer

Exact output size in px. Both set → cover-crop to exactly W×H (e.g. 1200×630 for OG). One set → proportional resize.

format

string

webp | jpeg | png. webp/jpeg strongly reduce file size (PNG ~1.2 MB → webp ~150 KB).

quality

integer

1–100 compression quality for webp/jpeg (default 82).

name

string

Base filename; a random suffix is added so every URL is unique.

model

string

Gemini model id (see list_models). Defaults to gemini-2.5-flash-image.

Returns: { "url", "mime", "bytes", "model", "width", "height", "aspect_ratio" }

Blog hero/OG recipe: width: 1200, height: 630, format: "webp" — one call, ready to embed.

edit_image — image(s) + prompt → new image

Feed existing image(s) and describe the change (recolor, add/remove an element, swap background, restyle, composite).

Arg

Type

Required

Notes

image_url

string

✅*

Source image: an http(s) URL (e.g. one from generate_image) or a data: URL.

image_urls

string[]

✅*

Or up to 4 images — composite two photos, transfer a style, place a product on a background.

prompt

string

What to change, e.g. "make the background dark navy, keep the apple".

width/height/format/quality/name/model

Same output options as generate_image.

Returns: { "url", "mime", "bytes", "model", "width", "height", "sources" }

list_models — pick a model

No arguments. Returns the image-capable Gemini models (queried live, with a curated fallback) plus the default:

{ "default": "gemini-2.5-flash-image", "models": [ { "id": "gemini-2.5-flash-image", "description": "…" } ] }

Pass any returned id as the model argument to generate_image / edit_image.

list_images — what's in the store

Arg

Type

Required

Notes

limit

integer

Max results (default 100, max 1000).

cursor

string

Pagination cursor from the previous call.

Returns { count, total_bytes, has_more, cursor, images: [{ url, pathname, size, uploaded_at }] } — handy for reviewing storage usage and finding candidates to clean up.

fetch_image — bring bytes into a sandboxed client

Some environments (e.g. Claude Cowork's cloud sandbox) can't download the Blob domain directly — but MCP tool results always get through. This tool returns the image as a base64 data: URL you can decode to a local file.

Arg

Type

Required

Notes

url

string

Image URL to fetch (e.g. a Blob URL from generate_image).

max_dimension

integer

Max px before re-encode (default 1024; 0 = no resize).

quality

integer

webp quality (default 80).

raw

boolean

true = original bytes untouched (4 MB cap).

Returns { "data_url", "mime", "bytes", "source" }.

delete_image — clean up

Arg

Type

Required

Notes

url

string

✅*

One Blob URL to delete.

urls

string[]

✅*

Or up to 100 URLs at once.

⚠️ Permanent — a blog post embedding a deleted URL will show a broken image. Check usage first.


How it works

api/mcp.js is a single Vercel serverless function that speaks JSON-RPC 2.0 (MCP):

  1. Auth: Authorization: Bearer <MCP_AUTH_TOKEN> or ?token=<MCP_AUTH_TOKEN>.

  2. initialize / tools/list / tools/call handled inline.

  3. generate_image / edit_image → call <model>:generateContent (text, or image + text), get base64 image bytes.

  4. Uploads the bytes to Vercel Blob (put(..., { access: "public" })).

  5. Returns the public Blob URL.

  6. Responds as text/event-stream when the client's Accept header asks for SSE (required by claude.ai), otherwise plain JSON.

Cost & notes

  • You pay for your own Gemini API usage and Vercel Blob storage/bandwidth. This project has no billing of its own.

  • The default model is gemini-2.5-flash-image; call list_models to see alternatives, or change DEFAULT_MODEL in api/mcp.js.

  • Keep MCP_AUTH_TOKEN secret — anyone with the URL + token can spend your Gemini quota.

License

MIT — see LICENSE. Copy it, fork it, ship it.

Related MCP Connectors

Related MCP Servers