Claude Code (Anthropic CLI) と Codex (OpenAI CLI) を同じシェルから併用したい。/codex:rescue のような Claude Code 側スラッシュコマンドが用意されているのは知っていたが、本当にちゃんと動くのか、セッションが維持されるのか、名前は付けられるのか — そのあたりを実機で全部確認した記録。
codex app-server の JSON-RPC thread/name/set を叩けば OK)Claude Code の中で完結したいワークフローでも、たまに別の眼が欲しくなる。Codex はコーディング寄りの強い AI で、特に大規模リファクタや別実装案の検討で使い分けると効く。
OpenAI 公式の Claude Code プラグイン @openai/codex (npm) と、それに対応する Claude Code プラグイン (openai-codex) が同梱の codex-companion.mjs を経由して両者を橋渡しする — 仕組み自体はすでにある。ある、が、ハマりどころが多い。
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
!codex login
ブラウザが開いて OAuth → ~/.codex/auth.json にトークンが入る。login 自体は CLI 機能。
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.detail に Failed to parse codex app-server JSONL と出ているなら、ほぼ確実に codex-cli が古い。アップグレードすれば直る (companion を patch する必要はない)。
同じ Codex 機能に 3 通りでアクセスできる。
/codex:rescue <自然文タスク>
Claude Code が codex:codex-rescue サブエージェントを起動し、内部で companion task を呼ぶ。デフォルトで write-capable。Claude Code 本体のコンテキストは消費されない。
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 番目を実装して"
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 的なフラグ) が無い。
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: <最初のプロンプト>" 形式で命名する。気にしないでよい。
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。
同時期に 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 側に手を入れる必要はない)。同症状を見たらまずバージョンを疑う。
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 を呼ぶワークフローはちゃんと動く。ただし
auth.loggedIn: false や JSONL parse error は 9 割が版違いこの 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。