generate_image
Generate images using Google Gemini and save to a specified file path. Automatically resolves filename conflicts by appending a numeric suffix.
Instructions
Generate an image with Gemini and save it to output_path.
Known model values (override via model):
gemini-2.5-flash-image (default — Nano Banana, fastest/cheapest)
gemini-3.1-flash-image-preview (Nano Banana 2, higher quality)
gemini-3-pro-image-preview (Nano Banana Pro, top quality)
If output_path already exists, a numeric suffix is appended (foo.png -> foo-1.png) and the final path is returned.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | ||
| output_path | Yes | ||
| model | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/nano_banana_mcp/server.py:24-24 (registration)The @mcp.tool() decorator registers 'generate_image' as an MCP tool on the FastMCP server instance.
@mcp.tool() - src/nano_banana_mcp/server.py:25-68 (handler)The main handler function that takes a prompt, output_path, and optional model, generates an image using Google's Gemini API (genai), extracts the image bytes from the response, and writes them to disk. Handles file collision by appending a numeric suffix and returns the final path.
def generate_image(prompt: str, output_path: str, model: str | None = None) -> str: """Generate an image with Gemini and save it to output_path. Known model values (override via `model`): - gemini-2.5-flash-image (default — Nano Banana, fastest/cheapest) - gemini-3.1-flash-image-preview (Nano Banana 2, higher quality) - gemini-3-pro-image-preview (Nano Banana Pro, top quality) If output_path already exists, a numeric suffix is appended (foo.png -> foo-1.png) and the final path is returned. """ api_key = os.environ.get("GEMINI_API_KEY") if not api_key: raise RuntimeError("GEMINI_API_KEY is not set in the MCP server environment.") target = Path(output_path).expanduser().resolve() target.parent.mkdir(parents=True, exist_ok=True) final = _resolve_collision(target) client = genai.Client(api_key=api_key) response = client.models.generate_content( model=model or DEFAULT_MODEL, contents=prompt, ) image_bytes = None for part in response.candidates[0].content.parts: inline = getattr(part, "inline_data", None) if inline and inline.data: image_bytes = inline.data break if image_bytes is None: text_parts = [ p.text for p in response.candidates[0].content.parts if getattr(p, "text", None) ] raise RuntimeError( f"No image in response. Model said: {' '.join(text_parts) or '(empty)'}" ) final.write_bytes(image_bytes) note = "" if final == target else f" (renamed from {target.name} to avoid overwrite)" return f"wrote: {final}{note}" - src/nano_banana_mcp/server.py:7-7 (helper)Default model constant used when no model override is provided.
DEFAULT_MODEL = "gemini-2.5-flash-image" - src/nano_banana_mcp/server.py:12-21 (helper)Helper function _resolve_collision that appends a numeric suffix (e.g., -1, -2) to avoid overwriting existing files.
def _resolve_collision(path: Path) -> Path: if not path.exists(): return path stem, suffix, parent = path.stem, path.suffix, path.parent i = 1 while True: candidate = parent / f"{stem}-{i}{suffix}" if not candidate.exists(): return candidate i += 1