@chrischall/gemini-mcp 0.2.0 → 0.4.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": "0.2.0"
10
+ "version": "0.4.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": "0.2.0",
18
+ "version": "0.4.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": "0.2.0",
4
+ "version": "0.4.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/.mcp.json CHANGED
@@ -6,7 +6,8 @@
6
6
  "env": {
7
7
  "GEMINI_API_KEY": "${GEMINI_API_KEY}",
8
8
  "GEMINI_IMAGE_MODEL": "${GEMINI_IMAGE_MODEL}",
9
- "GEMINI_OUTPUT_DIR": "${GEMINI_OUTPUT_DIR}"
9
+ "GEMINI_OUTPUT_DIR": "${GEMINI_OUTPUT_DIR}",
10
+ "GEMINI_INPUT_DIR": "${GEMINI_INPUT_DIR}"
10
11
  }
11
12
  }
12
13
  }
package/README.md CHANGED
@@ -11,6 +11,7 @@ Developed and maintained by AI (Claude Code).
11
11
  | `GEMINI_API_KEY` | Yes | Your Google Gemini API key ([aistudio.google.com/apikey](https://aistudio.google.com/apikey)) |
12
12
  | `GEMINI_IMAGE_MODEL` | No | Override the default image model (default: `gemini-3-pro-image`) |
13
13
  | `GEMINI_OUTPUT_DIR` | No | Default directory for generated images (default: current working directory) |
14
+ | `GEMINI_INPUT_DIR` | No | Directory to resolve bare input-image filenames against (so `images: ["foo.jpg"]` works) |
14
15
 
15
16
  ## Tools
16
17
 
@@ -20,6 +21,7 @@ Developed and maintained by AI (Claude Code).
20
21
  | `gemini_generate_image` | Generate image(s) from a text prompt |
21
22
  | `gemini_edit_image` | Edit or compose one or more input images with a text instruction |
22
23
  | `gemini_generate_set` | Generate a master image plus N consistent images referencing it |
24
+ | `gemini_interact` | Multi-turn generation/editing via the Interactions API (Beta); returns an `interaction_id` to refine the same image conversationally |
23
25
 
24
26
  ## Quick Start
25
27
 
package/SKILL.md CHANGED
@@ -71,6 +71,7 @@ Note: Image generation requires a billing-enabled Google Cloud project.
71
71
  | `GEMINI_API_KEY` | Yes | Your Google Gemini API key |
72
72
  | `GEMINI_IMAGE_MODEL` | No | Override the default image model (default: `gemini-3-pro-image`) |
73
73
  | `GEMINI_OUTPUT_DIR` | No | Default directory for saved images (default: current working directory) |
74
+ | `GEMINI_INPUT_DIR` | No | Directory to resolve bare input-image filenames against (e.g. point at Cowork's `uploads/` folder so `images: ["house.jpg"]` works) |
74
75
 
75
76
  ## Tools
76
77
 
@@ -82,9 +83,14 @@ Note: Image generation requires a billing-enabled Google Cloud project.
82
83
  ### Image Generation
83
84
  | Tool | Description |
84
85
  |------|-------------|
85
- | `gemini_generate_image(prompt, count?, model?, aspect_ratio?, image_size?, output_dir?, inline?)` | Generate image(s) from a text prompt |
86
- | `gemini_edit_image(prompt, images[], model?, aspect_ratio?, image_size?, output_dir?, inline?)` | Edit or compose one or more input images with a text instruction |
87
- | `gemini_generate_set(master_prompt, scenes? \| count?, reference_mode?, model?, ...)` | Generate a master image plus N consistent images referencing it |
86
+ | `gemini_generate_image(prompt, count?, images?, images_base64?, video_url?, google_search?, seed?, filename?, model?, aspect_ratio?, image_size?, thinking_level?, output_dir?, inline?)` | Generate image(s) from a text prompt (optionally image-conditioned via `images`/`images_base64`, or video-conditioned via `video_url`) |
87
+ | `gemini_edit_image(prompt, images?, images_base64?, google_search?, seed?, filename?, model?, aspect_ratio?, image_size?, thinking_level?, output_dir?, inline?)` | Edit or compose input image(s) — by **path** (`images`) or **value** (`images_base64`: data URI or raw base64) — with a text instruction. Requires ≥1 input |
88
+ | `gemini_generate_set(master_prompt, scenes? \| count?, reference_mode?, master_images?, master_images_base64?, google_search?, seed?, basename?, model?, thinking_level?, ...)` | Master image (optionally seeded from a reference photo) plus N consistent images referencing it |
89
+
90
+ ### Multi-turn (Interactions API — Beta)
91
+ | Tool | Description |
92
+ |------|-------------|
93
+ | `gemini_interact(input, previous_interaction_id?, images?, images_base64?, video_url?, google_search?, model?, aspect_ratio?, image_size?, thinking_level?, filename?, output_dir?, inline?)` | Generate/edit via Gemini's **Interactions API**. Returns an `interaction_id`; pass it back as `previous_interaction_id` to **iteratively refine the same image** conversationally — the recommended way to make incremental edits. Output is **JPEG**. (Beta API.) |
88
94
 
89
95
  ## Workflows
90
96
 
@@ -124,12 +130,60 @@ gemini_generate_set(
124
130
  → returns master + 5 variations
125
131
  ```
126
132
 
133
+ **Use a reference photo by value (when you have the bytes):**
134
+ ```
135
+ gemini_edit_image(
136
+ prompt: "place this house on a vintage travel-poster background",
137
+ images_base64: ["data:image/jpeg;base64,/9j/4AAQ..."] // or raw base64
138
+ )
139
+ → returns path to the edited image
140
+ ```
141
+ `images_base64` is for bytes you actually have — a file you `Read`/encode, a URL
142
+ you fetch, or a `data:` URI the user pastes as **text**.
143
+
144
+ **Iterate on ONE image conversationally (multi-turn):**
145
+ ```
146
+ r1 = gemini_interact(input: "a cozy reading nook, watercolor")
147
+ → { images: [...], interaction_id: "v1_abc…" }
148
+ r2 = gemini_interact(input: "add a sleeping cat on the chair",
149
+ previous_interaction_id: r1.interaction_id)
150
+ → refined image that preserves r1; returns a NEW interaction_id
151
+ ```
152
+ Prefer this over re-running `gemini_edit_image` when you're making a *series* of incremental edits — the model keeps the prior result in context.
153
+ **⚠️ Chat-pasted/attached images can't be fed to these tools directly.** A pasted
154
+ image reaches the assistant as a *vision* block — the assistant can SEE it but
155
+ never receives the original bytes, and the host doesn't write it to disk. So
156
+ neither `images` (no file exists) nor `images_base64` (the bytes can't be
157
+ reconstructed from a downscaled vision rendering) is obtainable from a paste.
158
+ To use a real reference photo, the **user** must make the bytes available: save
159
+ the file and give its **path** (→ `images`), drop it into the project dir, paste
160
+ it as a **`data:` URI in text**, or host it at a **URL** (fetch → base64 →
161
+ `images_base64`). This is a host/Cowork limitation, not an MCP one.
162
+
163
+ Two built-in ways to get past the unreachable-paste problem without any manual
164
+ extraction:
165
+ - **`from_clipboard: true`** (macOS) — the tool reads the image off the system
166
+ clipboard itself (osascript), downscales it, and uses it. The user just needs
167
+ to **copy** the image (⌘C — distinct from pasting it inline into chat, which
168
+ doesn't keep it on the clipboard). Works on every image tool:
169
+ `gemini_edit_image(prompt: "…", from_clipboard: true)`.
170
+ - **`GEMINI_INPUT_DIR`** — point it at a folder (e.g. Cowork's `uploads/`); then a
171
+ **bare filename** resolves against it: `gemini_edit_image(prompt: "…", images: ["house.jpg"])`.
172
+
127
173
  ## Notes
128
174
 
129
- - `output_dir` per-call overrides `$GEMINI_OUTPUT_DIR` which overrides the current working directory
130
- - `inline: true` returns image bytes directly in the response instead of writing to disk
131
- - `count` and `scenes` are mutually exclusive in `gemini_generate_set`
132
- - `reference_mode: "chain"` makes each scene reference the previous image (vs. all referencing master)
133
- - Aspect ratios: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `2:3`, `3:2`, and others
134
- - Image sizes: `1K`, `2K`, `4K`
135
- - Server logs to stderr only — stdout is reserved for JSON-RPC
175
+ - **Input images** accept either file **paths** (`images` / `master_images`) or **base64/data-URI values** (`images_base64` / `master_images_base64`).
176
+ - **`seed`** makes a result reproducible; it's echoed in the result metadata (a random one is chosen + echoed when omitted). `count>1` uses `seed, seed+1, …` so the images differ. Determinism isn't fully guaranteed by the model.
177
+ - **`filename`/`basename`** set the output name (extension stripped); names never overwrite (a `-2`, `-3` suffix is added). The result echoes the absolute path(s), `model`, `seed`, and aspect/size.
178
+ - **No edit-strength control.** Gemini exposes no denoise/strength knob, and Nano Banana over-preserves the input — big structural edits ("move/remove/shrink", add a mat border) are often ignored. Workarounds: reroll with a different `seed`, raise `thinking_level` to `high`, use forceful wording, do layout changes (padding/borders) externally, or use `gemini_interact` multi-turn.
179
+ - **`thinking_level`** (`minimal`/`high`, Gemini 3 models) controls reasoning depth — `high` can improve complex compositions/edits at higher latency/cost.
180
+ - **Model text.** When the model returns a caption/explanation (mostly Gemini 3 **Pro**), it's surfaced as `text` in the result metadata.
181
+ - **`google_search: true`** grounds the image in live Google Search (current events, weather, real data — great for infographics). The result metadata includes `grounding` with the `queries` run and the `sources` (`{uri, title}`) used. (`gemini_interact` surfaces `grounding.queries` only — the Interactions API returns no clean source list.)
182
+ - **`video_url`** (a public YouTube URL, on `gemini_generate_image` / `gemini_interact`) generates an image from a video reference — **requires a Flash model** (e.g. `model: "gemini-3.1-flash-image"`). Non-YouTube video (Files API upload) is not supported.
183
+ - **`gemini_interact`** is the multi-turn path: it returns an `interaction_id`; thread it back via `previous_interaction_id` for conversational refinement. Output is **JPEG only**. It's a **Beta** API (separate from the stable `generate`/`edit`/`set` tools).
184
+ - `output_dir` per-call overrides `$GEMINI_OUTPUT_DIR` overrides cwd. `inline: true` returns bytes (with a metadata text block) instead of writing.
185
+ - `count` and `scenes` are mutually exclusive in `gemini_generate_set`; `reference_mode: "chain"` references the previous image instead of the master.
186
+ - Aspect ratios: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `2:3`, `3:2`, … · Image sizes: `512` (0.5K, Flash only), `1K`, `2K`, `4K`. `4K` is the max native output — true 18×24 in @ 300 DPI (5400×7200) needs an external upscale step.
187
+ - All generated images carry a **SynthID** watermark (Google).
188
+ - The model can mis-render text/Roman numerals (e.g. years) — verify any text in the output; it's a model limitation, not a tool setting.
189
+ - Server logs to stderr only — stdout is reserved for JSON-RPC.