Codimage is a local Codex image-generation bridge. It uses a logged-in ChatGPT session in Chrome, driven through Chrome DevTools Protocol, to generate images and save them into a project as PNG files.
It does not call the OpenAI Images API and does not use OPENAI_API_KEY.
- A CLI for testing the browser runner:
codimage - An MCP stdio server for Codex:
codimage-mcp - Repeatable Chrome profile handling for ChatGPT login state
- Single-image and JSONL batch generation through ChatGPT Images
- Explicit output paths so generated assets land in the active project
ChatGPT's web UI can change, so this is best-effort browser automation. If a
selector breaks, update src/codimage/browser.py.
From this repo:
uv run codimage openLog in to ChatGPT in the Chrome window that opens. Codimage opens the dedicated
ChatGPT Images page at https://chatgpt.com/images and uses a separate Chrome
profile at:
~/.codex/codimage/chrome-profile
Check that the Chrome DevTools endpoint is reachable:
uv run codimage statusGenerate one image:
uv run codimage generate \
--prompt "Create one square watercolor storybook illustration of a glowing castle garden. No text, no letters, no watermark." \
--out /tmp/codimage-test.png \
--overwriteRun a small batch:
uv run codimage batch \
--input examples/jobs.jsonl \
--project-root "$PWD" \
--count 2 \
--overwriteBatch generation combines up to 10 selected jobs into one ChatGPT Images submission by sending a numbered multi-image prompt. Larger selections are split into additional submissions of up to 10 images each.
Point Codex at this repo's MCP entry point.
TOML-style config:
[mcp_servers.codimage]
command = "uv"
args = ["--directory", "/Volumes/EXT/Applications/codimage", "run", "codimage-mcp"]JSON-style config:
{
"mcpServers": {
"codimage": {
"command": "uv",
"args": ["--directory", "/Volumes/EXT/Applications/codimage", "run", "codimage-mcp"]
}
}
}After restarting Codex, the server exposes these tools:
codimage_open_chromecodimage_statuscodimage_generate_imagecodimage_generate_batchcodimage_generate_job_file
For MCP calls, use absolute output paths or pass project_root with relative
paths. Codimage refuses implicit relative writes from MCP so images do not land
inside the tool repo by accident.
Use JSONL with one object per image:
{"prompt": "Create one square watercolor puppy princess scene. No text.", "out": "media/generated/page_01.png"}
{"prompt": "Create one square cozy moonlit meadow scene. No text.", "out": "media/generated/page_02.png"}Then call:
uv run codimage batch \
--input /path/to/jobs.jsonl \
--project-root /path/to/project \
--start 1 \
--count 2codimage open starts Chrome with:
--remote-debugging-port=9222
--user-data-dir=~/.codex/codimage/chrome-profile
The opened page is:
https://chatgpt.com/images
The default CDP endpoint is:
http://127.0.0.1:9222
You can override it with --cdp-url in the CLI or the cdp_url MCP argument.
Codimage currently looks for the ChatGPT composer using #prompt-textarea,
visible contenteditable textboxes, and visible textarea fallbacks. Generated
image detection snapshots existing page images before submitting the prompt, then
waits for new image candidates from ChatGPT/OpenAI image hosts, blob URLs, or
data URLs.
uv run python -m compileall src
uv run python -m unittest discover
uv run codimage --help
uv run python -c "from codimage.server import mcp; print('server import ok')"For the intended use case and tradeoffs behind browser-mediated image generation,
see docs/browser-mcp-image-generation-paper.md.