@chrischall/gemini-mcp 2.4.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "MCP server for Google Gemini image generation and editing — generate and edit images via the Gemini API",
10
- "version": "2.4.0"
10
+ "version": "2.4.2"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "Gemini Images",
16
16
  "source": "./",
17
17
  "description": "Generate and edit images with Google Gemini image models (Nano Banana / Nano Banana Pro) via natural language prompts",
18
- "version": "2.4.0",
18
+ "version": "2.4.2",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gemini-mcp",
3
3
  "displayName": "Gemini Images",
4
- "version": "2.4.0",
4
+ "version": "2.4.2",
5
5
  "description": "MCP server for Google Gemini image generation and editing — generate and edit images via the Gemini API",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/.mcp.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "gemini": {
4
- "command": "node",
5
- "args": ["${CLAUDE_PLUGIN_ROOT}/dist/index.js"],
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@chrischall/gemini-mcp"
8
+ ],
6
9
  "env": {
7
10
  "GEMINI_API_KEY": "${GEMINI_API_KEY}",
8
11
  "GEMINI_IMAGE_MODEL": "${GEMINI_IMAGE_MODEL}",
package/README.md CHANGED
@@ -119,7 +119,8 @@ immediately), `max_wait_ms` (wait up to a budget, then hand back the `job_id`
119
119
  in-band, slow batches never trip the host timeout), and `idempotency_key` (a retry returns the
120
120
  recorded result instead of re-billing). On a hosted deployment, a `gemini_image_set` result with
121
121
  more than one image also carries a **`bundle_url`** — one signed URL for a zip of every image in
122
- the set — and set links are signed for ~7 days instead of the default ~48h. (A set too large to
122
+ the set. Like every hosted link it lives at most 24h (the host's blob-store ceiling);
123
+ `gemini_sign_media` re-mints an expired one. (A set too large to
123
124
  zip safely in memory skips the bundle and says so via `bundle_skipped`; the per-image
124
125
  links are unaffected.)
125
126
 
@@ -138,8 +139,9 @@ something you can *open*. It does: **every result includes a URL**, with no conf
138
139
  ```
139
140
 
140
141
  Those links need no auth header — the signature is in the URL — so they work in a browser, in
141
- `curl`, and in a chat message. They expire (48h by default) and the objects behind them are
142
- swept on a retention schedule. The `r2_key` is the durable handle for that window:
142
+ `curl`, and in a chat message. They expire after at most 24h — the host's blob store refuses a
143
+ longer signature — and the objects behind them are swept on the host's retention schedule. The
144
+ `r2_key` is the durable handle for that window:
143
145
 
144
146
  - **`gemini_sign_media`** (hosted deployments only) mints a fresh signed URL from an `r2_key`,
145
147
  so an expired link never forces you to re-generate — and re-pay for — the image.
@@ -173,8 +175,9 @@ both work.
173
175
  **Auth is a signed, expiring URL rather than an unlisted key.** Random keys would
174
176
  be simpler, but they never expire and never revoke: anything that ever logged or forwarded the
175
177
  link keeps working forever. A signature scopes access to one object with a deadline, and
176
- rotating `MEDIA_URL_SECRET` invalidates every outstanding link at once. The tradeoff is that
177
- links are long and cannot be shortened by hand.
178
+ rotating the host's signing key (`MCP_BLOB_SIGNING_KEY`, which mcp-host injects together with
179
+ `MCP_BLOB_BASE_URL`; this server never chooses either) invalidates every outstanding link at
180
+ once. The tradeoff is that links are long and cannot be shortened by hand.
178
181
 
179
182
  ### For assistants relaying a result
180
183
 
@@ -185,18 +188,18 @@ safe form, and a markdown link is a reasonable enhancement where you know it ren
185
188
 
186
189
  ### Retention
187
190
 
188
- | Variable | Default | Effect |
189
- |---|---|---|
190
- | `MEDIA_TTL_DAYS` | `7` | Objects older than this are deleted by a daily cron — generated media (`gen/`, legacy `media/`) and signed uploads (`up/`). The character/style library (`lib/`) is exempt: saved entries never expire |
191
- | `MEDIA_URL_SECRET` | generated | HMAC key for `/media` links; rotate to revoke all outstanding URLs |
192
-
193
- Signed-URL lifetime is clamped to `MEDIA_TTL_DAYS`, so a link never outlives the object it
194
- points at.
191
+ Retention is the host's, not a setting of this server. On mcp-host, the blob store prunes
192
+ generated media (`gen/`) and signed uploads (`up/`) on its own schedule (see mcp-host
193
+ `docs/BLOB-STORE.md`; default 30 days), while the character/style library (`lib/`) is written as
194
+ retention-exempt, so saved entries never expire. Every signed link is clamped to the store's
195
+ 24h ceiling, so it never outlives what the store will honour; `gemini_sign_media` re-mints one
196
+ for as long as the object exists. The variables this server reads for it are injected by the
197
+ host: `MCP_BLOB_BASE_URL` and `MCP_BLOB_SIGNING_KEY`.
195
198
 
196
199
  **Prompts are stored too.** Each generated object on a hosted deployment gets a small JSON
197
200
  record beside it holding the prompt (first 500 characters), model and interaction id — that is
198
201
  what `gemini_list_recent_media` shows and what lets a lost turn be recovered. The record lives
199
- and is swept with its object, so it is kept for the same `MEDIA_TTL_DAYS` window, not longer.
202
+ and is swept with its object, so it is kept for the same retention window, not longer.
200
203
  Locally, `gemini_interact` writes an `<image>.json` sidecar (model, interaction id, options and
201
204
  any text the model replied with — not the prompt itself) next to each image in the output dir;
202
205
  those files are yours to keep or delete and never expire on their own. If your
@@ -279,12 +282,12 @@ SVG is a scriptable document and `/media` serves from the server's own origin. T
279
282
  `r2_key` is then usable three ways: directly as `images_r2_keys` on any generation tool (the
280
283
  server reads its own bucket — no bytes in the conversation), permanently via
281
284
  `gemini_save_character`, or as a ~48h Files API reference via `gemini_upload_file({ r2_key })`.
282
- Uploads themselves follow the media retention schedule (`up/` prefix, default 7 days).
285
+ Uploads themselves follow the host's blob-store retention schedule (`up/` prefix).
283
286
 
284
287
  ### Character & style library (hosted)
285
288
 
286
- Recurring subjects and styles can be saved once, per account, with **no expiry** (the retention
287
- cron deliberately skips the library's `lib/` prefix):
289
+ Recurring subjects and styles can be saved once, per account, with **no expiry** (the library's
290
+ `lib/` objects are written retention-exempt, so the host's prune skips them):
288
291
 
289
292
  ```jsonc
290
293
  // once: