@chrischall/gemini-mcp 1.0.3 → 1.1.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.
@@ -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.0.3"
10
+ "version": "1.1.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.0.3",
18
+ "version": "1.1.0",
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": "1.0.3",
4
+ "version": "1.1.0",
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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![npm](https://img.shields.io/npm/v/@chrischall/gemini-mcp)](https://www.npmjs.com/package/@chrischall/gemini-mcp)
5
5
  [![license](https://img.shields.io/npm/l/@chrischall/gemini-mcp)](LICENSE)
6
6
 
7
- MCP server for Google Gemini media generation. Exposes eight 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), and an async result poll for long generations. 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.
7
+ 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.
8
8
 
9
9
  Developed and maintained by AI (Claude Code).
10
10
 
@@ -83,6 +83,79 @@ progress), two guards make re-issuing safe and unnecessary:
83
83
  | `gemini_video_generate` | Generate a short video (text→video, image→video, or `edit`) via the Gemini omni model (preview); written to disk as MP4 |
84
84
  | `gemini_music_generate` | Generate music from a text prompt via a Lyria model — `lyria-3-clip-preview` (~30s, default) or `lyria-3-pro-preview` (longer, WAV-capable); written to disk as MP3/WAV (preview) |
85
85
  | `gemini_get_result` | Fetch an async generation started with `async: true` by its `job_id` (status `running` → `done` result). Lets a long generation outlive a host's `tools/call` timeout |
86
+ | `gemini_upload_file` | Upload an image (or video/audio) to the Gemini Files API once — from a `url`, `data_base64`, or a local `path` — and get a reusable `files/<id>` reference |
87
+ | `gemini_list_files` | List the files currently uploaded under this API key, with MIME types and expiry times |
88
+ | `gemini_delete_file` | Delete an uploaded file before its ~48h expiry (confirm-gated) |
89
+
90
+ ## Sending reference images without burning context
91
+
92
+ Every image tool (`gemini_image_generate`, `gemini_image_edit`, `gemini_image_set`,
93
+ `gemini_interact`) takes reference images four ways. Only one of them costs model context:
94
+
95
+ | Parameter | Where the bytes travel | Context cost |
96
+ |---|---|---|
97
+ | `images_url` (`master_images_url`) | the **server** downloads the https URL | none |
98
+ | `images_file_uris` (`master_images_file_uris`) | a `files/<id>` reference, already uploaded | none |
99
+ | `images` | read off local disk (stdio builds only) | none |
100
+ | `images_base64` | **through the tool-call JSON** | **~14k tokens per JPEG** |
101
+
102
+ `images_base64` is the fallback of last resort. It costs roughly 14k tokens per modest photo,
103
+ and it is silently corrupted whenever the file read that produced it was truncated — the
104
+ payload still looks like base64, so the failure surfaces as a bad generation rather than an
105
+ error. Prefer any of the other three.
106
+
107
+ ### `images_url` — the server fetches it
108
+
109
+ ```jsonc
110
+ { "prompt": "make it look like winter", "images_url": ["https://example.com/photo.jpg"] }
111
+ ```
112
+
113
+ Fetches are restricted to public `https://` URLs — private, loopback and link-local hosts are
114
+ refused (IPv6 literals are parsed, so `[::ffff:7f00:1]` is caught as loopback), every redirect
115
+ hop is revalidated, and each hop is bounded by a timeout. The response must be
116
+ `Content-Type: image/*` and is capped at **15MB**, enforced while streaming rather than trusted
117
+ from `Content-Length`. A failure names the offending URL. Anything over 6MB is uploaded to the
118
+ Files API and referenced by uri instead of inlined, since `generateContent` caps a whole
119
+ request near 20MB.
120
+
121
+ ### `images_file_uris` — upload once, reference many times
122
+
123
+ ```jsonc
124
+ // 1. upload
125
+ { "tool": "gemini_upload_file", "url": "https://example.com/photo.jpg" }
126
+ // → { "file_uri": "files/abc123", "mime_type": "image/jpeg", "expires": "..." }
127
+
128
+ // 2. reference it, as many times as you like
129
+ { "prompt": "make it winter", "images_file_uris": ["files/abc123"] }
130
+ { "prompt": "make it sunrise", "images_file_uris": ["files/abc123"] }
131
+ ```
132
+
133
+ Uploads are retained **~48h**; after that the reference stops resolving (as a generic 404 —
134
+ see the chained-404 section above). `gemini_image_set` fetches or resolves such a reference
135
+ **once** and passes it to the master and every scene call.
136
+
137
+ On stdio builds, a local `images` path that gets referenced **more than once in a session** is
138
+ uploaded to the Files API automatically (keyed on path + mtime + size), so repeated edits of
139
+ the same photo stop re-sending the bytes. Editing the file invalidates the cached upload.
140
+
141
+ ### `POST /upload` — raw bytes, no base64 at all (hosted connector)
142
+
143
+ The hosted connector exposes an HTTP upload endpoint behind the **same OAuth token as
144
+ `/mcp`**. This is the intended path for an agent with a shell: disk file → curl → `file_uri` →
145
+ tool call, with the image never entering the conversation.
146
+
147
+ ```bash
148
+ curl -X POST https://connector.gemini.nullnet.app/upload \
149
+ -H "Authorization: Bearer $ACCESS_TOKEN" \
150
+ -H "Content-Type: image/jpeg" \
151
+ --data-binary @photo.jpg
152
+ # → {"file_uri":"files/abc123","mime_type":"image/jpeg","expires":"...","...":"..."}
153
+ ```
154
+
155
+ Then pass `"images_file_uris": ["files/abc123"]` to any image tool. The body is streamed
156
+ straight to the Files API (nothing is buffered), so `Content-Length` is required — curl sets it
157
+ automatically with `--data-binary @file`. Accepted content types are `image/*`, `video/*` and
158
+ `audio/*`; an optional `?name=` or `X-Filename` header sets the display name.
86
159
 
87
160
  ## Quick Start
88
161