img
Stores generated images, reference inputs, JSON metadata, and shared settings in an iCloud Drive library, enabling cross-Mac access and synchronization of images and IDs.
Integrates with macOS Keychain for secure API key storage and retrieval, and uses macOS image conversion for HEIC/TIFF/AVIF reference files.
Generates and refines images using OpenAI's Responses API image_generation tool, supporting model selection, variations, references, and iterative conversation-based editing.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@img4 minimalist otter logos for a coffee brand"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
img: OpenAI image generation for Claude Code
A Claude Code plugin that lets Claude generate and iterate on images with OpenAI's Responses API
(image_generation tool). It also gives you:
Variations in parallel:
/img:new 4 minimalist otter logoIteration and branching: refine any earlier image by its short id (
k7f2), not just the last oneReferences: pasted screenshots, local files, URLs or other library images
A live local gallery that opens as soon as you ask for images, shows a loading tile for each one, and fills them in as they finish
A permanent library in iCloud Drive, so every image and its id work on all your Macs
/img:new 4 minimalist otter logo → 4 variations, gallery opens with 4 loading tiles
/img:refine k7f2 thicker lines → iterate on k7f2 (keeps the OpenAI conversation context)
/img:new 2 an app UI like these [Image #1] [Image #2] → pasted images as references
/img:keep k7f2 ./public/logo.png → copy into the project (for git) and star it
/img:model flare → switch the default image model, for all sessionsYou can also just talk: "make the third one warmer", "go back to p3m9 and try a red scarf", "use ~/Desktop/moodboard.png as a reference".
Setup (once per Mac)
1. Create a dedicated OpenAI API key
Create a separate OpenAI project for this (e.g. claude-image-gen) at
https://platform.openai.com/settings/organization/projects, generate a key there, and set a monthly budget
for the project. Its costs then show up separately, and a runaway loop can't drain your main account.
A restricted key is enough. Under Permissions → Restricted, set:
Permission | Setting |
Responses ( | Request |
List models | Read (for |
everything else | None |
The Images endpoint (/v1/images) isn't needed: images are generated through the Responses API's
image_generation tool.
Image generation may require a verified organization.
2. Make the key available as OPENAI_API_KEY_FOR_CLAUDE_IMAGE_GEN
The server looks for the key in this order:
The environment variable
OPENAI_API_KEY_FOR_CLAUDE_IMAGE_GENOn macOS: a Keychain item with that same name. Recommended, because it works however Claude Code was started (terminal, Dock, VS Code), and the key never sits in a plaintext file:
Copy the key to the clipboard, then:
# -U updates an existing entry; the trailing pbcopy clears the clipboard security add-generic-password -U -a "$USER" -s OPENAI_API_KEY_FOR_CLAUDE_IMAGE_GEN -w "$(pbpaste)" && pbcopy </dev/nullDon't use the interactive form (
-wwithout a value): its prompt silently cuts input off at 128 characters, and OpenAI project keys are longer. Check withsecurity find-generic-password -s OPENAI_API_KEY_FOR_CLAUDE_IMAGE_GEN -w | wc -c(a full key gives about 165). Passing the key as an argument makes it visible topsfor the moment the command runs; on a personal Mac that's an acceptable trade-off for getting the whole key stored.Keys added this way stay in the Mac's login keychain and don't sync, so run this on each Mac.
Alternatively, export OPENAI_API_KEY_FOR_CLAUDE_IMAGE_GEN=sk-... in ~/.zshenv. Claude Code then only sees it
when started from a shell.
3. Install the plugin
In Claude Code:
/plugin marketplace add timpulver/openai-image-gen
/plugin install img@timpulverChoose user scope so it's available in every project. To get updates later, run
/plugin marketplace update timpulver.
You need Node.js ≥ 20.19 (any 22 or 24 works). The launcher also finds Homebrew, nvm, volta, fnm and vite-plus installs when Claude Code was
started without your shell's PATH.
4. Optional: a bare /img shortcut
Plugin skills are always namespaced (/img:new). To also get a plain /img that generates or refines depending on
whether you start with an id:
~/.claude/plugins/marketplaces/timpulver/bin/install-shortcut.shThen /img 4 minimalist otter logo and /img k7f2 make it warmer both work.
Related MCP server: Draw Things MCP Server
Commands
Command | What it does |
| New image(s). A leading number is the variation count (1–8). |
| Iterate on an image (default: the last one). Refining an older image starts a new branch. |
| Show the current image and mainline models, or switch them ( |
| Copy the image into the current project and star it. |
| Open the gallery. |
References: pasted images, files, URLs, ids
Pasted images (
[Image #1]): Claude passes them aspaste:1,paste:2, …, meaning images from your most recent message that contains images. Claude Code doesn't save pasted images as files, so the server reads them from the session transcript.Files: any path (
~/Desktop/a.png,./mockups/b.jpg). HEIC/TIFF/AVIF are converted automatically on macOS. Dragging a file into the terminal inserts its path.URLs: downloaded once.
Library ids:
k7f2orimg:k7f2, to use an earlier image as a style or content reference.
Every reference is copied into the library (inputs/, de-duplicated by content). That way the image's history stays
complete even after a temp file or URL is gone.
How iteration works
The Responses API runs two models. A mainline model (default gpt-6-astra) reads the conversation and calls the
image_generation tool, which runs on the image model (default gpt-image-2.5-sunburst, the more precise editor;
gpt-image-2.5-flare is faster for everyday images).
When you refine an image, the server sends the parent's previous_response_id, so the model sees the whole chain of
prompts and images. OpenAI only keeps stored responses for about 30 days. After that, or if that fails, the server
re-uploads the parent image from the library instead. Any image can always be refined, no matter how old. Each
image's details show which method was used ("continued conversation" or "parent image re-uploaded").
The library
~/Library/Mobile Documents/com~apple~CloudDocs/Claude Images/ (iCloud Drive → "Claude Images")
├── images/2026-10-05-k7f2-minimalist-otter-logo.png
├── images/2026-10-05-k7f2-minimalist-otter-logo.json ← prompt, revised prompt, parent, refs, models, OpenAI ids, usage
├── inputs/3f1c9a…e2.png ← stored reference images
└── settings.json ← default models etc., shared by all MacsgalleryPort and openGallery describe a single machine, so they're stored per Mac in
~/Library/Application Support/claude-image-gen/local.json instead.
Ids are 4 random characters mixing letters and digits (
k7f2), with no look-alike characters (0/o,1/l/i). They're random rather than sequential, so two Macs generating before iCloud syncs practically never create the same id. If it ever happens, using that id reports both files instead of picking one.One folder, date-prefixed names. Finder sorts them by date, and a few thousand files in one folder is no problem.
Each image has its own JSON sidecar and there is no shared index file. iCloud handles concurrent edits to a single file by creating
file 2.jsonconflict copies, so the server never keeps one.Offloaded files: if macOS "Optimise Mac Storage" evicts images, the server downloads them on demand. To avoid the wait, right-click the folder in Finder and choose Keep Downloaded.
Without iCloud Drive, the library goes to
~/Pictures/Claude Imagesinstead. To use a different location, setCLAUDE_IMAGE_GEN_LIBRARY=/path/to/folder.
Permanent for you, exported for everyone else
Referenced from | Use |
Your own notes, plans, handoff files, later Claude sessions on any of your Macs | the id: |
Anything committed to git or shared with others |
|
Claude is instructed to follow this rule (via the server's instructions), so library paths shouldn't end up in committed files. It's guidance to the model, not a hard check, so keep an eye on it when reviewing commits.
The gallery
http://localhost:47821 is a live view of the library, opened automatically for images you ask for:
loading tiles with timers, filled in as each image finishes; failures (e.g. moderation) show inline
click an image for full size, prompt, revised prompt, lineage (parent ↔ children), references and details
copy an id or
img:reference, star images, search, filter by starredone tab: when a new gallery tab opens, older tabs opened this way close themselves
The gallery is served by whichever Claude session started first; the other sessions forward their updates to it. To
browse without a Claude session running: node dist/server.js --gallery in this repo (or npm run gallery).
How Claude sees the results
Claude gets a preview of every generated image so it can judge the results. For details like text, hands or edges,
it uses inspect_image to zoom into a region at native resolution. Claude's vision input is limited to about
1.15 megapixels, so cropping is how fine detail actually becomes visible.
MCP tools
Tool | Purpose |
| prompt, count, |
| zoom: |
|
|
| copy into the project (converts format by extension), stars it |
| show or change persistent defaults |
| models available to your key |
| open the gallery at a batch or image |
Privacy
Prompts and reference images are sent to OpenAI. Pasted images are only read from the transcript when you reference them.
Responses are stored by OpenAI (the Responses API default,
store: true; about 30 days). Refining viaprevious_response_iddepends on that; after it expires, the parent image is re-uploaded instead.The gallery listens on
127.0.0.1only, rejects requests for other host names, and requires a custom header for writes, so websites can't post to it. Other user accounts on the same Mac can still reach it locally.
How it's built
The plugin is an MCP server (src/main.ts) plus five skills (skills/*/SKILL.md) that become the /img:…
commands. The rules Claude follows (show the gallery, use img:<id> in notes, export before committing) live in the
server's instructions. bin/run.sh finds a suitable Node.js and starts the server.
Part | Built with |
MCP server |
|
OpenAI requests | ofetch 2 on native |
Gallery | h3 v2 on |
Image previews, crops, conversion | macOS |
Bundle | Rolldown → one ESM file, |
Why dist/ is committed: Claude Code installs plugins with git clone and never runs npm install, so the
server and all its dependencies are bundled into dist/server.js and checked in. .gitattributes marks it as
generated, so GitHub hides it in diffs. The build also swaps out the MCP SDK's bundled ajv validator (unused here)
for the SDK's lighter one (src/mcp-shims.ts).
One gallery for all sessions: every Claude session runs its own server, but only the first one to bind the gallery port serves it. The others forward their updates to it over HTTP. If that session ends, the next update elects a new one.
Development
nvm use && npm install
npm run build # bundles src/ into dist/server.js (committed, so installs need no npm install)
npm test # end-to-end test against a mock OpenAI API; no key or credits needed
npm run typecheck
claude --plugin-dir . # try the plugin from this checkoutCommit dist/ after changing src/. Plugins are installed straight from git, with no build step.
Troubleshooting
"Incorrect API key provided": re-store the key with the
security add-generic-password -U … "$(pbpaste)"command above. The interactive prompt truncates keys to 128 characters. Check that the key belongs to an active project. An env var, if set, takes precedence over the Keychain."macOS blocked access to iCloud Drive": the app running Claude Code (Terminal, iTerm, VS Code, …) isn't allowed into iCloud Drive. Allow it in System Settings → Privacy & Security → Files & Folders (iCloud Drive) or Full Disk Access and restart it, or set
CLAUDE_IMAGE_GEN_LIBRARYto a folder outside iCloud Drive."macOS blocked access to the Downloads folder" (or Desktop, Documents): same cause, for a reference image. Allow the app under Files & Folders, copy the file elsewhere, or paste the image instead.
Tools don't show up: run
/mcpin Claude Code and look forplugin:img:images. If it failed, it's usually because Node.js wasn't found.Odd results or API errors: set
CLAUDE_IMAGE_GEN_DEBUG=1to keep OpenAI's raw responses (without the image data) in~/Library/Caches/claude-image-gen/debug/.Port 47821 is taken:
/img:model galleryPort 47900(or ask Claude to changegalleryPort). This only affects the current Mac.
This server cannot be deployed
Maintenance
Related MCP Connectors
- lightgenOAuthapp.lightgen
Generate and edit images and create short videos inside Claude. Prepaid credits, no subscription.
Generate AI images, video, speech, music and presentations from Claude, ChatGPT and Cursor.
Generate AI images, video, voiceovers and music from Claude, ChatGPT or Cursor through 50+ models (Veo 3.1, Kling 3, Seedance, Nano Banana, GPT Image, ElevenLabs). Also image editing, upscaling, background removal, face swap, transcription, voice cloning and UGC-style video ads. Sign in with OAuth — no API key to paste. Tools are annotated (read-only vs. credit-spending); failed generations are refunded.
Turn Claude into a creative studio: DNA-locked characters, images, video, voiceover — 55 tools.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables generating images from text prompts using OpenAI's GPT-Image-2 model within Claude Code and Codex conversations.1-
- AlicenseAqualityDmaintenanceEnables free local image generation from Claude Desktop/Claude Code using the Draw Things app on Apple Silicon Macs.4138 npm1MIT
- AlicenseAqualityBmaintenanceConnects Claude Code to image generation models (OpenAI GPT Image 2, Google Nano Banana) for generating, editing, and converting images via natural language.638 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude Code agents to generate images via the Runware API with full parameter control, exact USD cost reporting, local image saving, and a live gallery.MIT