Claude Code から Codex を操作する — 2026-05-23 検証メモ

Claude Code (Anthropic CLI) と Codex (OpenAI CLI) を同じシェルから併用したい。/codex:rescue のような Claude Code 側スラッシュコマンドが用意されているのは知っていたが、本当にちゃんと動くのか、セッションが維持されるのか、名前は付けられるのか — そのあたりを実機で全部確認した記録。


TL;DR

  • Claude Code から Codex を呼ぶ経路は 3 つ ある (companion slash command / companion Bash / codex CLI 直叩き)
  • どれも 同じ Codex thread に乗り続ける ことができる (3 ターン会話で実証)
  • thread (= セッション) に 名前を付けて UUID 無しで resume できる (公式 CLI フラグは無いが、codex app-server の JSON-RPC thread/name/set を叩けば OK)
  • ハマりやすいのは codex-cli のバージョン。古いと全モデル拒否 + companion の JSONL parser まで一緒に壊れる
  • ChatGPT app の Memory / 過去 chat history は Codex には引き継がれない。ChatGPT の OAuth はあくまで課金・クォータ用途

なぜ Claude Code から Codex を呼びたいか

Claude Code の中で完結したいワークフローでも、たまに別の眼が欲しくなる。Codex はコーディング寄りの強い AI で、特に大規模リファクタや別実装案の検討で使い分けると効く。

OpenAI 公式の Claude Code プラグイン @openai/codex (npm) と、それに対応する Claude Code プラグイン (openai-codex) が同梱の codex-companion.mjs を経由して両者を橋渡しする — 仕組み自体はすでにある。ある、が、ハマりどころが多い


セットアップ

1. codex-cli の最低バージョン

ChatGPT account 認証 + GPT-5.X 系モデルを使う場合、codex-cli は 0.126 以上が必須

codex --version
# codex-cli 0.133.0 など

cat ~/.codex/version.json
# {"latest_version":"0.133.0","last_checked_at":"..."}

古い場合は更新する。npm の global パッケージ。

npm install -g @openai/codex@latest

2. ログイン

!codex login

ブラウザが開いて OAuth → ~/.codex/auth.json にトークンが入る。login 自体は CLI 機能。

3. Claude Code 側の確認

node "$CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs" setup --json

または Claude Code 内で /codex:setup。期待される最終状態:

{
  "ready": true,
  "codex": { "available": true, "detail": "codex-cli 0.133.0; advanced runtime available" },
  "auth": { "loggedIn": true, "detail": "ChatGPT login active for ..." },
  "sessionRuntime": { "mode": "shared", ... }
}

loggedIn: false + auth.detailFailed to parse codex app-server JSONL と出ているなら、ほぼ確実に codex-cli が古い。アップグレードすれば直る (companion を patch する必要はない)。


動かし方 — 3 つの経路

同じ Codex 機能に 3 通りでアクセスできる。

A. Claude Code のスラッシュコマンド

/codex:rescue <自然文タスク>

Claude Code が codex:codex-rescue サブエージェントを起動し、内部で companion task を呼ぶ。デフォルトで write-capable。Claude Code 本体のコンテキストは消費されない。

B. Bash で companion を直接叩く

node "$CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs" task --background "リファクタ案を 3 つ出して"
# -> Codex Task started in the background as task-mph...
node "$CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs" status <job-id> --json
node "$CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs" result <job-id>

成功すると末尾に Codex 側 thread の UUID が付く:

... Codex session ID: 019e514a-fbf6-7860-9504-a60c536cd0a0
Resume in Codex: codex resume 019e514a-fbf6-7860-9504-a60c536cd0a0

continue したい場合は --resume-last:

node ".../codex-companion.mjs" task --resume-last --background "さっきの 2 番目を実装して"

C. codex CLI を素で叩く

companion を経由しない、最もシンプルな経路。

codex exec --json --skip-git-repo-check -m gpt-5.5 "..."
codex exec resume --last --json --skip-git-repo-check -m gpt-5.5 "..."
codex exec resume <UUID> --json --skip-git-repo-check -m gpt-5.5 "..."
codex exec resume "<thread name>" --json --skip-git-repo-check -m gpt-5.5 "..."

--json を付けると JSONL で thread_id / cached_input_tokens 等が読めて、後段で機械処理しやすい。

経路の使い分け

やりたいこと 推奨経路
Claude Code の会話の流れで Codex に振りたい A (/codex:rescue)
スクリプト・自動化に組み込みたい B (companion)
Codex の出力 JSONL を生で扱いたい / 名前付け等の細工 C (CLI 直叩き)

セッションが本当に継続するか確認

数当てクイズで 3 ターン回した。

# Turn 1 (新規 thread 作成)
codex exec --json ... -m gpt-5.5 \
  "私は数字 42 を思い浮かべました。受け取ったら『了解』とだけ短く返答してください。"
# -> {"type":"thread.started","thread_id":"019e5161-51ba-7791-aa1a-c07af59369bd"}
# -> 応答: 「了解」

# Turn 2 (resume --last)
codex exec resume --last --json ... -m gpt-5.5 \
  "その数字に 8 を足してください。結果の数字だけを一行で返してください。"
# -> 同じ thread_id
# -> 応答: 「50」

# Turn 3 (resume --last)
codex exec resume --last --json ... -m gpt-5.5 \
  "その結果から、私が最初に思い浮かべた元の数字を引いてください。"
# -> 同じ thread_id
# -> 応答: 「8」 (50 - 42)

3 ターン目に 元の 42 を覚えていない限り出ない値 が返ってきたので、文脈は完全に継続している。

cached_input_tokens も 9600 → 20736 → 30336 と累積。プロンプトキャッシュに過去ターンが乗っている裏付けになる。


セッションに名前を付ける

UUID で resume するのは正確だが覚えづらい。名前で resume したい。

codex exec resume --help には:

[SESSION_ID] Conversation/session id (UUID) or thread name. UUIDs take precedence if it parses.

と書いてある。取得側 (resume) は名前を受け付ける。ただし codex CLI 0.133.0 には 設定側 (--name 的なフラグ) が無い

解決: app-server プロトコルを直叩く

codex app-server (= JSON-RPC over stdio) を起動して thread/name/set を送る。

スキーマは自分で生成できる:

codex app-server generate-json-schema --out /tmp/codex-schema
cat /tmp/codex-schema/ClientRequest.json | jq '.oneOf[].title'
# -> "Thread/start", "Thread/resume", "Thread/name/set", "Thread/list", "Thread/fork", "Thread/archive", ...

thread/name/set の params:

{ "threadId": "<UUID>", "name": "<任意文字列>" }

小さなヘルパを書いた:

// tools/codex/set_thread_name.mjs
import { spawn } from "node:child_process";
import readline from "node:readline";

const [threadId, desiredName] = process.argv.slice(2);
const proc = spawn("codex", ["app-server"], {
  stdio: ["pipe", "pipe", "pipe"],
  shell: process.platform === "win32",
});
const rl = readline.createInterface({ input: proc.stdout });
let nextId = 1, pending = new Map();
const send = (method, params) => {
  const id = nextId++;
  pending.set(id, method);
  proc.stdin.write(JSON.stringify({ id, method, params }) + "\n");
};

rl.on("line", (line) => {
  const msg = JSON.parse(line);
  const method = pending.get(msg.id);
  pending.delete(msg.id);
  if (method === "initialize") {
    send("thread/name/set", { threadId, name: desiredName });
  } else if (method === "thread/name/set") {
    console.log("ok:", msg.result);
    proc.kill();
  }
});

send("initialize", { clientInfo: { name: "codex-namer", version: "0.1.0" } });

使い方:

node tools/codex/set_thread_name.mjs 019e5161-... "numeric-quiz-42"
# -> {"resp_for":"thread/name/set","id":2,"result":{}}

# 名前で resume できる
codex exec resume "numeric-quiz-42" --json ... -m gpt-5.5 "私の元の数字は?"
# -> 応答: 「42」 (もちろん同 thread に乗っている)

確認は thread/list で:

# thread/list params: { sortKey, sortDirection, sourceKinds, searchTerm }
# デフォルト sourceKinds は interactive のみ。exec 経由を含めたいなら
# ["cli", "vscode", "exec", "appServer"] を明示する

ちなみに companion 経由 (/codex:rescue / task) で作った thread は、companion が勝手に "Codex Companion Task: <最初のプロンプト>" 形式で命名する。気にしないでよい。


ハマりどころ

1. codex-cli が古いと全モデル拒否される

0.36.0 → 0.133.0 にアップグレードするまで、私の手元では以下のような 400 が連発した:

{"type":"stream_error","message":"stream error: unexpected status 400 Bad Request:
 {\"detail\":\"The 'gpt-5.5' model requires a newer version of Codex.
 Please upgrade to the latest app or CLI and try again.\"}; retrying 1/5 ..."}

gpt-5, gpt-5-codex, gpt-4o-mini 等を試しても ChatGPT account では拒否される という別の壁にあたる。素直に npm install -g @openai/codex@latest

2. JSONL ANSI parse エラーは版違いのサイン

同時期に companion 側も全 task で:

{ "errorMessage": "Failed to parse codex app-server JSONL: Unexpected token '\\u001b', \"\\u001b[?2004h\\u001b[\"... is not valid JSON" }

を吐いていた。companion の strict JSON parser が、旧 codex-cli の app-server が混入させる ANSI bracketed-paste escape (\\u001b[?2004h) を処理できない。

これも codex-cli を最新にすれば自然に直る (companion 側に手を入れる必要はない)。同症状を見たらまずバージョンを疑う。

3. ChatGPT 側の Memory / 履歴は Codex に降りてこない

OAuth が共通だから期待したくなるが、ダメだった。

codex exec --json ... -m gpt-5.5 \
  "私が ChatGPT で長期間議論してきたリーマンの調和球について、要点を 5 項目以内で具体的に述べてください。覚えていない場合は『記憶していません』とだけ返答。"
# -> 応答: 「記憶していません」

Codex 自身の自己申告も同じ:

このAPI環境では、この会話内で提示された情報と利用可能なローカル/ツール情報だけを参照でき、ChatGPT consumer app のメモリや過去チャット履歴には接続されていません。

~/.codex/memories/ というディレクトリは存在するが空。Codex 独自のメモリ store はあるが、ChatGPT app のメモリとは別物。

過去議論を Codex に持ち込みたいなら、最初のプロンプトに自分で貼るのが一番確実。 あるいは Codex で一度議論した thread を thread/name/set で命名しておけば、以降は codex exec resume "<name>" で続けられる。


まとめ

Claude Code から Codex を呼ぶワークフローはちゃんと動く。ただし

  • 最初に codex-cli の版 をきっちり最新にすること
  • auth.loggedIn: false や JSONL parse error は 9 割が版違い
  • セッション継続は CLI / companion どちらでも可
  • 命名は CLI フラグ非対応だが、app-server プロトコル一発で済む
  • ChatGPT の Memory は降りてこない、と覚えておく

この 5 つを押さえれば、Claude Code 側で会話を進めつつ Codex に重い仕事を投げる、というスタイルが安定して回る。


付録: 確認用ワンライナー集

# 環境チェック
codex --version
cat ~/.codex/version.json

# 認証チェック
node "$CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs" setup --json

# 新規セッション開始 & UUID 取得
codex exec --json --skip-git-repo-check -m gpt-5.5 "<prompt>" | grep thread.started

# 直近セッション継続
codex exec resume --last --json --skip-git-repo-check -m gpt-5.5 "<prompt>"

# 命名後の名前 resume
codex exec resume "<name>" --json --skip-git-repo-check -m gpt-5.5 "<prompt>"

# 命名 (要 set_thread_name.mjs)
node tools/codex/set_thread_name.mjs <UUID> "<name>"

# 全 RPC method 一覧
codex app-server generate-json-schema --out /tmp/codex-schema
ls /tmp/codex-schema/

検証環境: Windows 11 / Git Bash / Node 22.12.0 / codex-cli 0.133.0 / Claude Code (Opus 4.7 1M ctx) / 2026-05-23。


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   最終更新のRSS
Last-modified: 2026-05-23 (土) 10:11:58