@chrischall/gemini-mcp 1.4.0 → 1.5.0
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +64 -1
- package/dist/bundle.js +330 -27
- package/dist/client.js +6 -0
- package/dist/inputs.js +37 -1
- package/dist/jobs.js +46 -2
- package/dist/library.js +151 -0
- package/dist/media-cleanup.js +4 -1
- package/dist/media-endpoint.js +6 -0
- package/dist/media-url.js +2 -2
- package/dist/put-endpoint.js +122 -0
- package/dist/storage/media.js +23 -12
- package/dist/tools/generate.js +34 -10
- package/dist/tools/interact.js +3 -2
- package/dist/tools/library.js +186 -0
- package/dist/tools/music.js +3 -2
- package/dist/tools/set.js +37 -9
- package/dist/tools/shared.js +195 -2
- package/dist/tools/uploads.js +69 -0
- package/dist/tools/video.js +3 -2
- package/dist/upload-url.js +138 -0
- package/dist/version.js +1 -1
- package/dist/zip.js +113 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -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": "1.
|
|
10
|
+
"version": "1.5.0"
|
|
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": "1.
|
|
18
|
+
"version": "1.5.0",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/README.md
CHANGED
|
@@ -87,6 +87,18 @@ progress), two guards make re-issuing safe and unnecessary:
|
|
|
87
87
|
| `gemini_list_files` | List the files currently uploaded under this API key, with MIME types and expiry times |
|
|
88
88
|
| `gemini_delete_file` | Delete an uploaded file before its ~48h expiry (confirm-gated) |
|
|
89
89
|
| `gemini_sign_media` | *(hosted connector only)* Mint a fresh signed URL for generated media from its `r2_key` — an expired link is not a dead end |
|
|
90
|
+
| `gemini_get_upload_url` | *(hosted connector only)* Mint a short-lived signed PUT URL so a shell can upload a reference image with no auth header; the PUT returns an `r2_key` usable in `images_r2_keys`, `gemini_save_character`, or `gemini_upload_file` |
|
|
91
|
+
| `gemini_save_character` / `gemini_list_characters` / `gemini_delete_character` | *(hosted connector only)* Persistent per-account character library: save a reference image + description under a name, then pass `characters: ["name"]` on generation tools. No expiry |
|
|
92
|
+
| `gemini_save_style` / `gemini_list_styles` / `gemini_delete_style` | *(hosted connector only)* Persistent per-account style presets: a reusable prompt fragment (optionally with a reference image), applied by passing `style: "name"` on generation tools. No expiry |
|
|
93
|
+
|
|
94
|
+
Generation tools also share three throughput/latency controls: `async: true` (return a `job_id`
|
|
95
|
+
immediately), `max_wait_ms` (wait up to a budget, then hand back the `job_id` — fast results stay
|
|
96
|
+
in-band, slow batches never trip the host timeout), and `idempotency_key` (a retry returns the
|
|
97
|
+
recorded result instead of re-billing). On the hosted connector, a `gemini_image_set` result with
|
|
98
|
+
more than one image also carries a **`bundle_url`** — one signed URL for a zip of every image in
|
|
99
|
+
the set — and set links are signed for ~7 days instead of the default ~48h. (A set too large to
|
|
100
|
+
zip safely in Worker memory skips the bundle and says so via `bundle_skipped`; the per-image
|
|
101
|
+
links are unaffected.)
|
|
90
102
|
|
|
91
103
|
## Seeing your images (hosted connector)
|
|
92
104
|
|
|
@@ -150,7 +162,7 @@ safe form, and a markdown link is a reasonable enhancement where you know it ren
|
|
|
150
162
|
|
|
151
163
|
| Variable | Default | Effect |
|
|
152
164
|
|---|---|---|
|
|
153
|
-
| `MEDIA_TTL_DAYS` | `7` | Objects older than this are deleted by a daily cron
|
|
165
|
+
| `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 |
|
|
154
166
|
| `MEDIA_URL_SECRET` | generated | HMAC key for `/media` links; rotate to revoke all outstanding URLs |
|
|
155
167
|
| `MEDIA_PUBLIC_BASE_URL` | unset | Serve from R2 directly instead of the Worker route |
|
|
156
168
|
|
|
@@ -167,7 +179,9 @@ Every tool that takes a reference image — `gemini_image_generate`, `gemini_ima
|
|
|
167
179
|
|---|---|---|
|
|
168
180
|
| `images_url` (`master_images_url`) | the **server** downloads the https URL | none |
|
|
169
181
|
| `images_file_uris` (`master_images_file_uris`) | a `files/<id>` reference, already uploaded | none |
|
|
182
|
+
| `images_r2_keys` (`master_images_r2_keys`) | the connector reads its **own store** (hosted connector only) | none |
|
|
170
183
|
| `images` | read off local disk (stdio builds only) | none |
|
|
184
|
+
| `characters` / `style` | saved library entries, attached by name (hosted connector only) | none |
|
|
171
185
|
| `images_base64` | **through the tool-call JSON** | **~14k tokens per JPEG** |
|
|
172
186
|
|
|
173
187
|
`images_base64` is the fallback of last resort. It costs roughly 14k tokens per modest photo,
|
|
@@ -228,6 +242,55 @@ straight to the Files API (nothing is buffered), so `Content-Length` is required
|
|
|
228
242
|
automatically with `--data-binary @file`. Accepted content types are `image/*`, `video/*` and
|
|
229
243
|
`audio/*`; an optional `?name=` or `X-Filename` header sets the display name.
|
|
230
244
|
|
|
245
|
+
### Signed upload URLs — no token at all (hosted connector)
|
|
246
|
+
|
|
247
|
+
`POST /upload` needs the MCP session's OAuth bearer token, which a sandboxed shell often does
|
|
248
|
+
not have. `gemini_get_upload_url` closes that gap: the authenticated MCP session mints a
|
|
249
|
+
short-lived (~10 min) signed **PUT** URL, and the shell uploads with zero auth headers — the
|
|
250
|
+
signature in the URL is the authorization, mirroring how `/media` downloads work.
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# 1. tool call: gemini_get_upload_url { filename: "photo.jpg", content_type: "image/jpeg" }
|
|
254
|
+
# → { upload_url, r2_key, expires_at, curl_hint }
|
|
255
|
+
|
|
256
|
+
# 2. shell:
|
|
257
|
+
curl -sS -X PUT -H "Content-Type: image/jpeg" --data-binary @photo.jpg "$UPLOAD_URL"
|
|
258
|
+
# → { "r2_key": "up/<tenant>/2026-07-31/ab12cd34-photo.jpg", "size_bytes": 812345, ... }
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The signature covers one tenant-scoped object key, the declared content type and the expiry;
|
|
262
|
+
uploads are capped at 15MB, enforced while reading the stream. Only **raster** image types are
|
|
263
|
+
accepted (jpeg/png/webp/gif/avif/heic/heif/bmp/tiff) — SVG is deliberately refused, because an
|
|
264
|
+
SVG is a scriptable document and `/media` serves from the connector's own origin. The returned
|
|
265
|
+
`r2_key` is then usable three ways: directly as `images_r2_keys` on any generation tool (the
|
|
266
|
+
server reads its own bucket — no bytes in the conversation), permanently via
|
|
267
|
+
`gemini_save_character`, or as a ~48h Files API reference via `gemini_upload_file({ r2_key })`.
|
|
268
|
+
Uploads themselves follow the media retention schedule (`up/` prefix, default 7 days).
|
|
269
|
+
|
|
270
|
+
### Character & style library (hosted connector)
|
|
271
|
+
|
|
272
|
+
Recurring subjects and styles can be saved once, per account, with **no expiry** (the retention
|
|
273
|
+
cron deliberately skips the library's `lib/` prefix):
|
|
274
|
+
|
|
275
|
+
```jsonc
|
|
276
|
+
// once:
|
|
277
|
+
{ "tool": "gemini_save_character", "name": "finn",
|
|
278
|
+
"description": "6-year-old boy, curly red hair", "image_r2_key": "up/…/photo.jpg" }
|
|
279
|
+
{ "tool": "gemini_save_style", "name": "bold-cartoon-sports",
|
|
280
|
+
"prompt_fragment": "bold cartoon style, thick outlines, saturated colors" }
|
|
281
|
+
|
|
282
|
+
// afterwards, on any generation:
|
|
283
|
+
{ "tool": "gemini_image_set",
|
|
284
|
+
"master_prompt": "Finn on a soccer field",
|
|
285
|
+
"scenes": ["kicking the ball", "celebrating a goal"],
|
|
286
|
+
"characters": ["finn"], "style": "bold-cartoon-sports" }
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Naming a character attaches its saved reference image and weaves its description into the
|
|
290
|
+
prompt; naming a style appends its fragment (and attaches its reference image, if it has one).
|
|
291
|
+
`gemini_image_set` passes character references to the master *and every scene call*, which is
|
|
292
|
+
what keeps the subject consistent across the set.
|
|
293
|
+
|
|
231
294
|
## Quick Start
|
|
232
295
|
|
|
233
296
|
```json
|