Gemini Image MCP
by thomijasir
README.md
# Gemini Image MCP

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
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues