Skip to main content

Yes, Claude Code Can Generate Images — Calling Images 2.0 via OpenAI's Official Codex Plugin (+ 4 Pitfalls and a Delegation Design)

Cover image for Yes, Claude Code Can Generate Images — Calling Images 2.0 via OpenAI's Official Codex Plugin (+ 4 Pitfalls and a Delegation Design)

TL;DR

Update, June 20, 2026: After publishing this article, I found a frequent failure — in some sessions the Bash approval for Agent(codex:codex-rescue) gets denied, so image generation is never reached. I’ve added the cause and the workaround (a fallback where the parent runs the same generation directly) in the “Addendum” at the end.

Introduction

Claude Code is my daily driver, so honestly I had no idea you could “call Images 2.0 via Codex this easily.”

Claude Code can generate images and video too — just wire up an MCP like HiggsField. But that burns credits, so it’s not well suited to the casual workflow of cranking out a bunch of rough drafts.

Images 2.0 (OpenAI’s latest image generation model, GPT Image 2), on the other hand, is high quality and useful in lots of places: web design mockups, article banners, diagrams. Being able to call it casually would be genuinely handy.

And it turns out the entry point was already officially available.

Conclusion: You Can Call Images 2.0 from Claude Code

Given up on generating images in Claude Code? It turns out that just installing the Codex plugin that OpenAI ships officially, openai/codex-plugin-cc, gives you access to imagegen (OpenAI’s latest image generation model, Images 2.0 / GPT Image 2) from inside Claude Code. You can generate images from Claude Code indirectly.

Delegation flow diagram showing Claude Code (Anthropic) handing off to Codex CLI (OpenAI), then through imagegen to Images 2.0

Claude Code (parent agent, Anthropic)
   └─ Delegates to the codex:codex-rescue subagent (via Agent)
       └─ Codex CLI (child agent, OpenAI)
           └─ imagegen skill → Images 2.0

The very setup — OpenAI shipping an official plugin on top of competitor Anthropic’s Claude Code — is interesting in itself. Released 2026-03-30, with over 21,000 stars at the time of writing (June 16, 2026). If you use AI tooling across providers, knowing about this widens your options.

Why This Is Nice

Claude Code has a layered extension mechanism — plugin / skill / agent / subagent — and routing through the Codex plugin lets you pass work from an Anthropic-side agent (Claude) to an OpenAI-side agent (Codex).

In other words, “I got image generation working” is the tip of the iceberg. The real point is that an entry point for cross-provider delegation is already officially provided.

From Here On, It’s About Using It Smoothly

Between “you can call it” and “you can use it smoothly” there were 4 pitfalls. In chronological order, I’ll share how I knocked each one down and how I ultimately distilled them into my own skill, codex-image-gen.


Pitfall 1: It Dies Silently in the Background

At first I naively asked /codex:rescue to “turn this diagram into an image.”

The reply:

I'll use the imagegen skill

And then — nothing happened.

Cause

Depending on the situation, the Codex rescue subagent launches with --background (fork) by default. The forked child process can’t be tracked by Claude Code’s harness, and no completion notification arrives. It’s the classic “one side is running off in the background on its own” failure mode you see in LLM integrations.

Fix

Make the delegation prompt explicitly state “don’t go to the background; run in the foreground all the way to completion.” That alone changes the behavior.


Pitfall 2: Sandbox Path Restrictions

On my second attempt — this time stating “run to completion in the foreground” — the image generation itself succeeded. But saving to the specified ~/Downloads/example-image.png gave:

Operation not permitted

Cause

The Codex CLI runs by default in a workspace-write sandbox, and what it can write is limited to its own workspace (the working directory where the session started). Something like ~/Downloads, directly under the home directory, is outside the workspace, so naturally it gets rejected. (You can widen the write targets by adding writable_roots in the config, but in this article I take the approach of having the parent do the cp.)

Fix

Put “if you can’t write, save inside the workspace and report the absolute path” into the delegation prompt. With that, Codex saves inside the workspace (e.g., /path/to/workspace/generated/codex-image-xxx.png) and returns the absolute path in its completion report.

After that, the parent agent (Claude Code side) rescues the file to the destination path with cp. Crossing the sandbox boundary is the parent’s job — that’s the division of labor.

cp /path/to/workspace/generated/codex-image-xxx.png ~/Downloads/example-image.png

In my measurements each image was around 1–2 MB (2,378,465 bytes in the case described later).


Pitfall 3: CJK Garbling

When I put Japanese into a technical diagram’s labels, “複雑” (complex) came out garbled as “霊等”. Images 2.0 is weak at long CJK labels, and it falls apart especially when characters are densely packed, as in technical diagrams.

Fix (with a trade-off)

I settled on this approach: for text-heavy technical diagrams, also produce a Mermaid version as the canonical source of truth, and use the Codex image as an auxiliary “good-looking version.”

Use caseRecommendation
Text-heavy technical diagrams (architecture, sequence diagrams)Mermaid as the source of truth; Codex image for decoration
Single illustrations with little text (illustrations, thumbnails)Codex alone is fine
You really want CJK in the imageLimit to English alongside, or short labels

It’s a straightforward trade-off: Mermaid is accurate but looks formulaic, while the Codex image looks great but has lower text fidelity.


Pitfall 4 (the biggest): Skill(codex:rescue) Hangs

Working around the three pitfalls with hand-written prompts every time got tedious, so I decided to bundle them into a custom skill called codex-image-gen. And right here I stepped on the biggest pitfall.

What I Did

In the first version of the skill, I wrote the delegation phase like this:

Skill(skill="codex:rescue", args={prompt: "..."})

Intuitively I thought I was just “calling the official slash command with the Skill tool.” When I ran it:

Launching skill: codex:rescue

…stayed displayed, and it was, by any feel, “clearly taking way too long.” All I could do was abort from the user side, and no image ever got generated.

Cause: It Was Explicitly Forbidden in the Official Docs

Re-reading ~/.claude/plugins/cache/openai-codex/codex/{version}/commands/rescue.md, the iron rule for how to call it was spelled out clearly.

How to callResult
Skill(codex:rescue)NG — re-enters this command and the session hangs
Skill(codex:codex-rescue)NG — no such skill exists
Agent(subagent_type="codex:codex-rescue", prompt=...)OK — the correct way

The reason is structural. codex:rescue is a slash command, and internally it launches the real subagent codex:codex-rescue via the Agent tool. If you call Skill(codex:rescue) from a Claude skill into that, the slash command gets invoked recursively, the internal state can’t be resolved, and it hangs.

Why I Missed It

The culprit was that the name /codex:rescue and the Skill tool’s “you can call slash commands” capability superficially appear to line up. codex:rescue (slash command) and codex:codex-rescue (subagent) are in separate namespaces: the former is the window you knock on, and the latter is what a custom skill should call. The cause of my defeat was designing it from the general theory of the Skill tool without reading the official repo.

Fix

I rewrote the delegation phase from Skill() to Agent().

Before (NG):

Skill(skill="codex:rescue", args={prompt: "<delegation prompt>"})

After (OK):

Agent(subagent_type="codex:codex-rescue", prompt="<delegation prompt>")

The diff is small, but it’s a fundamental change from “via slash command” to “calling the subagent directly.” To prevent a recurrence, I put “no calling via Skill, must go via Agent” at the very top of the skill’s “guardrails.”


Verification After the Fix

With the fixed skill I tried generating a single vertical (9:16) illustration. Here’s the processing flow and the actual measurements:

Codex generates the image with imagegen (about 9 min / 539,756 ms)

Saves inside the workspace (2,378,465 bytes)
  /path/to/workspace/generated/codex-image-xxx.png

Parent agent rescues it to the destination Downloads directory with cp

Parent opens it with Read for a visual check → drawing elements nearly perfect

The spec was “no text inside the image,” so the CJK garbling risk was zero. Conversely, if you do want to include CJK, the Pitfall 3 trade-off still applies.


Delegation Prompt Template (Copy-Paste Ready)

I’ll paste the template I actually use, as is. These are the prerequisite-check and delegation parts.

Prerequisite Check

# Check that the Codex plugin exists
ls ~/.claude/plugins/cache/openai-codex/codex/
# v1.0.4 or later recommended
# If it's not installed, see https://github.com/openai/codex-plugin-cc

Delegating to Codex (how to call it)

Agent(
  subagent_type="codex:codex-rescue",
  prompt=<the delegation prompt template below>
)

Do not use Skill(codex:rescue) here. It’s forbidden in the official commands/rescue.md (see Pitfall 4 for the reason).

The Delegation Prompt Template Itself

[Task]
{Describe the use case, drawing elements, style, and aspect ratio here}

[Save destination]
{Absolute path. Example: ~/Downloads/example-image.png}

[Steps]
1. Generate the image with Images 2.0 / imagegen.
2. Save it to the destination path above. If you can't write, save inside the workspace and report that absolute path.
3. Verify the file exists and its size with `ls -la {destination path}`.
4. Include the file's absolute path and byte count in the completion report.

[Important — strictly follow]
- Do not go to the background; run in the foreground all the way to completion.
- Report only after finishing the save and the ls -la check (don't stop midway).
- If you include Japanese text, render it accurately. If you're worried CJK characters will break, including English alongside is fine.
- Don't stop the moment you call the imagegen skill; carry it through to the end.

Parent-Side Rescue, Verification, and Visual Check (pseudocode)

# 1. Cross-sandbox rescue
if (Codex's completion report returns an in-workspace path):
    cp {in-workspace path} {user's desired path}

# 2. Real verification
ls -la {user's desired path}
# Confirm the size is non-zero and the file exists

# 3. Visual inspection
Read({user's desired path})
# If there's CJK garbling, offer to regenerate / use the English version / switch to Mermaid

Addendum: In Some Sessions, the Bash Approval for Agent Gets Denied

After publishing this article, this was the failure I hit most. Even when you delegate the correct way with Agent(subagent_type="codex:codex-rescue", ...), it can whiff without ever reaching image generation.

Symptom

The parent (main loop) Bash works, but only the Agent subagent’s Bash gets denied every time. That asymmetry is the decisive sign. It comes back after tens of seconds with nothing happening — no trace that Codex ran (no imagegen output, no save report).

Cause

In sessions where Agent() is launched in the background (async), the background subagent can’t surface an interactive approval prompt. So a Bash call that needs approval gets auto-denied for “no approver present.” This is session-dependent — the same steps can go through in another session.

Two things to note:

Fix: Have the Parent Run the Same Generation Directly (fallback)

codex:codex-rescue is just firing a single raw companion command internally, so having the parent run that directly in the foreground is equivalent. The decisive difference: with the parent’s main-loop Bash, the approval prompt is visible to the user — so you can approve it on the spot.

# Resolve the absolute path of the installed companion (latest version)
CODEX_DIR=$(ls -d ~/.claude/plugins/cache/openai-codex/codex/*/ | sort -V | tail -1)
COMPANION="${CODEX_DIR}scripts/codex-companion.mjs"

# Pass the full image-generation prompt you would have handed to Agent
node "$COMPANION" task "<full delegation prompt>" --write

When Even the Parent’s node Gets Denied

Don’t fall into a question loop — recover with one of these:


Summary

Even though Claude Code alone can’t create images, you can generate them by delegating to Images 2.0 via OpenAI’s official Codex plugin. But the key to making it production-ready was less about image generation itself and more about the etiquette of delegation.

References

ZSL
ZSL

AI Engineer

Researching and practicing development workflows powered by Generative AI.