Skip to main content
Glama
README.md
# Gemini Image MCP

![Gemini Image MCP Banner](banner.jpg)

An [MCP](https://modelcontextprotocol.io) server for generating and editing
images with Google's Gemini image models (Nano Banana, Nano Banana 2, Nano
Banana Pro). It exposes one tool, `generate_image`, which AI tools like Claude,
Codex, and Cline can call using your own API key.

## What it does

- `generate_image` handles text-to-image, plus editing and composition when you
  pass it reference images (local file paths or base64).
- Every generation knob is exposed per call: `temperature` (1), `topP` (0.95),
  `topK`, `maxOutputTokens` (65536 for flash/lite, 32768 for pro), `seed`,
  `stopSequences`, `presencePenalty`, `frequencyPenalty`, `systemInstruction`,
  `thinkingLevel` (minimal/high), `thinkingBudget`, `enableGoogleSearch`
  (default true), `imageSize` (512/1K/2K/4K), `aspectRatio` ("auto" default +
  standard ratios), `personGeneration`.
- Ships an `instructions` block and per-parameter descriptions, so MCP clients
  figure out how to use the tool without extra prompting.
- Saves images to disk and returns file paths. No base64 in the response, so a
  4K image won't eat the client's context window.
- Errors come back with hints (bad key, rate limit, safety block, unknown model)
  instead of a raw API dump.
- stdio transport, the usual setup for local MCP servers.

## Requirements

- [Bun](https://bun.com) 1.0+
- A Gemini API key from <https://aistudio.google.com/apikey>

## Install

```bash
bun install
```

## Configuration

Three environment variables, normally set in the MCP client's config:

| Variable                  | Required                  | Default                  | What it does                                                 |
| ------------------------- | ------------------------- | ------------------------ | ------------------------------------------------------------ |
| `GEMINI_API_KEY`          | Yes (or `GOOGLE_API_KEY`) |                          | Your Gemini API key. If both are set, `GEMINI_API_KEY` wins. |
| `GEMINI_IMAGE_MODEL`      | No                        | `gemini-3.1-flash-image` | Model used when a call doesn't specify one.                  |
| `GEMINI_IMAGE_OUTPUT_DIR` | No                        | `<cwd>/generated-images` | Where images go. Created if it doesn't exist.                |

Models you can pick:

| Model                         | Max Output Tokens | Thinking Level | Google Search | Max Size | Notes                                                                           |
| ----------------------------- | ----------------- | -------------- | ------------- | -------- | ------------------------------------------------------------------------------- |
| `gemini-3.1-flash-image`      | 65536             | minimal / high | Supported     | 2K       | Nano Banana 2. Fast, cheap, general purpose. The default.                       |
| `gemini-3.1-flash-lite-image` | 65536             | minimal / high | Supported     | 2K       | Lightweight, high-throughput model.                                             |
| `gemini-3-pro-image`          | 32768             | _(none)_       | Supported     | 4K       | Nano Banana Pro. Best quality and in-image text, and the only one that does 4K. |

Models can also be specified with the `models/` prefix (e.g.
`models/gemini-3.1-flash-image`).

## Client setup

### Claude Desktop

Add this to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "gemini-image": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/gemini-image-mcp/index.ts"],
      "env": {
        "GEMINI_API_KEY": "YOUR_KEY_HERE"
      }
    }
  }
}
```

### Cline (VS Code)

`cline_mcp_settings.json`:

```json
{
  "mcpServers": {
    "gemini-image": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/gemini-image-mcp/index.ts"],
      "env": {
        "GEMINI_API_KEY": "YOUR_KEY_HERE"
      }
    }
  }
}
```

### Codex

`~/.codex/config.toml`:

```toml
[mcp_servers.gemini-image]
command = "bun"
args = ["run", "/absolute/path/to/gemini-image-mcp/index.ts"]
env = { GEMINI_API_KEY = "YOUR_KEY_HERE" }
```

### From npm (bunx/npx)

Once the package is published, point your client at bunx instead:

```json
{
  "mcpServers": {
    "gemini-image": {
      "command": "bunx",
      "args": ["gemini-image-mcp"],
      "env": { "GEMINI_API_KEY": "YOUR_KEY_HERE" }
    }
  }
}
```

## `generate_image` parameters

Only `prompt` is required. Everything else defaults to something sensible for
image generation.

| Parameter                              | Type                            | Default                        | Description                                                                                                                                                                          |
| -------------------------------------- | ------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `prompt`                               | string                          | — _(required)_                 | Narrative description of the image, or of the edit when `referenceImages` are provided.                                                                                              |
| `model`                                | string                          | env / `gemini-3.1-flash-image` | Gemini image model (see table above). Accepts `models/` prefix.                                                                                                                      |
| `referenceImages`                      | array (≤14)                     | —                              | Source images for editing/composition: `{ path }` or `{ base64, mimeType }`.                                                                                                         |
| `imageSize`                            | `"512" \| "1K" \| "2K" \| "4K"` | `"1K"`                         | Output resolution: 512 (fastest, lightweight), 1K (default), 2K, 4K (requires `gemini-3-pro-image`).                                                                                 |
| `aspectRatio`                          | enum                            | `"auto"`                       | `"auto"` (default, infers from prompt or matches reference images) or explicit: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`, `1:4`, `4:1`, `1:8`, `8:1`. |
| `personGeneration`                     | enum                            | `allow_all`                    | `allow_all` / `allow_adult` / `allow_none`.                                                                                                                                          |
| `thinkingLevel`                        | enum                            | `"minimal"` (on flash models)  | `"minimal"` / `"high"`. Supported on `gemini-3.1-flash-image` and `gemini-3.1-flash-lite-image`. Not supported on Pro.                                                               |
| `enableGoogleSearch`                   | boolean                         | `true`                         | Enables Google Search grounding tool for real-time web knowledge and accuracy across all models.                                                                                     |
| `thinkingBudget`                       | int                             | —                              | Explicit thinking budget (0 = off, -1 = auto).                                                                                                                                       |
| `temperature`                          | number 0–2                      | `1`                            | Sampling randomness.                                                                                                                                                                 |
| `topP`                                 | number 0–1                      | `0.95`                         | Nucleus sampling.                                                                                                                                                                    |
| `topK`                                 | int                             | —                              | Top-k sampling.                                                                                                                                                                      |
| `maxOutputTokens`                      | int 1–65536                     | 65536 (flash) / 32768 (pro)    | Output token cap.                                                                                                                                                                    |
| `seed`                                 | int                             | —                              | Best-effort reproducibility.                                                                                                                                                         |
| `stopSequences`                        | string[] (≤5)                   | —                              | Stop sequences for the text portion.                                                                                                                                                 |
| `presencePenalty` / `frequencyPenalty` | number -2..2                    | —                              | Token penalties.                                                                                                                                                                     |
| `systemInstruction`                    | string                          | —                              | Style/behavior steering, e.g. "flat vector style".                                                                                                                                   |
| `outputDir`                            | string                          | env / `<cwd>/generated-images` | Where to save.                                                                                                                                                                       |
| `fileName`                             | string                          | `gemini-image-<timestamp>`     | Base file name (extension auto from MIME type).                                                                                                                                      |

The tool returns a text summary with the saved file path(s), the model, the
effective config, and token usage. It never returns image data inline; open the
file to see the result.

### Things you can ask your AI

- _"Generate a 16:9 hero image of a rainy Tokyo street at night, cinematic neon
  lighting."_
- _"Edit `/tmp/product.png`: put it on a marble table with soft morning light"_
  (this uses `referenceImages`).
- _"Generate a 4K poster with the exact headline 'LAUNCH DAY' using
  gemini-3-pro-image."_

## Development

```bash
bun test              # unit tests (config, schema, request/response parsing)
bun run typecheck     # tsc --noEmit
bun run inspector     # interactive MCP inspector (needs GEMINI_API_KEY)
bun run start         # run the server on stdio
```

## Troubleshooting

- **"Missing Gemini API key"**: put `GEMINI_API_KEY` in the `env` block of the
  client's MCP config. Setting it in your shell isn't enough for GUI apps like
  Claude Desktop, since they don't read your shell environment.
- **Safety blocks**: rephrase the prompt. If people are involved, check
  `personGeneration`.
- **429 / quota exceeded**: wait and retry, or stick to
  `gemini-3.1-flash-image`, which has the higher quota.
- **Logs**: the server writes logs to stderr only. stdout carries the MCP
  protocol, so don't add `console.log` anywhere.

## Author

Thomi Jasir <dev@venobi.com>

## License

MIT