Skip to main content
Glama

gemini-image-mcp

An MCP server that generates and edits images by driving the consumer Gemini web app (gemini.google.com) with your own browser session cookies, via the gemini-webapi library — instead of the paid, metered Gemini API.

Why this exists: the official Gemini API bills per image. If you already have a Gemini web account where image generation works, this lets you use that account instead of a metered API key. The trade-off is described below — read it before using this.

This project is not affiliated with, endorsed by, or supported by Google. "Gemini" is a Google product; this is an independent, unofficial client built on top of the third-party gemini-webapi library.

Disclaimer

Driving the consumer web app with your own session cookies, instead of an official API key, is outside Google's Terms of Service for that product. Any consequence — rate limiting, a challenge, or account action — lands on your Google account, not on this code. This tool doesn't take a position on whether that trade-off is worth it beyond making sure you know it up front. See the License section for the full no-warranty disclaimer.

Related MCP server: nano-banana-mcpv2

Features

  • generate_image and edit_image MCP tools backed by your own Gemini web session — no API key, no per-image billing.

  • list_models to discover which models your account can use.

  • Every generated or edited image accumulates into a single, self-contained, interactive HTML gallery (output/gallery.html) — the primary way to browse your output.

  • gemini_image_mcp.core has zero mcp imports, so it can be imported directly by other Python code (e.g. a Telegram bot) without going through the MCP protocol at all.

  • Automatic image-format correction: Gemini doesn't always return the format you'd expect, so saved files are renamed to match their actual content (e.g. .jpg instead of a mislabeled .png).

Requirements

  • Python >= 3.11

  • uv

  • A Gemini web account where image generation already works manually in your browser. Image generation is 18+ and region-limited, and requires Gemini Apps Activity to be turned on for your account. If the web UI itself won't generate an image, this tool can't either — fix that first.

Install / Quickstart

uv sync
copy .env.example .env

Edit .env and paste in GEMINI_1PSID / GEMINI_1PSIDTS (see Getting your cookies below), then run the smoke test:

uv run python scripts/smoke_test.py "a watercolor fox"

The smoke test prints the saved image path(s) and the gallery path on success, or a clean error message (e.g. about missing/expired cookies) on failure.

Getting your cookies

  1. In Chrome, sign in and go to https://gemini.google.com. Manually generate an image there first (e.g. ask it to "generate an image of a fox") and confirm it actually works. If the web UI itself won't generate an image, this tool cannot either — fix that first.

  2. Press F12 to open Chrome DevTools.

  3. Go to the Application tab -> Storage -> Cookies -> https://gemini.google.com.

  4. Find the cookie named __Secure-1PSID. Click it and copy its Value column (a long string). This is your GEMINI_1PSID.

  5. Find the cookie named __Secure-1PSIDTS. Copy its Value the same way. This is your GEMINI_1PSIDTS.

  6. Copy .env.example to .env and paste the two values into GEMINI_1PSID and GEMINI_1PSIDTS.

__Secure-1PSIDTS rotates frequently. gemini-webapi refreshes it in the background while the server is running and persists the refreshed value to the path in GEMINI_COOKIE_PATH (default: output/.cookies), so in the happy path you only paste cookies once. Chrome's session credentials tend to be shorter-lived than Firefox's; if you find yourself re-pasting often, a dedicated Firefox profile kept signed in to Gemini is a more durable workaround.

Chrome cookies cannot be imported automatically. Since Chrome 127, Windows encrypts its cookie store with app-bound encryption that tools like browser-cookie3 cannot decrypt. There is no shortcut here — copy the two values by hand as above.

These cookies are your account

__Secure-1PSID and __Secure-1PSIDTS are equivalent to being logged in as you. Never commit them, paste them into a chat, or share them with anyone. .env is gitignored by default — keep it that way.

Registering with Claude Code

claude mcp add gemini-image-mcp -- uv run --directory "/path/to/gemini-image-generator-mcp" gemini-image-mcp

(On Windows this might look like uv run --directory "C:\Users\you\projects\gemini-image-generator-mcp" gemini-image-mcp.)

This registers the server to run via the gemini-image-mcp console script that uv sync installs into the project's virtual environment (defined in pyproject.toml's [project.scripts]), always executed from the correct project directory regardless of your current working directory.

Equivalent JSON (e.g. for claude_desktop_config.json or .mcp.json):

{
  "mcpServers": {
    "gemini-image-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/path/to/gemini-image-generator-mcp",
        "gemini-image-mcp"
      ]
    }
  }
}

Tools

Tool

Arguments

Returns

generate_image

prompt: str, model: str | None = None

Absolute path(s) of the newly saved image(s), the absolute path to output/gallery.html, the image count, and the model actually used.

edit_image

prompt: str, image_paths: list[str], model: str | None = None

Same return shape as generate_image, applied to edits of the given source image(s).

list_models

(none)

The models (image/chat) available to the signed-in account, as display name + internal model name/id, so you can pick a non-default model for the other two tools.

None of the tools return base64 image data — the gallery is the intended viewing surface, and every tool result includes its path so you can always click through to it.

Using the core library directly

gemini_image_mcp.core is deliberately MCP-free, so it can be imported directly — for example from a Telegram bot:

from gemini_image_mcp.config import get_settings
from gemini_image_mcp import core

async def handle_image_request(prompt: str) -> None:
    settings = get_settings()
    records = await core.generate_images(prompt, settings=settings)
    for record in records:
        absolute_path = settings.output_dir / record.image_path
        # e.g. send `absolute_path` back to the Telegram chat

Troubleshooting

  • Auth / cookie expirygenerate_image, edit_image, and list_models all raise a clean error naming the exact problem when GEMINI_1PSID/GEMINI_1PSIDTS are missing or have expired. Re-copy both values from Chrome DevTools (see above) and update .env (or the running process's environment).

  • "No images returned" for a prompt that seems reasonable — this is almost always Gemini refusing the request (safety filter, region restriction, age-gating) rather than a bug. The error message includes the model's own text response, which usually explains the refusal directly.

  • Usage limits / temporarily blocked — Gemini's own rate limiting on the web app. Wait before retrying; there is no bypass.

  • Where things live on disk — generated/edited images: output/images/; the gallery: output/gallery.html; the manifest backing the gallery: output/manifest.json; the persisted cookie cache: wherever GEMINI_COOKIE_PATH points (default: output/.cookies). All of output/ is gitignored.

Known limitations

  • Unofficial and fragile by nature. This drives a consumer web app that Google can change at any time without notice; a Google-side change can break this project until it's updated.

  • Region/age gated. Image generation availability depends on your Google account's region and age, not on this project.

  • Output format is whatever Gemini returns. Currently that's typically JPEG, regardless of the extension you might expect — this project sniffs the real format and corrects the file extension accordingly rather than trusting the request.

  • The manifest grows unbounded. output/manifest.json accumulates every record ever generated; there's no pruning or rotation.

  • Not a daemon. The MCP server's lifetime is tied to the Claude session that launched it — it's not designed to run as a standalone, long-lived background service.

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md for the credential-handling model and how to report a vulnerability.

License

MIT — see the disclaimer above for the ToS and warranty caveats specific to this project; the MIT license text itself covers the standard no-warranty terms.

Available Tools

3 tools
edit_imageA

Edit one or more existing local image files using a text instruction.

image_paths must be paths to existing image files on disk (e.g. a photo or a previously generated image) describing what to edit; prompt describes the desired change. The edited image(s) Gemini returns are saved to disk and appended to the cumulative HTML gallery; this tool returns the absolute paths of the new images plus the gallery path so the result can be viewed.

Parameters

prompt: str Instructions describing the desired edit. image_paths: list[str] Paths to existing local image files to edit. model: str | None, optional Model name/alias/id to use (see list_models). Defaults to the server's configured default model, or the account's own default if unset.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo
promptYes
image_pathsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states that edited images are saved to disk and appended to an HTML gallery, and that it returns absolute paths and the gallery path. This covers side effects and return behavior. It does not mention permissions or whether original files are overwritten, but the mention of 'new images' implies non-destructive behavior. Overall, it provides meaningful behavioral context beyond a bare operation.

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 structured with a clear opening sentence, a behavioral summary, and a parameter list. It is slightly verbose but every sentence adds value. The key behavioral facts are front-loaded, and the parameter details are organized for quick reference. It could be tightened slightly, but it is appropriately sized for a tool with three parameters and side effects.

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 complexity (3 params, side effects, output schema), the description covers the essential context: it explains input requirements, the editing process, the return values, and the model selection mechanism. It does not explicitly address file overwrite behavior or permission requirements, but it does state that new images are returned, implying safe handling. The description is sufficient for an agent to call the tool correctly without further lookup.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must fully compensate. It does so by explaining all three parameters: prompt (instructions), image_paths (existing local files), and model (with defaults and reference to list_models). Each parameter is given a clear semantic meaning that goes well beyond the schema's type-only definitions. This is exemplary parameter documentation.

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 ('edit'), a clear resource ('existing local image files'), and the method ('using a text instruction'). It distinguishes from siblings by explicitly requiring existing files, which sets it apart from generate_image and list_models. The purpose 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 Guidelines3/5

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

The description implies usage by requiring 'paths to existing image files' and noting the edited images are saved, but it does not explicitly name alternative tools or state when not to use it. The reference to list_models for the model parameter gives some guidance, but no direct comparison to generate_image is provided. The 'must be paths to existing' hints at a prerequisite but leaves the alternative selection to inference.

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

generate_imageA

Generate one or more new images from a text prompt using the Gemini web app.

The prompt should describe the desired image in as much visual detail as helpful (subject, style, composition, lighting, etc.) - it is sent to Gemini as an image generation request. Newly generated images are saved to disk and appended to the cumulative HTML gallery; this tool returns the absolute paths of the new images plus the gallery path so the result can be viewed.

Parameters

prompt: str A description of the image to generate. model: str | None, optional Model name/alias/id to use (see list_models). Defaults to the server's configured default model, or the account's own default if unset.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo
promptYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure and does so thoroughly. It states that the prompt is sent to Gemini as an image generation request, that generated images are saved to disk and appended to a cumulative HTML gallery, and that the tool returns absolute paths plus the gallery path.

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 well-structured and front-loaded with the core purpose, followed by important side-effect and return information, then parameter details. Every sentence adds meaningful value without unnecessary padding.

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 description covers the essential behavior, side effects, return information, and both parameters. It also points to list_models for model selection, making the tool self-contained and complete for invocation despite the lack of annotations.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate for both parameters, and it does. The prompt parameter is explained with specific visual-detail guidance, and the model parameter is documented with defaults and a pointer to list_models.

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 and resource: generate one or more new images from a text prompt. It clearly distinguishes this from edit_image by emphasizing new image generation from a text prompt, and from list_models by targeting actual image creation.

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 gives clear context for when to use the tool: when a new image should be generated from a text prompt and saved/viewable via the gallery. It does not explicitly name edit_image as the alternative for modifying existing images, so it stops short of full when-to-use vs alternatives guidance.

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

list_modelsA

List the Gemini models (image/chat) available to the currently signed-in account.

Returns each model's display name and internal model name/id, one per line. Use a model_name value from this list as the model argument to generate_image or edit_image to override the default model.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

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?

With no annotations, the description carries the full disclosure burdencluster. It specifies account scoping ('available to the currently signed-in account'), the return contents ('display name and internal model name/id'), and the output format ('one per line'). It could add details about ordering or empty results, but this is a transparent read-only listing.

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 only two sentences, front-loaded with the core purpose, and each sentence earns its place. The first defines the tool; the second details the return format and how to use the result with sibling tools. No unnecessary filler.

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 zero-parameter read-only list tool with an output schema, the description is effectively complete. It covers account scoping, the information returned, output formatting, and the integration path to `generate_image` and `edit_image`. Nothing an agent would need to invoke this tool correctly is missing.

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 and schema coverage is 100%, so there is nothing for the description to clarify about parameters. The baseline for no params is 4; the description appropriately focuses on output semantics and downstream usage instead.

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 begins with 'List the Gemini models (image/chat) available to the currently signed-in account', giving a specific verb, resource, and scope. It also ties the tool to its siblings by stating that its output values are meant for `generate_image` or `edit_image`, differentiating its listing role from those generation tools.

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 states a clear usage context: use the returned `model_name` as the `model` argument for `generate_image` or `edit_image` to override the default. It does not explicitly state when not to use the tool, but with no competing list-style siblings, the guidance is sufficient.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observededit_image
    • First observedgenerate_image
    • First observedlist_models

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: generate new images, edit existing images, and list available models. There is no meaningful overlap between these operations, so an agent can reliably select the right tool.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: generate_image, list_models, edit_image. This creates a predictable and readable naming convention across the entire set.

Tool Count5/5

Three tools is a well-scoped count for an image generation and editing server. Each tool covers a necessary core function without redundancy or unnecessary bloat.

Completeness4/5

The server covers the core image workflow: generating, editing, and choosing models. Minor gaps exist, such as no explicit gallery management or image deletion, but these are not essential to the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers