Skip to main content
Glama

generate_image

Generate an image from a text prompt via Google Flow.

model — pass ONE of these exact ids (from GET v1/flow/models, verified 2026-07-25):
  NARWHAL      = "Nano Banana 2"      — the DEFAULT, ~30s
  GEM_PIX_2    = "Nano Banana Pro"    — highest quality, ~40s, has a separate DAILY
                                        per-account quota (429 rotates accounts)
  HARBOR_SEAL  = "Nano Banana 2 Lite" — ~40s
Anything else is rejected with HTTP 400 — there is no silent fallback, so a wrong id
wastes a round trip, not credits. Do NOT guess names like "nano_banana_pro": that is
the model FAMILY key from the config, not the id the generate call takes.

image_inputs: mediaIds from prior generations, edit-in-place (keeps them pixel-exact).
control_images: base64 image bytes (no data: prefix) of a locally rendered layout/control
image — uploaded first, then prepended to image_inputs so the generator follows an exact
spatial layout instead of prose. For whole-scene layout control prefer generate_scene.

seed: 1..900000, fixes the generation so the same request returns the same image. Omit
for a random seed. Needed to compare two prompts, two models or two control images
honestly — without it every run is a fresh roll and the difference you are measuring
drowns in noise. Measured 2026-08-09: with an UNCHANGED control image a fixed seed
reproduces the frame to ~0.1%; once the control image changes, the seed no longer keeps
the character — for that use image_inputs with a reference frame's mediaId.

project_id: put the result into a project made with create_project instead of the
account's default one — one project per end client keeps their work separate. Omit it
and nothing changes from before.

include_preview: ON by default since 2026-08-21 — a generated image nobody can see
in the chat is half a result. Pass False to get the plain dict back and nothing else
(worth doing in a loop of many generations, where the previews would fill the
context). When on and the job finished with at least one url, the call returns the
usual result dict, a short card naming the parameters actually used, and a small
compressed JPEG (long side capped at 768px, ~100-160KB once base64-encoded) as an
inline image content block, so a human can actually see the result without leaving
the chat. This is deliberately a shrunk preview, never the original — the real Flow
image is ~0.5MB (~740KB in base64), enough to burn a whole tool call's worth of a
client's context budget on its own. The preview is for EYES ONLY: urls/media_ids
stay the authoritative result in both modes, and every downstream call (upscale_image,
image_inputs edit-in-place, ...) must keep using media_ids, never the preview bytes.
If the preview download/shrink fails for any reason, this silently falls back to the
plain (no-preview) result instead of failing the whole call.

SAVE THE RESULT INTO THE USER'S PROJECT. A finished job also carries `download_urls`
(plain URLs, no auth header needed) and `save_as` (the filenames to use). Unless the
user said otherwise, write them to ./media/<save_as> in their working directory and
tell them the path. The server keeps its own copy, but only the file in their project
is theirs: our copy can be reclaimed when the disk fills, and the URLs expire within
the hour. Downloading costs no credits and no quota.

Returns {"urls": [...], "media_ids": [...]} when done, or a job_id to poll
with check_job if it's not ready within ~60s (rare for images unless the
device is cold). With the default include_preview=True and a finished result,
returns [that dict, <card>, <inline image>] instead — see include_preview above.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
seedNo
modelNoNARWHAL
aspectNoIMAGE_ASPECT_RATIO_LANDSCAPE
promptYes
project_idNo
image_inputsNo
control_imagesNo
include_previewNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare readOnlyHint=false and openWorldHint=true, and the description adds substantial behavioral detail: it writes files to the user's project, URLs expire within the hour, the preview silently falls back on failure, and GEM_PIX_2 has a separate daily quota. No contradiction with annotations.

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 long but well-structured with distinct paragraphs per parameter and a front-loaded core (purpose and model selection). Every sentence adds value – model details, preview fallback, and saving instructions are not redundant. It balances detail with organization.

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 an 8-parameter tool with no output schema and minimal annotations, the description covers return dicts, job polling, fallback behavior, file saving, and quota notes. The only omission is aspect, which is covered by the schema enum. Nothing critical is missing for correct invocation.

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?

With schema description coverage at 0%, the description compensates thoroughly: it explains model as exact IDs with defaults and rejection behavior, seed range and purpose, image_inputs and control_images encoding, project_id usage, and include_preview behavior. Only aspect is left to the schema's enum and default, a minor gap.

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 opens with 'Generate an image from a text prompt via Google Flow' – a precise verb, resource, and input. It distinguishes itself from a key sibling by explicitly naming generate_scene as the preferred tool for whole-scene layout control, so the agent can tell when this tool is the right one.

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 operational guidance: when to use a fixed seed for comparisons, when to use control_images, and the explicit direction 'For whole-scene layout control prefer generate_scene.' However, it does not systematically contrast with all image-generation siblings (e.g., generate_character_image), so exclusions are only partial.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.