Skip to content

gemini mcp changelog

io.github.chrischall/gemini-mcp

11 changes recorded. MCP Harbor re-reads this listing from the official registry every six hours and asks the live server what it exposes, and keeps what changed between one look and the next.

  • server.json 1 field changed
    version
    2.5.0 2.5.1

  • server.json 1 field changed
    version
    2.4.2 2.5.0

  • server.json 1 field changed
    version
    2.4.1 2.4.2

  • AGENTS.md +1 −200

    https://raw.githubusercontent.com/chrischall/gemini-mcp/HEAD/AGENTS.md

    − # AGENTS.md — gemini-mcp− Guidance for coding agents working in this repo.− ## TL;DR− v0.6.0: Google **Gemini** image-generation MCP server. Wraps the Generative− Language REST API (`https://generativelanguage.googleapis.com/v1beta`) and− exposes 13 tools to Claude over stdio: text→image and image→image generation,− multi-turn conversational editing, consistent image *sets*, **video generation**− (omni, `gemini_video_generate`), **music generation** (Lyria clip/3.5/pro,− `gemini_music_generate`), model listing (Nano Banana / Nano Banana Pro− family), **Files API** upload/list/delete, and a credential− healthcheck (`gemini_healthcheck`). Reference images can come from an− https URL the *server* fetches (`images_url`), a Files API reference− (`images_file_uris`), local file paths, raw base64 / data URIs, or the macOS− clipboard; video from a public YouTube URL or a local upload. Video and music ride the **same− Interactions endpoint** as `gemini_interact` — the tool naming is media-first− (`gemini_<media>_<action>`). Realtime Lyria (WebSocket) is intentionally− **not** implemented (see the video/music design spec).− A hosted deployment additionally serves: `gemini_get_upload_url` (signed PUT− upload URLs — zero-auth-header uploads from a shell), a persistent per-account− character/style library (`gemini_save/list/delete_character`/`_style`, applied− via `characters`/`style` params on the generation tools), `images_r2_keys`− inputs, `max_wait_ms` wait-then-hand-off on generation tools, and a `bundle_url`− zip on multi-image `gemini_image_set` results.− Auth is a Google **API key** (`GEMINI_API_KEY`) sent in the `x-goog-api-key`− header — Gemini does **not** use `Authorization: Bearer`. Because the model is− baked into the URL path (`/models/{model}:generateContent`) rather than the body,− this is the bearer/direct-API archetype with a custom twist: a thin `call()`− wrapper over the fleet-shared `createApiClient` (configured with a non-Bearer− `tokenHeader`), not a hand-rolled fetch and not a stock Bearer client.− ## Environment− ```− GEMINI_API_KEY=<key>        # Optional to boot; every Gemini API call needs it unless the hosted connector−                             #   supplies a per-session key. Create at https://aistudio.google.com/apikey− GEMINI_IMAGE_MODEL=<id>     # Optional. Default model override (bare id, e.g. gemini-3.1-flash-image)− GEMINI_OUTPUT_DIR=<dir>     # Optional. Where generated images are written (default: ~/Downloads/gemini-mcp); when set, confines per-call output_dir− GEMINI_INPUT_DIR=<dir>      # Optional. Base dir searched for relative input image paths− GEMINI_UPLOAD_DIR=<dirs>    # Optional. Confine local-file Files-API uploads (upload_file `path`, `video_path`)−                             #   to these dirs (path.delimiter-separated, `~` ok). Unset = unconfined.− GEMINI_REFERENCE_DIR=<dirs> # Optional. Confine local reference images (`images` paths) — referenceRoots() in images.ts: this → GEMINI_UPLOAD_DIR → $MCP_DATA_DIR/uploads (hosted) → unconfined; GEMINI_OUTPUT_DIR always added when on− GEMINI_TIMEOUT_MS=<ms>      # Optional. Upstream timeout (default 60000; 120000 for 4K; per-call timeout_ms wins)+ CLAUDE.md

    Showing the first 40 of each.

  • server.json 1 field changed
    version
    2.4.0 2.4.1

  • server.json 1 field changed
    version
    2.3.4 2.4.0

  • server.json 2 fields changed
    env_vars
    GEMINI_API_KEY, GEMINI_IMAGE_MODEL, GEMINI_OUTPUT_DIR, GEMINI_INPUT_DIR, GEMINI_UPLOAD_DIR, GEMINI_REFERENCE_DIR GEMINI_API_KEY, GEMINI_IMAGE_MODEL, GEMINI_OUTPUT_DIR, GEMINI_INPUT_DIR, GEMINI_UPLOAD_DIR, GEMINI_REFERENCE_DIR, GEMINI_TIMEOUT_MS, GEMINI_HEARTBEAT_MS, GEMINI_CHAIN_RETRY_MS, GEMINI_DEBUG, GEMINI_RATE_CARD
    version
    2.3.3 2.3.4

  • AGENTS.md +40 −24

    https://raw.githubusercontent.com/chrischall/gemini-mcp/HEAD/AGENTS.md

    − GEMINI_API_KEY=<key>        # Required. Create at https://aistudio.google.com/apikey− GEMINI_OUTPUT_DIR=<dir>     # Optional. Where generated images are written (default: cwd)− `${FOO}` placeholders as unset. All but `GEMINI_HEARTBEAT_MS`, `GEMINI_DEBUG` and− `GEMINI_CHAIN_RETRY_MS` map to `manifest.json`'s `user_config` (`gemini_api_key`,− `gemini_image_model`, `gemini_input_dir`, `gemini_upload_dir`, `gemini_output_dir`,− `gemini_timeout_ms`).−                   #   slugify, uniquePath, resolveOutputDir, resolveImagePath.− `output_dir` → `$GEMINI_OUTPUT_DIR` → cwd), de-duplicating with `uniquePath`− **The registry is per SESSION, not per process** — it lives at− `client.session.jobs` (`src/session.ts`). Hosted, one− isolate serves many authenticated sessions, so a module-level registry let user− B replay user A's result via a colliding `idempotency_key` ("1", "test") and− attach to A's in-flight billable job via `fingerprintRequest`. See Quirks.− one try that falls back to inline, and the upload carries an− `AbortSignal.timeout` because `uploadToFilesApi` is otherwise untimed and this− puts two round trips in front of a call nobody asked to wait for.− - **No module-level mutable state in `src/` — it leaks across tenants.**−   one process can serve several sessions, so−   a module-level `Map`/`let` is shared by every authenticated claude.ai session−   in that isolate. The per-session `GeminiClient` isolates the API key and−   nothing else. When the job registry and `lastInteractionId` lived at module−   scope, a colliding `idempotency_key` handed user B user A's recorded result−   verbatim (A's media refs, A's interaction id), an identical prompt attached B−   never a module global. Guarded by `tests/session-isolation.test.ts`.+ GEMINI_API_KEY=<key>        # Optional to boot; every Gemini API call needs it unless the hosted connector+                             #   supplies a per-session key. Create at https://aistudio.google.com/apikey+ GEMINI_OUTPUT_DIR=<dir>     # Optional. Where generated images are written (default: ~/Downloads/gemini-mcp); when set, confines per-call output_dir+ GEMINI_REFERENCE_DIR=<dirs> # Optional. Confine local reference images (`images` paths) — referenceRoots() in images.ts: this → GEMINI_UPLOAD_DIR → $MCP_DATA_DIR/uploads (hosted) → unconfined; GEMINI_OUTPUT_DIR always added when on+ `${FOO}` placeholders as unset. Every one maps to an optional `manifest.json`+ `user_config` entry (`gemini_<lowercased suffix>`, e.g. `gemini_api_key`,+ `gemini_heartbeat_ms`) and an optional `server.json` environment variable —+ `tests/env-manifest.test.ts` holds both install paths to the vars `src/` reads.+ Optional includes `GEMINI_API_KEY`: the server boots without it and resolves it+ per request, so `gemini_healthcheck` can say it is missing.+                   #   slugify, resolveOutputDir, resolveImagePath (output kit + magic-byte sniff from mcp-utils).+ `output_dir` → `$GEMINI_OUTPUT_DIR` → `~/Downloads/gemini-mcp`), de-duplicating with mcp-utils `writeUniqueFile`+ **The registry lives on the session, never at module scope** — it is+ `client.session.jobs` (`src/session.ts`). Today that is one registry per+ process, and that is sound only because one registration is one user (stdio,+ or an mcp-host child per registration). The retired Cloudflare Worker served+ many users from one isolate, and there a module-level registry let user B+ replay user A's result via a colliding `idempotency_key` ("1", "test") and+ attach to A's in-flight billable job via `fingerprintRequest`. A host that+ multiplexes users onto one process must build a client per user. See Quirks.+ one try that falls back to inline, and the upload carries a+ short `AbortSignal.timeout` because `uploadToFilesApi`'s own default deadline is+ sized for multi-GB files, and this puts two round trips in front of a call+ nobody asked to wait for.+   `MCP_CONFIRM_ELICITATION` (`on` | `off` — `off` skips the prompt for clients+   that declare elicitation but never show it, e.g. opencode 2.0.x),+ - **No module-level mutable state in `src/` — it would leak across users the+   moment a process serves more than one.** A module-level `Map`/`let` is shared+   by everything in the process, and the `GeminiClient` isolates the API key and+   nothing else. That bit for real on the retired Cloudflare Worker, which served+   many claude.ai users from one isolate: when the job registry and+   `lastInteractionId` lived at module scope, a colliding `idempotency_key`+   handed user B user A's recorded result verbatim (A's media refs, A's+   interaction id), an identical prompt attached B+   never a module global. Guarded by `tests/session-isolation.test.ts` — which+   shows separate clients stay apart, NOT that production builds them: today+   there is ONE client per process, and that is sound only because one+   registration is one user (stdio, or an mcp-host child per registration). A+   host that multiplexes users onto one process must also build a client per+   user (see the invariant in `src/session.ts`).

  • server.json 1 field changed
    version
    2.3.2 2.3.3

  • server.json 1 field changed
    version
    2.3.1 2.3.2

  • server.json 2 fields changed
    env_vars
    GEMINI_API_KEY, GEMINI_IMAGE_MODEL, GEMINI_OUTPUT_DIR, GEMINI_INPUT_DIR, GEMINI_UPLOAD_DIR GEMINI_API_KEY, GEMINI_IMAGE_MODEL, GEMINI_OUTPUT_DIR, GEMINI_INPUT_DIR, GEMINI_UPLOAD_DIR, GEMINI_REFERENCE_DIR
    version
    2.3.0 2.3.1