Skip to main content
Glama
README.md
# nanobanana-mcp

An [MCP](https://modelcontextprotocol.io) server for Google's Gemini image models — the **"Nano Banana"** family. It exposes image generation, image editing/composition, and a curated set of prompt templates as MCP tools, prompts, and resources, and works with **any** of Gemini's three credential paths.

> **Note on naming:** Vertex AI was rebranded to the **Gemini Enterprise Agent Platform** in April 2026. The underlying APIs and credentials are unchanged — this README uses "Vertex AI" and "Agent Platform" interchangeably.

## Features

- 🎨 **Multi-Model AI Image Generation** — three Gemini models with intelligent automatic selection
  - 🍌 **Gemini 3.1 Flash Image (Nano Banana 2)** — default model: up to 4K resolution at Flash speed, with Google Search grounding
  - 🏆 **Gemini 3 Pro Image (Nano Banana Pro)** — maximum reasoning depth for the most complex compositions
  - ⚡ **Gemini 2.5 Flash Image (legacy)** — the original Flash model, for high-volume rapid prototyping
- 🤖 **Smart Model Selection** — when you don't pin a model, a transparent, explainable heuristic routes each prompt to Nano Banana 2 or Nano Banana Pro (never the legacy model) based on prompt complexity, and tells you why
- 📐 **Aspect Ratio & Resolution Control** — `1:1`, `16:9`, `9:16`, `21:9`, and 7 more, plus `512`/`1K`/`2K`/`4K` output sizes
- 📋 **Smart Templates** — 10 curated prompt templates for photography, design, and editing, available as native MCP Prompts *and* as plain tools for clients without a prompt-picker UI
- 🔍 **Resource Discovery** — browse the template catalog and metadata for every image you've saved to disk through MCP Resources
- 🖼️ **Image Editing & Composition** — up to 14 reference images, by local file path or inline base64
- 🔑 **Three Auth Modes** — Gemini API key, Vertex AI Express Mode API key, or full ADC — auto-detected from environment variables
- 🛡️ **Production Ready** — every tool call is wrapped in structured error handling; all logging goes to stderr (stdout is reserved for the JSON-RPC wire); startup fails fast with an actionable message if credentials are missing or contradictory
- ⚡ **High Performance** — a TTL/LRU response cache serves identical repeated requests (retries, accidental duplicates) from memory instead of re-billing the API

## Requirements

- Node.js **20+**
- One of: a [Gemini API key](https://aistudio.google.com/apikey), a Vertex AI Express Mode API key, or a Google Cloud project with Application Default Credentials

## Installation

**From npm (recommended)** — no local install step needed. Every client config below uses `npx -y @amit-y11/nanobanana-mcp`, which downloads and runs the latest published version on demand.

**From source** — for local development or before the package is published:

```bash
git clone https://github.com/amit-y11/nanobanana-mcp.git
cd nanobanana-mcp
npm install
npm run build
```

This produces `build/index.js`, a self-contained stdio MCP server. If you're running from source, swap `"command": "npx", "args": ["-y", "nanobanana-mcp"]` in every config below for `"command": "node", "args": ["/ABSOLUTE/PATH/TO/nanobanana-mcp/build/index.js"]`.

## Authentication

Pick **one** of the three modes. `nanobanana-mcp` auto-detects which one you've configured; set `NANOBANANA_AUTH_MODE` to force a specific mode and get a precise error if it's misconfigured, instead of silently falling through to another mode.

| Mode | Env vars | Notes |
| --- | --- | --- |
| **1. Gemini Developer API** | `GEMINI_API_KEY` | Simplest option. Get a key at [aistudio.google.com/apikey](https://aistudio.google.com/apikey). |
| **2. Vertex AI Express Mode** | `GOOGLE_GENAI_USE_VERTEXAI=true`<br>`VERTEX_API_KEY` | An API key that talks to Vertex AI / Agent Platform without a full GCP project. |
| **3. Vertex AI with ADC** | `GOOGLE_GENAI_USE_VERTEXAI=true`<br>`GOOGLE_CLOUD_PROJECT`<br>`GOOGLE_CLOUD_LOCATION` | Needs a real GCP project. Credentials come from `GOOGLE_APPLICATION_CREDENTIALS` (a service account JSON key), `gcloud auth application-default login`, or an attached service account when running on GCP compute — whichever is available. |

`GOOGLE_API_KEY` is also accepted as a fallback for either key-based mode (matching the underlying Google SDK's own conventions); `VERTEX_API_KEY` exists so you can keep a Gemini key and a Vertex key configured side by side without one silently shadowing the other.

Call the `auth_status` tool at any time to see which mode is active (secrets are masked).

See [`.env.example`](./.env.example) for the full list of variables, including optional ones (default model, output directory, log level, cache settings).

## Available tools

| Tool | Purpose |
| --- | --- |
| `generate_image` | Text-to-image generation. |
| `edit_image` | Edit, inpaint, restyle, or compose 1–14 reference images (file path or base64). |
| `list_models` | The 3 supported models, their aliases, and capabilities. |
| `list_templates` | The prompt-template catalog (see below). |
| `render_template` | Fill a template's fields and get back a ready-to-use prompt. |
| `auth_status` | Which credential mode is active, and cache stats. |

Both `generate_image` and `edit_image` accept: `model` (id, alias, or `"auto"`), `aspect_ratio`, `image_size`, `person_generation`, `thinking_level`, `use_search_grounding`, `save_to_file`, `output_path`.

### Smart model selection

Leave `model` unset (or pass `"auto"`) and the server scores the prompt — length, design/text-rendering keywords ("logo", "infographic", "poster", quoted text to render, reference-image count) against "make it quick/rough/simple" signals — and routes to **Nano Banana 2** or **Nano Banana Pro** accordingly. The response always states which model was picked and why, e.g.:

> Auto-selected model: Nano Banana Pro (score 3/3): mentions logo; requires exact quoted text to be rendered.

The legacy model is never auto-selected — ask for it explicitly (`model: "legacy"`) when you specifically want it.

### Prompt templates

Ten templates, adapted from Google's own Gemini prompting guide, across three categories:

- **Photography** — `photo_realistic_scene`, `product_mockup`
- **Design** — `logo_design`, `sticker_illustration`, `infographic`, `minimalist_negative_space`
- **Editing** — `add_remove_element`, `inpaint_replace`, `style_transfer`, `combine_images`

They're available three ways, so every client can use them:

1. **MCP Prompts** (`prompts/list` / `prompts/get`) — Claude Desktop and Claude Code show these in their prompt picker / slash-command menu with full argument validation.
2. **Resources** — `template://catalog` (the whole catalog as JSON) and `template://{category}/{id}` per template, for clients that only browse resources.
3. **Tools** — `list_templates` to browse, `render_template` to fill one in and get back a prompt string to feed into `generate_image`/`edit_image`. This path works in any MCP client, including ones without prompt or resource UI.

### Resources

| URI | Contents |
| --- | --- |
| `template://catalog` | All templates, as JSON. |
| `template://{category}/{id}` | One template's fields and description. |
| `generated-image://recent` | Metadata for images saved to disk this session (most recent first). |
| `generated-image://{id}` | One saved image's model, prompt, path, size, and whether it was auto-selected. |

The `generated-image://*` resources only cover images actually written to disk (see `save_to_file` / `NANOBANANA_OUTPUT_DIR` below) — there's nothing durable to browse for an inline-only result, and the manifest itself is in-memory and resets when the server restarts.

### Saving images to disk

By default, generated images are returned inline (base64) and **not** written to disk. To save them:

- Set `NANOBANANA_OUTPUT_DIR` to a directory — every generation is saved there automatically, or
- Pass `save_to_file: true` (and optionally `output_path`) on a specific call.

Saved images are also indexed in the `generated-image://` resources above.

## Connecting to MCP clients

All examples below use `npx -y @amit-y11/nanobanana-mcp` (the published package) and the Gemini API key mode for brevity. To use a different auth mode, swap the `env` block for the one shown in [Authentication](#authentication) — everything else about each config stays the same. Running from a local clone instead? See the note at the end of [Installation](#installation).

### Claude Desktop

Edit your config file (create it if it doesn't exist):

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%AppData%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "nanobanana": {
      "command": "npx",
      "args": ["-y", "@amit-y11/nanobanana-mcp"],
      "env": {
        "GEMINI_API_KEY": "your-gemini-api-key"
      }
    }
  }
}
```

Restart Claude Desktop fully (not just the window) afterwards.

### Claude Code

Either run:

```bash
claude mcp add --transport stdio --env GEMINI_API_KEY=your-gemini-api-key \
  nanobanana -- npx -y @amit-y11/nanobanana-mcp
```

or add it directly to `.mcp.json` (project scope) or `~/.claude.json` (user scope, under `mcpServers`) using the same shape as the Claude Desktop config above. Verify with `claude mcp list` / the `/mcp` command.

### VS Code (GitHub Copilot)

Create `.vscode/mcp.json` in your workspace (or use **MCP: Open User Configuration** for a global config). VS Code requires an explicit `"type"` field and uses `servers`, not `mcpServers`:

```json
{
  "servers": {
    "nanobanana": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@amit-y11/nanobanana-mcp"],
      "env": {
        "GEMINI_API_KEY": "your-gemini-api-key"
      }
    }
  }
}
```

### Cursor

Create `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):

```json
{
  "mcpServers": {
    "nanobanana": {
      "command": "npx",
      "args": ["-y", "@amit-y11/nanobanana-mcp"],
      "env": {
        "GEMINI_API_KEY": "your-gemini-api-key"
      }
    }
  }
}
```

Restart Cursor afterwards.

### OpenAI Codex (CLI and IDE extension)

Codex uses TOML, shared between the CLI and the IDE extension, at `~/.codex/config.toml` (or a project-scoped `.codex/config.toml` for trusted projects):

```toml
[mcp_servers.nanobanana]
command = "npx"
args = ["-y", "@amit-y11/nanobanana-mcp"]

[mcp_servers.nanobanana.env]
GEMINI_API_KEY = "your-gemini-api-key"
```

Or via the CLI:

```bash
codex mcp add nanobanana --env GEMINI_API_KEY=your-gemini-api-key \
  -- npx -y @amit-y11/nanobanana-mcp
```

Run `/mcp` inside a Codex session afterwards to confirm it's connected.

> **Windows note:** `npx` on Windows sometimes needs the `.cmd` shim — if a client can't spawn it, try `"command": "npx.cmd"` (or the full path from `where npx`).

## Development

```bash
npm run dev       # tsc --watch
npm run build     # one-off build
npm run inspect   # build, then open the MCP Inspector against the built server
```

[MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) is the fastest way to poke at tools/resources/prompts by hand without wiring up a full client.

### Logging

Everything is logged to **stderr only** — on the stdio transport, stdout is the JSON-RPC wire, and anything else written there corrupts every message after it. Set `NANOBANANA_LOG_LEVEL=debug` for more detail (cache hits, etc.).

## Troubleshooting

- **"No credentials found" on startup** — you haven't set any of the three auth modes' variables. Check `.env.example` and the table above.
- **"NANOBANANA_AUTH_MODE=... requires ..."** — you forced a mode with `NANOBANANA_AUTH_MODE` but didn't set that mode's required variables.
- **Server doesn't show up in your client** — confirm the path in `args` is absolute, that you ran `npm run build` (the client runs `build/index.js`, not `src/index.ts`), and restart the client fully.
- **Call `auth_status`** to confirm which credential mode is active and see basic cache stats without leaving your MCP client.

## License

MIT — see [LICENSE](./LICENSE).

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: generate vs edit operate on different inputs/outputs, list_models and list_templates target different resource types, render_template produces a prompt while generate_image/edit_image consume it, and auth_status is uniquely diagnostic. No pair of tools appears to do the same thing.

Naming Consistency4/5

Five of six names follow a readable verb_noun snake_case pattern (generate_image, edit_image, list_models, list_templates, render_template). auth_status is a minor deviation as a noun_noun, but remains clear and consistent in casing style.

Tool Count5/5

Six tools is well-scoped for an image generation/editing server with model selection, templates, and auth diagnostics. Each tool earns its place, and the set avoids both thinness and bloat.

Completeness4/5

The core lifecycle is covered: generating, editing, listing models, listing/rendering templates, and checking auth. Minor gaps include no explicit tool for history, batch operations, or inspecting saved outputs, but these are workable around or outside the server's core scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues