gemini-mcp
This MCP server provides a suite of tools for media generation and management using Google Gemini models. You can:
List available image generation models and see the active default.
Generate images from text prompts with control over size, aspect ratio, seed, model, and search grounding, and reference images via URLs, Files API, local paths, or base64.
Edit or compose images by applying text-driven edits or merging multiple images.
Create consistent image sets with a master image plus variations or themed scenes.
Iteratively refine images through multi-turn editing with the Interactions API, chaining edits and recovering from errors.
Generate short videos from text, images, or existing videos using the Omni model, with async support.
Compose music clips from text prompts (mood, genre, instruments) with Lyria models, outputting MP3 or WAV.
Run long generations asynchronously and poll for results to avoid timeouts.
Upload, list, and delete files in the Gemini Files API for reusable references (48h expiry).
Sign media URLs (for hosted connectors) to refresh expired links.
Use idempotency keys to safely retry timed-out calls.
Write output to disk or receive it inline as base64.
All generation tools support async mode, multiple input methods, and progress heartbeats to keep connections alive.
Provides tools for interacting with Google Gemini's media generation API, enabling image generation/editing, video generation, music generation, and file management through the Gemini platform.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gemini-mcpgenerate an image of a cat wearing a hat"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
gemini-mcp
MCP server for Google Gemini media generation. Exposes eleven tools to Claude over stdio: list available models, generate/edit/compose images, generate a consistent set of images from a master prompt, multi-turn image refinement (Interactions API), video generation (omni), music generation (Lyria), an async result poll for long generations, and Files API upload/list/delete for reusable image references. Output is written to disk by default (path returned) or returned inline as base64. Built on the Gemini v1beta API (generativelanguage.googleapis.com) using the Nano Banana / Nano Banana Pro (images), omni (video), and Lyria (music) model families.
Developed and maintained by AI (Claude Code).
Environment Variables
Variable | Required | Description |
| Yes | Your Google Gemini API key (aistudio.google.com/apikey) |
| No | Override the default image model (default: |
| No | Default directory for generated images (default: current working directory) |
| No | Directory to resolve bare input-image filenames against (so |
| No | Upstream request timeout in ms (default: |
| No | Progress-notification cadence in ms while a generation runs (default: |
| No | How long to wait out interactions-store lag when a chained call 404s (default: |
Long generations and client timeouts
4K / Pro-model generations can outrun an MCP host's own tools/call timeout (error -32001).
The server sends notifications/progress heartbeats so hosts that reset their timeout on
progress wait it out. If the host still gives up, the server-side generation usually completes
anyway: the image is written to the output dir, gemini_interact also writes an
<image>.json sidecar recording the interaction_id, and continue_last: true resumes the
interaction the lost response belonged to.
When a chained call 404s
A 404 on a request carrying previous_interaction_id is not proof the chain expired. The
only 404 body observed live is generic — "Requested entity was not found." — and never names
which entity. An unknown or renamed model id, and an expired Files API files/… uri
(~48h TTL), return exactly the same thing. So the server no longer asserts a cause it can't
establish: the upstream text is surfaced verbatim, and gemini_interact runs an experiment to
find out which it was.
Most often the id isn't missing at all — it just isn't visible yet. The interactions store is
eventually consistent, and a freshly created id can 404 while the same id resolves fine minutes
later; heavy turns (4K, Pro, thinking_level: high) are the likeliest to hit it, which is
exactly the turn you most want to chain from. So a chained 404 is retried with exponential
backoff for up to 120s (GEMINI_CHAIN_RETRY_MS) before anything is declared broken. The
404 generates nothing and isn't billed, so the wait costs only time.
After that budget is spent, the tool looks up that id's sidecar, re-attaches the image it produced, and re-issues the request without the chain:
The re-issue succeeds → the chain really was the problem, and you get your image anyway, reported as
chain_recovered: { expired_interaction_id, reanchored_on }. The 404'd attempt generates nothing, so this costs the one generation you'd have paid for re-anchoring manually.The re-issue 404s too → the interaction id was never the cause. You get told exactly that, with the upstream text, and pointed at the model id and any
files/…uri instead of being sent to chase an interaction that was fine all along.No sidecar matches the dead id → the original error, rather than a guess. Re-anchoring on the wrong picture would silently corrupt the edit.
Separately, continue_last no longer dies with the server process: with no in-memory id it
resumes from the newest <image>.json sidecar in the output dir and reports
continued_from_sidecar: true. That case was never an expired chain at all — the interaction
was alive upstream the whole time; only our memory of its id was gone.
For hosts whose timeout can't be tamed (e.g. Claude Desktop, a fixed ~30s cap that ignores progress), two guards make re-issuing safe and unnecessary:
async: truereturns ajob_idimmediately instead of the image, so the call can't time out at all; pollgemini_get_resultwith thejob_iduntil it'sdone.idempotency_keymakes a repeat call idempotent — a retry with the same key returns the recorded result (reused: true) instead of billing a second generation. (Even without a key, two identical in-flight calls are deduplicated automatically.)
Related MCP server: mmxomni
Tools
Tool | Description |
| List available Gemini image models and the current default |
| Generate image(s) from a text prompt |
| One-off edits or multi-image composition with a text instruction (for a series of edits, use |
| Generate a master image plus N consistent images referencing it |
| Preferred tool for iterative refinement: multi-turn generation/editing via the Interactions API — chain the returned |
| Generate a short video (text→video, image→video, or |
| Generate music from a text prompt via a Lyria model — |
| Fetch an async generation started with |
| Token usage and an estimated USD cost for this session so far. Call it before and after a workflow and subtract to attribute that workflow's spend. Priced per call against each call's own model from a dated rate card ( |
| Upload an image (or video/audio) to the Gemini Files API once — from a |
| List the files currently uploaded under this API key, with MIME types and expiry times |
| Delete an uploaded file before its ~48h expiry (confirm-gated) |
| (hosted deployments only) Mint a fresh signed URL for generated media from its |
| (hosted deployments only) Mint a short-lived signed PUT URL so a shell can upload a reference image with no auth header; the PUT returns an |
| (hosted deployments only) Persistent per-account character library: save a reference image + description under a name, then pass |
| (hosted deployments only) Persistent per-account style presets: a reusable prompt fragment (optionally with a reference image), applied by passing |
Generation tools also share three throughput/latency controls: async: true (return a job_id
immediately), max_wait_ms (wait up to a budget, then hand back the job_id — fast results stay
in-band, slow batches never trip the host timeout), and idempotency_key (a retry returns the
recorded result instead of re-billing). On a hosted deployment, a gemini_image_set result with
more than one image also carries a bundle_url — one signed URL for a zip of every image in
the set — and set links are signed for ~7 days instead of the default ~48h. (A set too large to
zip safely in memory skips the bundle and says so via bundle_skipped; the per-image
links are unaffected.)
Seeing your images (hosted)
On a hosted deployment there is no filesystem, so a generated image has to come back as something you can open. It does: every result includes a URL, with no configuration.
{
"images": ["https://mcp.nullnet.app/b/<account>/gemini/gen/2026-07-29/ab12cd34-a-cat.png?exp=…&sig=…"],
"media": [{ "url": "https://…", "r2_key": "gen/2026-07-29/ab12cd34-a-cat.png",
"expires_at": "2026-07-31T12:00:00.000Z",
"curl_hint": "curl -sS -o a-cat.png \"https://…\"" }]
}Those links need no auth header — the signature is in the URL — so they work in a browser, in
curl, and in a chat message. They expire (48h by default) and the objects behind them are
swept on a retention schedule. The r2_key is the durable handle for that window:
gemini_sign_media(hosted deployments only) mints a fresh signed URL from anr2_key, so an expired link never forces you to re-generate — and re-pay for — the image.gemini_upload_filewithr2_keyturns media this server generated into a Files API reference (the server reads it back with its own key — no signature for you to mint), so a generated image can become the reference image for the next generation in one cheap call.Idempotent replays (
idempotency_key) re-mint the URLs inside the recorded result before returning it, so a reused result never carries a dead link.
Why this matters: MCP's inline image content blocks (inline: true) are visible to the
assistant but many chat clients never render them to the user, and the assistant cannot
extract bytes back out of its own context to save them elsewhere. A generation could bill
successfully and be invisible. A URL is the portable answer; inline remains available, but
it is no longer the only way to receive media.
How the bytes are served
The host stores each generated object and serves it back at a signed, expiring
URL — https://<host>/b/<account>/gemini/<key>?exp=&sig=. No setup, and no auth
header: the signature in the link is the authorization, so curl and a browser
both work.
Auth is a signed, expiring URL rather than an unlisted key. Random keys would
be simpler, but they never expire and never revoke: anything that ever logged or forwarded the
link keeps working forever. A signature scopes access to one object with a deadline, and
rotating MEDIA_URL_SECRET invalidates every outstanding link at once. The tradeoff is that
links are long and cannot be shortened by hand.
For assistants relaying a result
Show the user the URL. If your sandbox has network egress to the host, fetching it
and attaching the bytes as a file gives the nicest result; otherwise present the link itself.
Whether a given client renders  markdown inline varies by client — a bare URL is the
safe form, and a markdown link is a reasonable enhancement where you know it renders.
Retention
Variable | Default | Effect |
|
| Objects older than this are deleted by a daily cron — generated media ( |
| generated | HMAC key for |
Signed-URL lifetime is clamped to MEDIA_TTL_DAYS, so a link never outlives the object it
points at.
Sending reference images without burning context
Every tool that takes a reference image — gemini_image_generate, gemini_image_edit,
gemini_image_set, gemini_interact, plus gemini_video_generate (reference stills) and
gemini_music_generate — accepts them four ways. Only one of them costs model context:
Parameter | Where the bytes travel | Context cost |
| the server downloads the https URL | none |
| a | none |
| the server reads its own store (hosted deployments only) | none |
| read off local disk (stdio builds only) | none |
| saved library entries, attached by name (hosted deployments only) | none |
| through the tool-call JSON | ~14k tokens per JPEG |
images_base64 is the fallback of last resort. It costs roughly 14k tokens per modest photo,
and it is silently corrupted whenever the file read that produced it was truncated — the
payload still looks like base64, so the failure surfaces as a bad generation rather than an
error. Prefer any of the other three.
images_url — the server fetches it
{ "prompt": "make it look like winter", "images_url": ["https://example.com/photo.jpg"] }Fetches are restricted to public https:// URLs — private, loopback and link-local hosts are
refused (IPv6 literals are parsed, so [::ffff:7f00:1] is caught as loopback), every redirect
hop is revalidated, and each hop is bounded by a timeout. The response must be
Content-Type: image/* and is capped at 15MB, enforced while streaming rather than trusted
from Content-Length. A failure names the offending URL. Anything over 6MB is uploaded to the
Files API and referenced by uri instead of inlined, since generateContent caps a whole
request near 20MB.
images_file_uris — upload once, reference many times
// 1. upload
{ "tool": "gemini_upload_file", "url": "https://example.com/photo.jpg" }
// → { "file_uri": "files/abc123", "mime_type": "image/jpeg", "expires": "..." }
// 2. reference it, as many times as you like
{ "prompt": "make it winter", "images_file_uris": ["files/abc123"] }
{ "prompt": "make it sunrise", "images_file_uris": ["files/abc123"] }Uploads are retained ~48h; after that the reference stops resolving (as a generic 404 —
see the chained-404 section above). gemini_image_set fetches or resolves such a reference
once and passes it to the master and every scene call.
On stdio builds, a local images path that gets referenced more than once in a session is
uploaded to the Files API automatically (keyed on path + mtime + size), so repeated edits of
the same photo stop re-sending the bytes. Editing the file invalidates the cached upload.
Signed upload URLs — no token at all (hosted)
This is the intended path for an agent with a shell: disk file → curl → r2_key → tool call,
with the image never entering the conversation. gemini_get_upload_url mints a short-lived
(~10 min) signed PUT URL, and the shell uploads with zero auth headers — the signature in
the URL is the authorization, mirroring how the download links work.
# 1. tool call: gemini_get_upload_url { filename: "photo.jpg", content_type: "image/jpeg" }
# → { upload_url, r2_key, expires_at, curl_hint }
# 2. shell:
curl -sS -X PUT -H "Content-Type: image/jpeg" --data-binary @photo.jpg "$UPLOAD_URL"
# → { "r2_key": "up/<tenant>/2026-07-31/ab12cd34-photo.jpg", "size_bytes": 812345, ... }The signature covers one tenant-scoped object key, the declared content type and the expiry;
uploads are capped at 15MB, enforced while reading the stream. Only raster image types are
accepted (jpeg/png/webp/gif/avif/heic/heif/bmp/tiff) — SVG is deliberately refused, because an
SVG is a scriptable document and /media serves from the server's own origin. The returned
r2_key is then usable three ways: directly as images_r2_keys on any generation tool (the
server reads its own bucket — no bytes in the conversation), permanently via
gemini_save_character, or as a ~48h Files API reference via gemini_upload_file({ r2_key }).
Uploads themselves follow the media retention schedule (up/ prefix, default 7 days).
Character & style library (hosted)
Recurring subjects and styles can be saved once, per account, with no expiry (the retention
cron deliberately skips the library's lib/ prefix):
// once:
{ "tool": "gemini_save_character", "name": "finn",
"description": "6-year-old boy, curly red hair", "image_r2_key": "up/…/photo.jpg" }
{ "tool": "gemini_save_style", "name": "bold-cartoon-sports",
"prompt_fragment": "bold cartoon style, thick outlines, saturated colors" }
// afterwards, on any generation:
{ "tool": "gemini_image_set",
"master_prompt": "Finn on a soccer field",
"scenes": ["kicking the ball", "celebrating a goal"],
"characters": ["finn"], "style": "bold-cartoon-sports" }Naming a character attaches its saved reference image and weaves its description into the
prompt; naming a style appends its fragment (and attaches its reference image, if it has one).
gemini_image_set passes character references to the master and every scene call, which is
what keeps the subject consistent across the set.
Quick Start
{
"mcpServers": {
"gemini": {
"command": "npx",
"args": ["-y", "@chrischall/gemini-mcp"],
"env": {
"GEMINI_API_KEY": "your-api-key-here"
}
}
}
}See SKILL.md for full usage documentation.
Available Tools
13 toolsgemini_delete_fileADestructive
Delete an uploaded file, image or photo (by file_uri) from the Gemini Files API before its ~48h expiry. Any tool call still referencing it will then fail with a generic 404, so delete only references you are finished with.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| file_uri | Yes | The `files/<id>` reference (or full uri) to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, and the description adds context: deletion causes 404 errors for other references, mentions ~48h expiry, and explains the confirm parameter's role. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the primary action, no unnecessary words. Efficient and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with 2 parameters and no output schema, the description fully covers purpose, usage, behavioral effects, and parameter semantics. Annotations complement well.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description reinforces the required parameter (file_uri) and clarifies the confirm parameter's behavior (preview if false). Adds slight value beyond schema by explaining the '~48h expiry' context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool deletes uploaded files by file_uri, and distinguishes it from sibling tools (upload, list) by specifying the deletion action and its consequence (404 for references).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly warns that deleting a file will cause other tool calls referencing it to fail with 404, advising to delete only references you are finished with. Provides clear when-to-use and consequence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_get_resultA
Retrieve a generation started with async: true or handed off by max_wait_ms. Pass the returned job_id: while running it reports status "running"; on completion it returns the normal result (image URLs/paths + meta); on failure it raises the recorded error, including the case where the generation was killed before it finished. On the hosted connector job records are stored durably and survive a restart; on a local stdio server they live with the process and expire ~10 min after completion, where the output dir / .json sidecar is the fallback. A killed video/music job started with background: true is recovered from its upstream interaction when it finished there.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The job_id returned by a generation tool called with async: true | |
| output_dir | No | Where to write media recovered from a killed job (default: $GEMINI_OUTPUT_DIR or cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations by explaining exactly what happens while the job is running, on completion, and on failure, including the killed-before-finished case. It also discloses durability differences between hosted and local servers, expiration behavior, and recovery of killed background jobs. This is rich behavioral context that the annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but not bloated; every sentence delivers useful information about retrieval, status, failure, durability, and recovery. It is not formatted with bullets, but the first sentence is front-loaded with purpose and usage. Slightly more structure would make the edge cases easier to scan, but there is no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, yet the description explains the return behavior clearly: status 'running', normal result with image URLs/paths and meta, and raised errors. It also covers the optional output_dir in the killed-job recovery flow and gives environment-specific behavior. For a tool with this complexity, the description is unusually complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters already have meaningful schema descriptions. The tool description reinforces them by explaining the job_id lifecycle and the output_dir fallback, but it does not substantially add semantics beyond what the input schema already states. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Retrieve a generation started with async: true or handed off by max_wait_ms.' This unambiguously distinguishes gemini_get_result from the sibling generation, editing, file-management, and interaction tools. It also specifies the exact input (job_id) and expected output shape, so there is no doubt about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states when to use the tool: after a generation was started with async: true or after max_wait_ms handed off a job. This gives the agent actionable context. It does not explicitly name alternatives or say when not to use this tool, but among the siblings none serve the same result-retrieval role, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_healthcheckVerify credentials and upstream reachabilityARead-onlyIdempotent
Resolves the credential the way real tools do, then makes one authenticated request to generativelanguage.googleapis.com. Reports which source supplied the credential, whether generativelanguage.googleapis.com accepted it, the round-trip time, and a plain-English hint distinguishing 'no credential' from 'credential rejected' from 'a generativelanguage.googleapis.com-side problem'. Call this when a real tool fails and you want to know which hop broke. Read-only; never returns the credential itself.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description discloses valuable behavioral details: it resolves the credential the way real tools do, performs exactly one authenticated request, reports credential source and acceptance, measures round-trip time, and explicitly states it never returns the credential itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, starting with what the tool does, then what it reports, then when to call it, and ending with safety. It is somewhat dense but every sentence contributes useful information; no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining return semantics, and it does: it enumerates the reported items (credential source, acceptance, round-trip time, plain-English hint) and the three failure categories. Combined with zero parameters and strong annotations, nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. The description adds useful context by explaining that it resolves the credential the way real tools do, which gives the agent a mental model without needing any parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it 'makes one authenticated request to generativelanguage.googleapis.com' and reports health information. It clearly distinguishes itself from sibling tools by its diagnostic purpose, describing it as a healthcheck that determines which hop broke when a real tool fails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit usage condition: 'Call this when a real tool fails and you want to know which hop broke.' This is clear guidance for when to use the tool, though it does not explicitly name alternatives or provide when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_image_editA
Edit or compose images: provide one or more input images (paths or base64), plus a text instruction. For a SERIES of successive edits to the same image, prefer gemini_interact (multi-turn) — it keeps edit context and avoids re-processing the full image each round; use gemini_image_edit for one-off edits or composing multiple distinct inputs. Gemini over-preserves the input; there is no edit-strength control — for large structural changes, reroll with a different seed or more forceful wording.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for reproducible generation; random if omitted | |
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| model | No | Model id override (default: server default; see gemini_list_models). gemini-3.1-flash-image (Nano Banana 2) is the versatile generalist workhorse — balances speed with state-of-the-art 4K generation, world knowledge, and reliable text rendering; excels at multi-reference-image processing and consistency. gemini-3-pro-image (Nano Banana Pro) is the premium choice for the most complex visual tasks — highest world knowledge, advanced localization, accurate brand consistency, precision creative control. gemini-3.1-flash-lite-image (Nano Banana 2 Lite) is the fastest/cheapest for simple tasks (1K only, no search grounding). | |
| style | No | Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only. | |
| images | No | Paths to input image file(s) (1 = edit, 2+ = compose) | |
| inline | No | Return base64 images inline instead of writing to disk | |
| prompt | Yes | Instruction describing the edit or composition | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| filename | No | Base filename for the output image (extension stripped; default: slugified prompt) | |
| characters | No | Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only. | |
| image_size | No | Output resolution (512 = 0.5K, Flash-only) | |
| images_url | No | Input images as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| output_dir | No | Directory to write images to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| orientation | No | Shape of the output, in plain terms: "landscape" (wide, 16:9), "portrait" (tall, 9:16) or "square" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given. | |
| aspect_ratio | No | Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given. | |
| google_search | No | Ground the image in live Google Search results (current events, weather, data) | |
| images_base64 | No | Input images as base64 strings or data URIs. Last resort: prefer images_url or images_file_uris, which keep image bytes out of the conversation | |
| from_clipboard | No | Use the image currently on the macOS system clipboard as an input (downscaled to JPEG) | |
| images_r2_keys | No | Input images by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only. | |
| thinking_level | No | Reasoning depth (Gemini 3 models); higher can help complex/structural edits | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| images_file_uris | No | Input images by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds a genuinely useful behavioral caveat beyond the annotations: 'Gemini over-preserves the input; there is no edit-strength control' and advises rerolling with a different seed or more forceful wording. With only readOnlyHint=false and openWorldHint=true in annotations, this behavioral disclosure materially helps the agent set expectations. It does not cover the full mutation/write surface, but it goes well beyond the structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with purpose, then usage routing, then a behavioral caveat. Every sentence earns its place: no fluff, no restatement of schema contents, and the most important selection guidance appears early. It packs a lot of useful orientation into a small space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's high complexity (24 parameters, no output schema, rich schema), the description provides the essential selection context, input requirements, and a key behavioral warning. It does not summarize output/return behavior or the async/confirmation flow, but those are well covered by the parameter descriptions. The description is not exhaustive, yet it covers the cross-cutting guidance an agent needs to choose and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even without parameter details in the description. The top-level description reinforces the core inputs (images, prompt) and mentions seed as a lever for structural changes, but it does not need to repeat the extensive per-parameter documentation already present in the schema. This is adequate value-added context, no more.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb+resource: 'Edit or compose images', then states the required inputs ('one or more input images (paths or base64), plus a text instruction'). It also distinguishes itself from gemini_interact by positioning itself for one-off edits or composing multiple distinct inputs, so an agent can tell it apart from its closest sibling without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is given: for a SERIES of successive edits it says 'prefer gemini_interact (multi-turn)' and explains why, while 'use gemini_image_edit for one-off edits or composing multiple distinct inputs' defines the boundary. This is direct, actionable routing guidance with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_image_generateA
Generate image(s) from a text prompt with a Gemini image model (Nano Banana / Nano Banana Pro). If the result will likely be refined iteratively, prefer gemini_interact (multi-turn) as the entry point.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for reproducible generation; random if omitted | |
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| count | No | Number of independent images (default 1) | |
| model | No | Model id override (default: server default; see gemini_list_models). gemini-3.1-flash-image (Nano Banana 2) is the versatile generalist workhorse — balances speed with state-of-the-art 4K generation, world knowledge, and reliable text rendering; excels at multi-reference-image processing and consistency. gemini-3-pro-image (Nano Banana Pro) is the premium choice for the most complex visual tasks — highest world knowledge, advanced localization, accurate brand consistency, precision creative control. gemini-3.1-flash-lite-image (Nano Banana 2 Lite) is the fastest/cheapest for simple tasks (1K only, no search grounding). | |
| style | No | Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only. | |
| images | No | Paths to reference input images (image-conditioned generation) | |
| inline | No | Return base64 images inline instead of writing to disk | |
| prompt | Yes | Text prompt describing the image | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| filename | No | Base filename for the output image (extension stripped; default: slugified prompt) | |
| video_url | No | Public YouTube URL (or a previously uploaded Files API uri) as a video reference (video→image; use a Flash model e.g. gemini-3.1-flash-image) | |
| characters | No | Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only. | |
| image_size | No | Output resolution (512 = 0.5K, Flash-only) | |
| images_url | No | Reference images as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| output_dir | No | Directory to write images to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| video_path | No | Path to a local video file — uploaded to the Gemini Files API (~48h retention, 2 GB max) and used as the video reference. Alternative to video_url. | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| orientation | No | Shape of the output, in plain terms: "landscape" (wide, 16:9), "portrait" (tall, 9:16) or "square" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given. | |
| aspect_ratio | No | Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given. | |
| google_search | No | Ground the image in live Google Search results (current events, weather, data) | |
| images_base64 | No | Reference images as base64 strings or data URIs. Last resort: prefer images_url or images_file_uris, which keep image bytes out of the conversation | |
| from_clipboard | No | Use the image currently on the macOS system clipboard as an input (downscaled to JPEG) | |
| images_r2_keys | No | Reference images by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only. | |
| thinking_level | No | Reasoning depth (Gemini 3 models); higher can help complex/structural edits | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| images_file_uris | No | Reference images by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=true, so the agent knows this is a mutating, external-state-dependent operation. But the description adds almost no behavioral context beyond model naming: it does not mention that generation writes files to disk, can take 60–120s+ and risk host timeouts, requires confirm=true to actually generate, or bills a new generation. The rich behavioral details live in parameter descriptions (async, max_wait_ms, idempotency_key, timeout_ms) rather than in the tool description itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The primary action is front-loaded in sentence one, and the conditional routing to gemini_interact occupies sentence two. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 27-parameter tool with no output schema, the description is very thin, but the schema compensates heavily with exhaustive parameter semantics. The main gaps are the lack of routing guidance toward gemini_image_edit (new generation vs. editing) and no mention of the confirm-gated preview flow, which is an unusual behavior an agent should be warned about. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3: every one of the 27 parameters already has a detailed schema description (e.g., orientation vs. aspect_ratio disambiguation, images_url vs. images_base64 tradeoffs, max_wait_ms semantics). The tool description itself contributes no parameter-level meaning, which is acceptable given the schema's depth.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Generate'), a precise resource ('image(s)'), the input type ('text prompt'), and the model family ('Gemini image model (Nano Banana / Nano Banana Pro)'). It is immediately distinguishable from siblings like gemini_video_generate, gemini_music_generate, and gemini_image_edit, and it names the closest ambiguous sibling (gemini_interact) as a different entry point.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit routing rule with a condition: 'If the result will likely be refined iteratively, prefer gemini_interact (multi-turn) as the entry point.' This resolves the primary ambiguity (generate vs. interact). It does not, however, give any guidance on when to prefer gemini_image_edit, gemini_image_set, or the async/get_result path, so a bit is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_image_setA
Generate a consistent SET of images: a master image from master_prompt, then one image per scene that references the master so the subject/style stays consistent. Provide scenes (explicit per-image prompts) OR count (variations of the master). Scene generations run in parallel (reference_mode "master", the default). On the hosted connector: saved characters and a saved style can seed the whole set by name, multi-image results include a bundle_url zip of every image (one curl instead of N), and max_wait_ms returns a pollable job handle if the batch runs long.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for reproducible generation; random if omitted | |
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| count | No | Number of variations of master_prompt (when scenes omitted) | |
| model | No | Model id override (default: server default; see gemini_list_models). gemini-3.1-flash-image (Nano Banana 2) is the versatile generalist workhorse — balances speed with state-of-the-art 4K generation, world knowledge, and reliable text rendering; excels at multi-reference-image processing and consistency. gemini-3-pro-image (Nano Banana Pro) is the premium choice for the most complex visual tasks — highest world knowledge, advanced localization, accurate brand consistency, precision creative control. gemini-3.1-flash-lite-image (Nano Banana 2 Lite) is the fastest/cheapest for simple tasks (1K only, no search grounding). | |
| style | No | Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only. | |
| inline | No | Return base64 images inline instead of writing to disk | |
| scenes | No | Per-image prompts (1-8); each references the master | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| basename | No | Base filename prefix for output images (default: slugified master_prompt) | |
| characters | No | Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only. | |
| image_size | No | Output resolution (512 = 0.5K, Flash-only) | |
| output_dir | No | Directory to write images to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| orientation | No | Shape of the output, in plain terms: "landscape" (wide, 16:9), "portrait" (tall, 9:16) or "square" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given. | |
| aspect_ratio | No | Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given. | |
| google_search | No | Ground the image in live Google Search results (current events, weather, data) | |
| master_images | No | Reference image paths passed to the master generation call | |
| master_prompt | Yes | Prompt for the master/reference image | |
| from_clipboard | No | Use the image currently on the macOS system clipboard as an input (downscaled to JPEG) | |
| reference_mode | No | master: every image references the master (default). chain: each references the previous. | |
| thinking_level | No | Reasoning depth (Gemini 3 models); higher can help complex/structural edits | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| master_images_url | No | Reference images passed to the master AND to every scene call (fetched once) as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| master_images_base64 | No | Reference images as base64 strings or data URIs for master generation. Last resort: prefer master_images_url or master_images_file_uris, which keep image bytes out of the conversation | |
| master_images_r2_keys | No | Reference images passed to the master AND to every scene call by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only. | |
| master_images_file_uris | No | Reference images passed to the master AND to every scene call by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only providing readOnlyHint=false and openWorldHint=true, the description adds substantial behavioral disclosure: scene generations run in parallel, the master seeds consistency, hosted-connector features like bundle_url zip downloads and pollable job handles, and max_wait_ms behavior when the budget expires. It also mentions the executor-lifetime constraint on the hosted connector. It doesn't detail every failure mode or auth requirement, but for a generative image tool the disclosed behaviors (parallelism, async vs bounded wait, zip output) are meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient: it front-loads the core 'consistent SET' purpose, then packs workflow, defaults, parallel execution, hosted features, bundle_url, and max_wait_ms into three sentences. Every sentence earns its place. It is slightly long relative to the number of behavioral details, but the information density is high and no filler is present. It earns a 4 rather than 5 because the length is near the upper bound and some details (one curl instead of N) are minor.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 27 parameters and no output schema, the description captures the essential operational model: master-then-scenes, scenes vs count, parallel execution, hosted-connector features, and timeout/job-handle behavior. The absence of an output schema means the description could have described the return shape in more detail, but the input schema already documents parameters thoroughly. It is complete enough for an agent to call it correctly in the common hosted and local cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description adds value by explaining the relationship between scenes/count/master_prompt and the consistency workflow. It also contextualizes hosted-connector-only params like characters, style, and master_images_r2_keys. The description goes beyond the schema by clarifying defaults like reference_mode 'master' and when max_wait_ms is preferable to async. It doesn't restate every parameter, but it doesn't need to given full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb phrase—'Generate a consistent SET of images'—and clearly distinguishes the tool from single-image generation by explaining the master-image-plus-scenes workflow. It also differentiates it from siblings like gemini_image_generate and gemini_image_edit by emphasizing consistency across multiple outputs. The mention of scenes, count, reference_mode, and bundle_url gives a concrete, non-tautological purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to provide `scenes` OR `count`, names the default reference_mode, and explains when to use hosted-connector features like saved characters/style and max_wait_ms. The `max_wait_ms` guidance also tells the agent when to prefer it over `async`, which is strong when-to-use guidance. This goes well beyond a vague 'use this for consistent sets' and includes concrete alternatives and conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_interactA
Preferred tool for iterative or multi-step refinement of a single image — multi-turn generation/editing via Gemini's Interactions API. To refine, capture the returned interaction id and pass it as previous_interaction_id on the next call — do NOT start a new interaction or re-upload the image for each tweak. continue_last: true chains from this session's most recent interaction without threading the id. If a call times out on the client side, the generation usually still completes: the image plus a <image>.json sidecar recording its interaction id land in the output dir, and continue_last: true still resumes that interaction — check the output dir before re-issuing (a re-issue is a second billable generation). If a chained call 404s, this tool re-anchors itself on the prior output image and re-issues un-chained: success is reported as chain_recovered (the chain was the problem, and you get your image anyway); a second 404 is reported as the interaction id NOT being the cause (check the model id / files uri instead). Output is JPEG.
| Name | Required | Description | Default |
|---|---|---|---|
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| input | Yes | Text prompt or editing instruction | |
| model | No | Model id override (default: server default; see gemini_list_models). gemini-3.1-flash-image (Nano Banana 2) is the versatile generalist workhorse — balances speed with state-of-the-art 4K generation, world knowledge, and reliable text rendering; excels at multi-reference-image processing and consistency. gemini-3-pro-image (Nano Banana Pro) is the premium choice for the most complex visual tasks — highest world knowledge, advanced localization, accurate brand consistency, precision creative control. gemini-3.1-flash-lite-image (Nano Banana 2 Lite) is the fastest/cheapest for simple tasks (1K only, no search grounding). | |
| images | No | Paths to reference input images. NEW reference images only (e.g. a style or target photo). When chaining with previous_interaction_id, do NOT re-attach the prior turn's output — the interaction already contains it, and re-sending it anchors the model against your edit. | |
| inline | No | Return base64 images inline instead of writing to disk | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| filename | No | Base filename for the output image (extension stripped; default: slugified input) | |
| video_url | No | Public YouTube URL (or a previously uploaded Files API uri) as a video reference (video→image; use a Flash model e.g. gemini-3.1-flash-image) | |
| image_size | No | Output resolution (512 = 0.5K, Flash-only) | |
| images_url | No | Reference images. NEW reference images only (e.g. a style or target photo). When chaining with previous_interaction_id, do NOT re-attach the prior turn's output — the interaction already contains it, and re-sending it anchors the model against your edit. Given as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| output_dir | No | Directory to write images to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| video_path | No | Path to a local video file — uploaded to the Gemini Files API (~48h retention, 2 GB max) and used as the video reference. Alternative to video_url. | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| orientation | No | Shape of the output, in plain terms: "landscape" (wide, 16:9), "portrait" (tall, 9:16) or "square" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given. | |
| aspect_ratio | No | Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given. | |
| search_types | No | Grounding search types (implies google_search). image_search (gemini-3.1-flash-image only) uses Google Image Search results as visual references; per Google ToS the returned grounding.search_suggestions HTML must then be displayed to the user. Cannot depict real people from web images. | |
| continue_last | No | Continue from the most recent interaction this server created (convenience for previous_interaction_id; an explicit id wins). Survives a server restart by falling back to the newest <image>.json sidecar in the output dir. | |
| google_search | No | Ground the image in live Google Search results (current events, weather, data) | |
| images_base64 | No | Reference images as base64 strings or data URIs. Last resort: prefer images_url or images_file_uris, which keep image bytes out of the conversation. NEW reference images only (e.g. a style or target photo). When chaining with previous_interaction_id, do NOT re-attach the prior turn's output — the interaction already contains it, and re-sending it anchors the model against your edit. | |
| from_clipboard | No | Use the image currently on the macOS system clipboard as an input (downscaled to JPEG) | |
| thinking_level | No | Reasoning depth; higher can help complex/structural edits | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| images_file_uris | No | Reference images. NEW reference images only (e.g. a style or target photo). When chaining with previous_interaction_id, do NOT re-attach the prior turn's output — the interaction already contains it, and re-sending it anchors the model against your edit. Given by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. | |
| previous_interaction_id | No | ID from a prior gemini_interact call — continues that multi-turn conversation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are thin (readOnlyHint=false, openWorldHint=true), and the description carries the real burden with exceptional disclosure: client-side timeouts 'usually still complete' with a <image>.json sidecar, a re-issue is 'a second billable generation,' 404s recover via chain_recovered with a second 404 meaning the interaction id was not the cause, and output is JPEG. This goes far beyond the annotations and directly prevents double-billing and retry confusion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place — purpose, chaining rule, timeout recovery, 404 recovery, output format — and the core purpose is front-loaded. It is a dense block with several long sentences, so it could be more scannable, but nothing is redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 25-parameter tool with serious failure modes (double billing, broken chains), no output schema, and thin annotations, the description covers all operational essentials: how chaining works, what happens on timeout and 404, where artifacts land (output dir, .json sidecar), and the output format. Remaining return-value behaviors (job_id, status: 'running', reused: true) are already documented in the schema's parameter descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with individually rich parameter docs, so the baseline is 3. The description adds genuine cross-parameter semantics not present in any single field: the chaining relationship among previous_interaction_id, continue_last, and images (do not re-attach the prior turn's output), and the timeout→sidecar→continue_last recovery flow. That earns one point above baseline, but the schema already does most of the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opening sentence states a specific verb+resource: 'iterative or multi-step refinement of a single image — multi-turn generation/editing via Gemini's Interactions API.' The 'iterative/multi-step' framing distinguishes it from single-shot siblings like gemini_image_generate and gemini_image_edit, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly positioned as the 'Preferred tool for iterative or multi-step refinement,' giving clear when-to-use context, plus a detailed chaining protocol: capture the returned interaction id, pass it as previous_interaction_id, and 'do NOT start a new interaction or re-upload the image for each tweak.' It stops short of a 5 because it never names the when-not-to-use alternative (a single one-shot generation would go to gemini_image_generate/gemini_image_edit).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_list_filesARead-only
List files, images and photos currently uploaded to the Gemini Files API under this API key, with their reusable file_uri (files/<id>) references, MIME types and expiry times. Retention is ~48h, so an entry that has vanished has expired rather than failed.
| Name | Required | Description | Default |
|---|---|---|---|
| page_size | No | Maximum files to return (1-100, default 100) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. Description adds value by clarifying retention period and expiry behavior, which is beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no wasted words. Front-loaded with purpose, then key behavioral detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, returned fields, and retention. No output schema but description compensates. Parameters are covered. Complete for a list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter (page_size) is well described in the schema. Description adds no extra parameter info, but baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the action (list) and resource (files, images, photos) along with returned fields (file_uri, MIME types, expiry times). Distinguishes from siblings like gemini_upload_file and gemini_delete_file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides context on retention (~48h) and explains that vanished files are expired, helping the agent understand behavior. No explicit when-not-to-use, but sibling differentiation is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_list_modelsARead-only
List the Gemini image-generation models available to your API key (Nano Banana / Nano Banana Pro family), and the current default model.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already indicates no side effects. The description adds context that the tool lists models specific to the API key and includes the default model, but does not disclose additional behavioral traits beyond what annotations already provide. It confirms safe behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that fully conveys the tool's purpose without extra words. It is appropriately sized and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema, no nested objects), the description is sufficiently complete. It explains what is returned (models list and default model). However, it does not detail the structure of each model entry, which is acceptable for a list operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters, so baseline is 4. The description adds meaning by specifying the model family (Nano Banana / Nano Banana Pro) and that the default model is included, which helps the agent understand what will be returned.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists Gemini image-generation models available to the API key, including a specific model family (Nano Banana / Nano Banana Pro) and the current default model. This provides specific verb and resource, distinguishing it from sibling tools like gemini_image_generate or gemini_list_files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for checking available models and the default, but does not explicitly state when to use it versus alternatives, nor does it provide exclusions or when-not-to-use guidance. Since it's a simple listing tool, it's adequate but could be improved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_music_generateA
Generate music from a text prompt (mood, genre, instruments, structure, or lyrics inline) via a Lyria model (preview): lyria-3-clip-preview (~30s clips, default) or lyria-3-pro-preview (longer, WAV-capable). Written to disk as MP3/WAV (or returned inline). Runs long — use async: true + gemini_get_result, or raise timeout_ms. Preview model: needs a funded account.
| Name | Required | Description | Default |
|---|---|---|---|
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| model | No | Lyria model (default: lyria-3-clip-preview). Pro is longer-form and supports WAV. | |
| images | No | Optional reference image path(s) to condition the music | |
| inline | No | Return base64 audio inline instead of writing to disk | |
| prompt | Yes | Description of the music: mood, genre, instruments, tempo, structure, or lyrics | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| filename | No | Base filename for the output audio (extension stripped; default: slugified prompt) | |
| background | No | Run the generation on Google's side and poll it, so a killed job can be recovered by gemini_get_result. Off by default — see gemini_video_generate | |
| images_url | No | Reference images as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| output_dir | No | Directory to write audio to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| audio_format | No | Output format (default mp3). wav is lyria-3-pro-preview-only. | |
| continue_last | No | Continue from the most recent music interaction this server created (explicit previous_interaction_id wins) | |
| images_base64 | No | Reference images as base64 strings or data URIs. Last resort: prefer images_url or images_file_uris, which keep image bytes out of the conversation | |
| from_clipboard | No | Use the image currently on the macOS clipboard as a reference | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| images_file_uris | No | Reference images by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. | |
| previous_interaction_id | No | Interaction id to continue from |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the minimal readOnlyHint/openWorldHint annotations by disclosing side effects: results are written to disk as MP3/WAV or returned inline, generation runs long, model capabilities differ by preview tier, and a funded account is required. This is strong behavioral context for a mutation-style tool with no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core action, then model details, output behavior, and long-run handling. Every sentence earns its place, and the most important invocation guidance appears early.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 19 parameters and no output schema, the description gives a solid high-level workflow: models, output formats, async + gemini_get_result, and the funded-account prerequisite. It does not explicitly describe the sync return shape or the confirm gate, though the very rich input schema covers those details, so it is nearly complete but not fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the individual parameter descriptions are detailed, so the baseline is 3. The description adds only a bit of extra model-level semantics, such as '~30s clips' for the default model and longer/WAV capability for Pro, but it does not need to compensate for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Generate music from a text prompt' via Lyria models, and it names the concrete models and their output characteristics. The resource differs clearly from sibling tools like gemini_video_generate and gemini_image_generate, so an agent can select it without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational guidance: use async: true with gemini_get_result for long runs, or raise timeout_ms, and it warns that the preview model needs a funded account. It does not explicitly say when not to use this tool versus sibling generation tools, but the music-specific scope plus the async guidance makes the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_token_usageARead-only
Token usage for this session so far — what every generation has cost in tokens, added up. Call it before and after a workflow and subtract to get that workflow's cost; call it after a single generation for that call's. Reports tokens AND an estimated USD cost, priced per call against each call's own model and stamped with the date its rates were read (override with GEMINI_RATE_CARD). Note there is no account-balance endpoint to query — Google Cloud is post-paid and its billing data lags by hours — so this is the accurate way to attribute spend to a call.
| Name | Required | Description | Default |
|---|---|---|---|
| reset | No | Zero the running total after reporting it, so the next call measures from here. Use it to bracket a workflow without arithmetic. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses that the tool accumulates session-wide totals, supports resetting the running total, estimates USD cost using each call's own model and rate-card date, and honors the GEMINI_RATE_CARD override. It also explains the external billing constraint that motivates the tool's design. The description is fully consistent with the readOnlyHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the first defines what the tool reports, the second covers the two main invocation patterns, the third explains the cost/rate-card behavior, and the fourth justifies why no account-balance endpoint exists. It is dense but not verbose, with the core purpose front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description adequately tells the agent what the tool returns (tokens plus estimated USD cost), how to interpret it, how to use reset, and what limitations apply. Given the tool's simple one-parameter interface, this is sufficient for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the reset parameter at 100% coverage, so the baseline is 3, but the description adds real interpretive value by explaining that reset zeros the total after reporting and lets you bracket a workflow without arithmetic. This goes beyond the schema's literal parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a cumulative token-usage and cost reporter for the current session, with a specific verb implied by 'Call it' and 'Reports.' It is easily distinguished from the sibling generation, file, and model tools because it is the only one concerned with measuring spend rather than producing content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage patterns: call before and after a workflow and subtract, or call after a single generation to get that call's cost. It also explains why this tool is necessary by noting there is no account-balance endpoint and that Google Cloud billing data lags, making this the accurate way to attribute spend.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_upload_fileA
Upload a file — an image, reference photo, picture, screenshot, video or audio clip — to the Gemini Files API ONCE, and get back a reusable file_uri (files/<id>) to attach to later image, video or music generations. Keywords: upload, upload file, upload image, upload photo, attach, reference image, reference photo, file_uri, files api, image reference, reuse across calls. Use this instead of pasting base64 into a tool call: the reference is a short string, so no image bytes ever enter the conversation, and it can be reused across many generations until it expires (~48h). Provide exactly one of url (the server downloads it), data_base64, or path (a local file).
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Public https URL the SERVER downloads and uploads (image/video/audio, up to 100MB). No bytes pass through the conversation. | |
| path | No | Path to a local file (absolute, or resolved against $GEMINI_INPUT_DIR). Confirm-gated like every other local-file input. | |
| r2_key | No | Unavailable on this server (media is written to local disk) — pass the file path via `path` instead. | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| mime_type | No | Override the detected MIME type (sniffed from the bytes / taken from the server response otherwise) | |
| data_base64 | No | Raw base64 or a data: URI. Last resort — this is the one form that costs model context (~14k tokens for a modest JPEG). | |
| display_name | No | Human-readable name recorded against the upload |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false and openWorldHint=true, aligning with the write operation described. The description adds behavioral details: 'upload once,' reusability, and token cost of data_base64. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose and keywords. It is slightly long but every sentence adds value, covering usage, parameters, and behavioral notes. Minor redundancy (e.g., 'reuse across calls' repeated) but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description clearly states the return value (file_uri as files/<id>). It covers input sources and expiration. Missing details on error handling or size limits (except in url param), but for a file upload, this is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds significant value: it explains that exactly one of url, data_base64, or path must be provided, clarifies the confirm parameter's requirement, and warns about token cost for data_base64. This goes well beyond the schema's descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool uploads a file to the Gemini Files API and returns a reusable file_uri. It lists supported file types (image, video, audio clip) and distinguishes from siblings like gemini_list_files or gemini_image_generate by focusing on upload-only functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases: upload files to avoid base64 tokens and for reusability across calls. It mentions expiration (~48h) but does not explicitly state when not to use this tool or name alternative tools. However, the sibling context shows no direct upload alternative, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gemini_video_generateA
Generate a short video via the Gemini omni model (preview): text→video, image→video / reference→video (supply reference image[s]), or edit a prior video (task: "edit" + previous_interaction_id / continue_last). Output is written to disk as MP4 (video has no inline MCP block). Video runs long — use async: true to get a job_id immediately and poll gemini_get_result, or raise timeout_ms. Preview model: needs a funded account.
| Name | Required | Description | Default |
|---|---|---|---|
| task | No | text_to_video (default), image_to_video / reference_to_video (need image input), or edit (needs previous_interaction_id) | |
| async | No | Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off. | |
| model | No | Model id override (default: gemini-omni-flash-preview) | |
| images | No | Reference image path(s) for image_to_video / reference_to_video | |
| prompt | Yes | Description of the video to generate (or the edit instruction when task=edit) | |
| confirm | No | Must be true to proceed. Without this, the tool returns a preview. | |
| delivery | No | How the clip comes back: "uri" (default — a Files API link the server downloads, no size ceiling) or "inline" (base64, capped ~4MB) | |
| filename | No | Base filename for the output video (extension stripped; default: slugified prompt) | |
| background | No | Run the generation on Google's side and poll it, so a killed job can be recovered by gemini_get_result. Trade-off: retrieving a backgrounded interaction is unreliable today (some become permanently unreadable), so the default is off | |
| images_url | No | Reference stills as public https URLs — the SERVER downloads them, so no image bytes travel through the conversation. Preferred over images_base64, which costs ~14k tokens per photo and breaks if a file read was truncated. Max 15MB each; must be a directly-linked image (Content-Type image/*). | |
| output_dir | No | Directory to write the video to (default: $GEMINI_OUTPUT_DIR or cwd) | |
| timeout_ms | No | Upstream request timeout in ms for this call (default: $GEMINI_TIMEOUT_MS, else 60000 — or 120000 when image_size is 4K, which routinely runs past 60s) | |
| max_wait_ms | No | Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: "running" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set. | |
| orientation | No | Shape of the output, in plain terms: "landscape" (wide, 16:9), "portrait" (tall, 9:16) or "square" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given. | |
| aspect_ratio | No | Exact output aspect ratio (omni: 16:9 or 9:16). `orientation` is the plain-language shorthand; this wins if both are given. | |
| continue_last | No | Continue from the most recent video interaction this server created (explicit previous_interaction_id wins) | |
| images_base64 | No | Reference images as base64 strings or data URIs. Last resort: prefer images_url or images_file_uris, which keep image bytes out of the conversation | |
| from_clipboard | No | Use the image currently on the macOS clipboard as a reference | |
| idempotency_key | No | Opaque idempotency key: a repeat call with the same key returns the recorded result (reused: true) instead of billing a new generation. Set it when retrying after a host timeout (-32001) to avoid a duplicate charge. | |
| images_file_uris | No | Reference stills by Gemini Files API reference ("files/<id>", or the full uri) from gemini_upload_file or POST /upload. Upload once, then reference it across as many calls as you like — no bytes are re-sent and none enter the conversation. Files are retained ~48h, after which the reference stops resolving. | |
| previous_interaction_id | No | Interaction id to edit/continue (with task: "edit") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations (readOnlyHint=false, openWorldHint=true), the description discloses that output is written to disk as MP4 with no inline MCP block, that generation runs long and can hit timeouts, that async returns a job_id immediately, and that the preview model requires a funded account. It also flags background retrieval as unreliable, which annotations would never convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences cover purpose, output, async behavior, and a prerequisite with zero filler. The most important scoping information (video generation modes) is front-loaded before the operational caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 21-parameter tool with no output schema and thin annotations, the description covers the high-risk aspects an agent must know before calling: funding requirement, timeout behavior, polling via gemini_get_result, background reliability, and output location. Parameter-level details live in the schema, so nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter; the description adds workflow-level meaning by tying task modes to input requirements, recommending async/timeout_ms for long videos, and explaining the disk/MP4 output semantics. It doesn't add much beyond the already-detailed schema descriptions, but the synthesis is useful, so a 4 is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact operation—'Generate a short video via the Gemini omni model'—and enumerates the three input modes: text→video, image/reference→video, and editing a prior video. This clearly separates it from sibling image/audio generation tools despite not naming them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete selection criteria: use task edit with previous_interaction_id/continue_last, supply reference images for image-to-video, and use async or raised timeout_ms for long-running jobs, explicitly pointing to gemini_get_result for polling. It lacks an explicit 'don't use for still images/audio' exclusion, so it doesn't fully earn a 5, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v1.12.0- Added
gemini_healthcheck
1 tool update
v1.11.1- Added
gemini_token_usage
7 tool updates
v1.10.0- Changed
gemini_get_result1 field changed- added
Input schema / properties / output_dirAdded value: +{ + "description": "Where to write media recovered from a killed job (default: $GEMINI_OUTPUT_DIR or cwd)", + "type": "string" +}
- Changed
gemini_image_edit2 fields changed- changed
Input schema / properties / aspect_ratio / descriptionPrevious value: -"Output aspect ratio"New value: +"Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given." - added
Input schema / properties / orientationAdded value: +{ + "description": "Shape of the output, in plain terms: \"landscape\" (wide, 16:9), \"portrait\" (tall, 9:16) or \"square\" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given.", + "enum": [ + "landscape", + "portrait", + "square" + ], + "type": "string" +}
- Changed
gemini_image_generate2 fields changed- changed
Input schema / properties / aspect_ratio / descriptionPrevious value: -"Output aspect ratio"New value: +"Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given." - added
Input schema / properties / orientationAdded value: +{ + "description": "Shape of the output, in plain terms: \"landscape\" (wide, 16:9), \"portrait\" (tall, 9:16) or \"square\" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given.", + "enum": [ + "landscape", + "portrait", + "square" + ], + "type": "string" +}
- Changed
gemini_image_set2 fields changed- changed
Input schema / properties / aspect_ratio / descriptionPrevious value: -"Output aspect ratio"New value: +"Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given." - added
Input schema / properties / orientationAdded value: +{ + "description": "Shape of the output, in plain terms: \"landscape\" (wide, 16:9), \"portrait\" (tall, 9:16) or \"square\" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given.", + "enum": [ + "landscape", + "portrait", + "square" + ], + "type": "string" +}
- Changed
gemini_interact2 fields changed- changed
Input schema / properties / aspect_ratio / descriptionPrevious value: -"Output aspect ratio"New value: +"Exact output aspect ratio. For a plain landscape/portrait/square request, `orientation` is the shorthand; this wins if both are given." - added
Input schema / properties / orientationAdded value: +{ + "description": "Shape of the output, in plain terms: \"landscape\" (wide, 16:9), \"portrait\" (tall, 9:16) or \"square\" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given.", + "enum": [ + "landscape", + "portrait", + "square" + ], + "type": "string" +}
- Changed
gemini_music_generate1 field changed- added
Input schema / properties / backgroundAdded value: +{ + "description": "Run the generation on Google's side and poll it, so a killed job can be recovered by gemini_get_result. Off by default — see gemini_video_generate", + "type": "boolean" +}
- Changed
gemini_video_generate4 fields changed- changed
Input schema / properties / aspect_ratio / descriptionPrevious value: -"Output aspect ratio (omni: 16:9 or 9:16)"New value: +"Exact output aspect ratio (omni: 16:9 or 9:16). `orientation` is the plain-language shorthand; this wins if both are given." - added
Input schema / properties / backgroundAdded value: +{ + "description": "Run the generation on Google's side and poll it, so a killed job can be recovered by gemini_get_result. Trade-off: retrieving a backgrounded interaction is unreliable today (some become permanently unreadable), so the default is off", + "type": "boolean" +} - added
Input schema / properties / deliveryAdded value: +{ + "description": "How the clip comes back: \"uri\" (default — a Files API link the server downloads, no size ceiling) or \"inline\" (base64, capped ~4MB)", + "enum": [ + "inline", + "uri" + ], + "type": "string" +} - added
Input schema / properties / orientationAdded value: +{ + "description": "Shape of the output, in plain terms: \"landscape\" (wide, 16:9), \"portrait\" (tall, 9:16) or \"square\" (1:1). Use this for a request phrased as landscape/portrait/vertical/horizontal. For any other proportion — 35mm photo (3:2), print (4:3), social (4:5), cinematic (21:9) — name it with aspect_ratio instead, which overrides this when both are given.", + "enum": [ + "landscape", + "portrait", + "square" + ], + "type": "string" +}
6 tool updates
v1.7.0- Changed
gemini_image_edit5 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / charactersAdded value: +{ + "description": "Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 8, + "type": "array" +} - added
Input schema / properties / images_r2_keysAdded value: +{ + "description": "Input images by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +} - added
Input schema / properties / styleAdded value: +{ + "description": "Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only.", + "minLength": 1, + "type": "string" +}
- Changed
gemini_image_generate5 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / charactersAdded value: +{ + "description": "Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 8, + "type": "array" +} - added
Input schema / properties / images_r2_keysAdded value: +{ + "description": "Reference images by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +} - added
Input schema / properties / styleAdded value: +{ + "description": "Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only.", + "minLength": 1, + "type": "string" +}
- Changed
gemini_image_set5 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / charactersAdded value: +{ + "description": "Names of saved characters (see gemini_list_characters / gemini_save_character): each one's reference image and description are attached to the request automatically, keeping recurring subjects consistent without re-sending anything. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 8, + "type": "array" +} - added
Input schema / properties / master_images_r2_keysAdded value: +{ + "description": "Reference images passed to the master AND to every scene call by r2_key from THIS connector's store: a signed upload (gemini_get_upload_url → curl PUT) or an earlier generation's media[].r2_key. The server reads its own bucket directly — no bytes in the conversation, no signed URL, no ~48h Files API expiry. Hosted connector only.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +} - added
Input schema / properties / styleAdded value: +{ + "description": "Name of a saved style preset (see gemini_list_styles / gemini_save_style): its prompt fragment — and reference image, if it has one — is applied to the request automatically. Hosted connector only.", + "minLength": 1, + "type": "string" +}
- Changed
gemini_interact2 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +}
- Changed
gemini_music_generate2 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +}
- Changed
gemini_video_generate2 fields changed- changed
Input schema / properties / async / descriptionPrevious value: -"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result (jobs are per-process and expire ~10 min after completion)."New value: +"Run in the background and return a job_id immediately instead of the image, so a long (Pro/4K) generation cannot hit the host tools/call timeout (-32001). Poll gemini_get_result with the job_id to fetch the result. PREFER `max_wait_ms` on the hosted connector: it runs where the executor is only guaranteed to stay alive while the request is open, so this option is served there as a bounded wait rather than an immediate hand-off." - added
Input schema / properties / max_wait_msAdded value: +{ + "description": "Wait up to this many ms for the result; if generation is still running when the budget expires, return { job_id, status: \"running\" } immediately instead (poll gemini_get_result). Keeps fast results in-band while a slow batch can never trip the host tools/call timeout (-32001) — e.g. 20000 for multi-image sets. Ignored when async is set.", + "exclusiveMinimum": 0, + "maximum": 600000, + "type": "integer" +}
1 tool update
v1.4.0- Changed
gemini_upload_file1 field changed- added
Input schema / properties / r2_keyAdded value: +{ + "description": "Unavailable on this server (media is written to local disk) — pass the file path via `path` instead.", + "minLength": 1, + "type": "string" +}
11 tool updates
v1.2.0- First observed
gemini_delete_file - First observed
gemini_get_result - First observed
gemini_image_edit - First observed
gemini_image_generate - First observed
gemini_image_set - First observed
gemini_interact - First observed
gemini_list_files - First observed
gemini_list_models - First observed
gemini_music_generate - First observed
gemini_upload_file - First observed
gemini_video_generate
TDQS
Each tool has a clear role—file management, generation, editing, or polling—and the overlapping image tools are differentiated by workflow (image_generate for one-shot, interact for iterative, image_edit for one-off edits, image_set for consistent sets). Some minor ambiguity remains between image_edit and interact for editing tasks, but the descriptions largely resolve it.
All tools share the gemini_ prefix, which helps, but the suffix pattern is mixed: upload_file/list_files/delete_file/get_result use verb_noun, while image_generate/video_generate/music_generate use noun_verb, and interact is a bare verb. The names are readable and searchable, but they do not follow a single predictable convention.
11 tools is a well-scoped size for a Gemini media-generation server. Each tool covers a distinct capability—file lifecycle, model discovery, image generation/edit/set/interact, video, music, and async result polling—without redundant entries.
The server covers the main media-generation workflows well: file upload/list/delete, model discovery, image/video/music generation, iterative editing, and async retrieval. Minor gaps exist, such as no way to list or cancel in-flight async jobs, but agents can work around these using output files and job IDs.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Google Veo AI video generation
Focused MCP server for OpenAI image/audio generation (v2.0.0). Wraps endpoints via HAPI CLI.
AI image, video, voice and music generation over MCP, routed to Veo 3.1, Seedance 2.0 and more.
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
Related MCP Servers
- AlicenseAqualityAmaintenanceProduction-grade MCP server for image and video understanding and generation across Gemini, OpenAI, and Grok.54Apache 2.0
- AlicenseNot gradedqualityDmaintenanceModel Context Protocol server exposing MiniMax's image, speech, music, and video generation APIs as MCP tools for use with any MCP-aware host.4,051MIT
- FlicenseAqualityDmaintenanceWraps Google Gemini's image generation API as an MCP server, enabling text-to-image, image editing, and grounded search workflows from any MCP client.2-
- AlicenseNot gradedqualityCmaintenanceRemote MCP server that exposes Google Gemini's text, image, video (Veo), and audio transcription capabilities as tools any MCP client can call directly.59MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrischall/gemini-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server