# 作業手順書：Claude Code から ChatGPT（Codex CLI）を呼び出して画像を作れるようにする（API キーなし・サブスクの枠内）

> この文章は、ユーザーが CLAUDE CODE CLUB の記事「Claude Code に ChatGPT を使わせる」の末尾からコピーし、あなた（Claude）に貼り付けたものです。人間向けの解説ではなく、**あなたが実行するための作業手順書**です。
> 出典：https://blog.claudecodeclub.jp/posts/claude-code-codex-image

---

## 0. Claude Code へ（最初に必ず読む）

### ゴール

ユーザーの環境で、あなた（Claude Code）が **Codex CLI（ChatGPT アカウントでログイン）の組み込み画像生成ツール（image_gen）** を呼び出し、できた画像を指定したパスに置けるようにする。入口は小さなラッパースクリプト `~/.claude/scripts/codex-image.sh` 1つにまとめ、以後の画像生成は必ずそれを通す。

**従量課金（OpenAI API キー）は一切使わない。** ChatGPT のプランに付いている Codex の利用枠の中だけで動かす。

### 実行環境の確認（最優先）

- この手順はコマンド実行とファイル書き込みを伴う。あなたが **Claude Code（ターミナル、IDE 拡張、またはデスクトップアプリの Code タブ）** として動いていて、シェルとファイル書き込みが使えることを確認する。
- claude.ai のチャット欄やスマホアプリなど、ローカルのコマンドを実行できない環境で貼られた場合は、**何も実行せず**、「この手順書は Claude Code（デスクトップアプリの Code タブ、またはターミナルの `claude`）に貼り直してください」と短く伝えて止まる。
- OS を判定する（`uname -s`）。この手順書のスクリプトは **macOS で実測したもの**（画像の形式変換に `sips` を使う）。Linux・Windows（WSL）の場合は、手順 3 の注記に従って形式変換の部分だけ置き換える。

### 守ること

1. **OPENAI_API_KEY を設定しない・使わない・作らせない。** 環境変数やシェルの設定ファイルに入っていても、値を画面に出さない。API キーを使う画像生成スクリプト（Codex 同梱の imagegen スキルの予備手順 `scripts/image_gen.py` など）を実行しない。ユーザーが API キーの方法を勧められても、この手順書の範囲では使わない。
2. **Codex 同梱の imagegen スキルには「組み込みツールが使えなければ API キー方式の CLI に切り替える」予備手順がある。** だから毎回のプロンプトで「組み込みの image_gen だけを使う。API キー方式は使わない」と明示する（ラッパーが自動で付ける）。
3. **ラッパーを迂回して `codex exec` を直接叩かない。** 生成物の回収・形式変換・取り違え防止はラッパーが担う。
4. 既存のファイル（`~/.claude/CLAUDE.md`、同名のスクリプト）を書き換える前に、必ずバックアップを取る。
5. **人間にしかできない操作は、ユーザーに頼む。** ChatGPT へのログイン（ブラウザでのサインイン）、Homebrew 等のインストールでパスワードを求められたとき。頼むときは「どの画面で・何を押すか」を1つずつ書く。
6. 手順ごとに「確認」が通ってから次へ進む。
7. ユーザーへの説明は、ユーザーの言語で、専門用語を避けて短く。

### 最初にユーザーへ聞くこと（まとめて1回で）

- ChatGPT のどのプランを使っているか（無料／有料）。**記事の筆者は有料プランで動作を確認している。無料プランで画像生成まで通るかは未確認**と伝えたうえで進める。
- 画像の既定の置き場所（例：作業中のプロジェクトの `images/`）
- 今後、画像が必要になったら自動でこの方法を使うよう `~/.claude/CLAUDE.md` に書いてよいか

---

## 1. Codex CLI を入れてログインする

```bash
command -v codex && codex --version
```

- 入っていなければインストールする。macOS で Homebrew があれば `brew install codex`。無ければ `npm install -g @openai/codex`（Node.js が必要）。
- ログイン状態を見る：

```bash
codex login status
```

- ChatGPT でログインしていなければ、ユーザーに**ターミナルで `codex login` を実行し、開いたブラウザで ChatGPT アカウントにサインインする**よう頼む（あなたが代わりにパスワードを扱わない）。**API キーでのログインは選ばない。**

**確認**：`codex login status` が ChatGPT でログイン済みであることを示す。

---

## 2. 画像生成の道具が使えるか確かめる

```bash
codex features list | grep -i image
```

- `image_generation` が `stable` かつ `true` なら使える（記事の筆者の環境では codex-cli 0.155.1 で確認）。
- 出てこない・`false` の場合：まず Codex を最新に更新する（`brew upgrade codex` または `npm install -g @openai/codex@latest`）。更新しても使えなければ、**ここで止まり**、「今の Codex では Claude から呼ぶ形（codex exec）で画像を作れません。API キー方式は従量課金になるので使いません」とユーザーに報告する。記事の筆者も 2026-09-22 の時点ではこの状態だった（`--enable image_generation` を付けても道具が出なかった）。

**確認**：`image_generation` が使える状態である。

---

## 3. ラッパースクリプトを作る

`~/.claude/scripts/codex-image.sh` に次の内容を保存し、`chmod +x` する（同名ファイルがあればバックアップしてから）。

```bash
#!/usr/bin/env bash
# codex-image.sh — Claude Code から Codex CLI（ChatGPT 有料プランの枠）で画像生成する薄いラッパー
#
# 使い方:
#   ~/.claude/scripts/codex-image.sh -o images/hero.png "プロンプト（日本語可）"
#   ~/.claude/scripts/codex-image.sh -i ref.png -o images/flyer.png "この画像を元に…"
#
# -o  出力パス(必須)。ディレクトリは自動作成。拡張子 .jpg なら sips で変換
# -i  参考画像（繰り返し指定可）。codex exec -i でそのまま渡す
# -t  タイムアウト秒  既定: 600
#
# 成功: 出力ファイルが存在し exit 0 / 失敗: exit 非0 + stderr に理由
#
# ---- 実測で分かったこと（2026-10-08 / codex-cli 0.155.1）----
# * `codex features list` で image_generation は stable/true。exec でも image_gen ツールが使える
# * 認証は ChatGPT ログイン（OPENAI_API_KEY は使わない・設定しない）
# * 生成物は ~/.codex/generated_images/<thread>/exec-<uuid>.png に出る。指定パスへの配置はこのラッパーが行う
# * 同梱 imagegen スキルに「API キー方式の CLI に切り替える」予備手順があるので、プロンプトで禁止する
# * codex exec の -i は複数値を取るので、プロンプトの前に `--` が要る（無いとプロンプトが画像扱いになる）
# * 1枚あたり約1分・約5万トークン（Codex の利用枠から引かれる）

set -u
export PATH="/opt/homebrew/bin:$HOME/.local/bin:$PATH"

GEN_ROOT="$HOME/.codex/generated_images"
OUT=""
TIMEOUT=600
REFS=()

while getopts "o:i:t:" opt; do
  case "$opt" in
    o) OUT="$OPTARG" ;;
    i) REFS+=("$OPTARG") ;;
    t) TIMEOUT="$OPTARG" ;;
    *) echo "usage: $0 -o out.png [-i ref.png ...] [-t sec] \"prompt\"" >&2; exit 2 ;;
  esac
done
shift $((OPTIND - 1))
PROMPT="${1:-}"

[ -z "$PROMPT" ] && { echo "ERROR: prompt required" >&2; exit 2; }
[ -z "$OUT" ]    && { echo "ERROR: -o output path required" >&2; exit 2; }
command -v codex >/dev/null 2>&1 || { echo "ERROR: codex not found" >&2; exit 2; }

OUT_DIR="$(dirname "$OUT")"
mkdir -p "$OUT_DIR" || { echo "ERROR: cannot create dir: $OUT_DIR" >&2; exit 2; }
OUT_DIR="$(cd "$OUT_DIR" && pwd)"
OUT_ABS="$OUT_DIR/$(basename "$OUT")"

IMG_ARGS=()
for r in ${REFS[@]+"${REFS[@]}"}; do
  [ -f "$r" ] || { echo "ERROR: reference not found: $r" >&2; exit 2; }
  IMG_ARGS+=(-i "$(cd "$(dirname "$r")" && pwd)/$(basename "$r")")
done

WORK="$(mktemp -d "${TMPDIR:-/tmp}/codex-image.XXXXXX")"
MARK="$WORK/.mark"
touch "$MARK"
mkdir -p "$GEN_ROOT"

FULL_PROMPT="Use ONLY your built-in image generation tool (image_gen) to generate exactly one image. Do NOT use any CLI script, Python, or API-key based fallback (e.g. scripts/image_gen.py, OPENAI_API_KEY). Do not move or copy files; just generate the image and reply with its saved path.

Image request:
$PROMPT"

echo "codex: generating..." >&2
(
  cd "$WORK" &&
  perl -e 'alarm shift; exec @ARGV' "$TIMEOUT" \
    codex exec --skip-git-repo-check -s read-only ${IMG_ARGS[@]+"${IMG_ARGS[@]}"} -- "$FULL_PROMPT" </dev/null
) > "$WORK/codex.log" 2>&1
RC=$?

# 並列実行でも取り違えないよう、ログの session id のフォルダから回収する（取れなければ新しいもの順）
SID="$(grep -oE 'session id: [0-9a-f-]+' "$WORK/codex.log" | head -1 | awk '{print $3}')"
SEARCH="$GEN_ROOT"
[ -n "$SID" ] && [ -d "$GEN_ROOT/$SID" ] && SEARCH="$GEN_ROOT/$SID"
NEW="$(find "$SEARCH" -newer "$MARK" -type f \( -name '*.png' -o -name '*.jpg' -o -name '*.webp' \) -print0 2>/dev/null \
  | xargs -0 ls -t 2>/dev/null | head -1)"

if [ -z "$NEW" ]; then
  echo "ERROR: no image produced (codex exit $RC). log: $WORK/codex.log" >&2
  tail -20 "$WORK/codex.log" >&2
  exit 1
fi

case "$(echo "${OUT_ABS##*.}" | tr 'A-Z' 'a-z')" in
  jpg|jpeg) sips -s format jpeg "$NEW" --out "$OUT_ABS" >/dev/null || exit 1 ;;
  png)      sips -s format png  "$NEW" --out "$OUT_ABS" >/dev/null || exit 1 ;;
  *)        cp "$NEW" "$OUT_ABS" || exit 1 ;;
esac

file "$OUT_ABS" | grep -qi 'image' || { echo "ERROR: output is not an image: $OUT_ABS" >&2; exit 1; }
rm -rf "$WORK"
echo "$OUT_ABS"
```

```bash
mkdir -p ~/.claude/scripts
chmod +x ~/.claude/scripts/codex-image.sh
```

- **Linux・WSL の場合**：`sips` が無いので、末尾の `case` の部分を「拡張子が生成物と同じなら `cp`、違えば ImageMagick の `convert`（または Python の Pillow）で変換」に置き換える。`export PATH=...` の行は環境に合わせる。
- スクリプトの各部分が何を防いでいるか（説明用）：
  - プロンプトの頭の英文：組み込みの image_gen だけを使わせ、API キー方式への切り替えを禁止する
  - `-- "$FULL_PROMPT"`：`codex exec -i` は画像を複数受け取るため、区切りが無いとプロンプトまで画像のパスとして扱われる
  - `session id` の行からフォルダを特定して回収：複数を並行で作ったときに、別の回の画像を取り違えないため
  - 生成物は `~/.codex/generated_images/<セッション>/` に出る。指定パスへ移すのはスクリプトの役目

---

## 4. 動作確認（1枚だけ作る）

テスト用の場所に1枚作る。**1枚あたり約1分・約5万トークン（ChatGPT プランの Codex 枠から引かれる）**なので、試すのは1枚だけにする。

```bash
~/.claude/scripts/codex-image.sh -o /tmp/codex-image-test.png "白い背景に、赤いりんごが1つ。水彩画風。文字は入れない"
```

- 成功すると最後に出力パスが表示される。
- **「保存しました」を信じず、Read で画像を開いて中身を確かめる**（りんごか・文字が入っていないか）。ユーザーにも `open /tmp/codex-image-test.png`（macOS）で見せる。
- 参考画像つきも1回試す（任意）：`~/.claude/scripts/codex-image.sh -i /tmp/codex-image-test.png -o /tmp/codex-image-test2.png "この絵を、鉛筆画風に描き直して"`

**確認**：画像ファイルが存在し、開いて内容が指示どおりである。API の請求につながる設定（OPENAI_API_KEY）を一度も使っていない。

---

## 5. 次回以降のために書き残す（ユーザーの了承があれば）

`~/.claude/CLAUDE.md` をバックアップしてから、末尾に次を追記する。

```markdown
## 画像生成（ChatGPT / Codex 経由・API キーなし）

- ビットマップ画像（イラスト・バナー・サムネ・アイコン等）が必要になったら、自分で SVG 等で描かず `~/.claude/scripts/codex-image.sh -o <出力パス> [-i 参考画像] "<プロンプト>"` で作る（日本語プロンプト可・1枚約1分）
- OPENAI_API_KEY は使わない・設定しない。ラッパーを迂回して codex exec を直接叩かない
- 生成後は必ず Read で画像を開き、内容（特に日本語の文字）を確かめる。ずれていたらプロンプトを直して作り直す（最大2回）
- 図解・フローチャート・グラフは対象外（コードで作る）
```

---

## 6. 最後の報告

ユーザーに短く報告する：

- Codex のバージョンとログイン状態（ChatGPT ログイン。API キーは未使用）
- 作ったスクリプトの場所と、使い方の例（`-o` と `-i`）
- テストで作った画像の場所と、確かめた内容
- これからの頼み方の例：「このチラシに使うイラストを ChatGPT で作って」「このロゴを参考に、アイコンを3案作って」
- 1枚あたり約1分・約5万トークン（Codex の利用枠から引かれる）であること

---

## ハマりどころ（症状 → 原因 → 対処）

| 症状 | 原因 | 対処 |
|---|---|---|
| `ERROR: no image produced` が出て画像ができない | Codex に画像生成の道具が無い（古い版）／ログインしていない | 手順 1・2 をやり直す。更新しても無ければ止まって報告 |
| 参考画像を付けると、プロンプトが無視される・画像が見つからないと言われる | `-i` の後ろの文まで画像のパスとして読まれている | `codex exec` に渡すとき、プロンプトの前に `--` を入れる（スクリプトは対応済み） |
| 並行で何枚も作ったら、違う画像が置かれた | 「いちばん新しい画像」を拾っていた | ログの session id のフォルダから回収する（スクリプトは対応済み） |
| Codex が Python のスクリプトを実行しようとする・API キーを求める | 同梱 imagegen スキルの予備手順（API キー方式）に流れた | プロンプトで禁止する（スクリプトは対応済み）。OPENAI_API_KEY を設定しない |
| 画像の中の日本語が崩れている | 画像生成の苦手な部分 | 文字を短くする・文字を指定し直して作り直す。必ず開いて確かめる |
| タイムアウトする | 混雑や大きな指示で時間がかかった | `-t 900` のように延ばす。何度も失敗したら止まって報告 |
