Codex SDKは、自分のアプリのコードからCodexに作業を頼み、結果を受け取るためのライブラリです。TypeScriptならnpm install @openai/codex-sdk、Pythonならpip install openai-codexで入れ、会話(スレッド)を作ってrun()に依頼文を渡します。同じスレッドでrun()を続ければ会話が続き、スレッドIDを保存しておけば後から再開できます。最初に「どこまで書き込ませるか」と「結果をどんな形で受け取るか」を決めておくと、アプリの処理に組み込みやすくなります。

この記事は、OpenAIの公式資料と、公式リポジトリにあるSDKの説明・ソースコード(いずれも2026年10月29日に確認)に基づく解説です。パッケージの最新版も、同じ日にnpmとPyPIの公開情報で確かめました。下のコードは教材で、結果を検査する関数だけを編集部がNode.jsで試しています。SDKからCodex本体に依頼を送る実測は行っていません。

Codex SDKでできること:App Serverやcodex execとの違い

公式資料は、Codex SDKの使いどころとして次の4つを挙げています。

  • CI/CDのパイプラインの一部としてCodexを動かす
  • Codexと連携して複雑な開発作業をこなす、自前のエージェントを作る
  • 社内ツールや業務の流れにCodexを組み込む
  • 自分のアプリケーションの中でCodexを使う

仕組みは言語で少し違います。TypeScript版はcodexのCLIを起動し、標準入出力でJSONLのイベントをやり取りします。Python版は、手元で動くCodexのapp-serverをJSON-RPCで操作します。公開版をインストールすると、SDKと版をそろえたCodex CLIの実行環境(openai-codex-cli-bin)も依存パッケージとして自動で入ります。どちらも、アプリを動かしているマシンの上でCodexが作業する点は同じです。

入口向いている使い方自分で扱う範囲
Codex SDKアプリのコードから依頼し、結果や失敗を受け取る会話の開始・継続、書き込みの範囲、結果の検査
Codex App Server自社の画面で会話・途中経過・承認ボタンを出す(実験的な機能で、本番ワークロードは公式のサポート対象外)接続の初期化、通知の反映、承認への応答まで
codex execスクリプトやCIで一回の作業を実行するコマンドの引数と、標準出力の受け取り

App Serverの公式資料も、認証や会話履歴、承認、途中のイベントまで扱う独自のクライアントを作るならApp Serverを使うよう案内しています。画面づくりまで踏み込む場合はCodex App Serverの使い方を、シェルから一回ずつ動かすならcodex execの使い方を参照してください。なお、以前のcodex mcp-serverコマンドは削除されており、公式の移行案内は既存の連携をApp Serverへ移すよう求めています。

Codex SDKを組み込む4つの手順。読み取り専用で依頼し、最初のrunの後にIDを保存し、結果の形をアプリ側でも確かめ、範囲を決めて書き込みへ広げる。
図:Codex SDKを組み込む4つの手順。読み取り専用で依頼し、最初のrunの後にIDを保存し、結果の形をアプリ側でも確かめ、範囲を決めて書き込みへ広げる。 編集部の説明図です。製品の画面ではありません。画像を開くと拡大できます。

インストールの前に確かめること

TypeScriptはNode.js 18以上、Pythonは3.10以上

TypeScript版はNode.js 18以上が必要で、サーバー側で使う前提です。ブラウザの画面から直接呼び出すものではありません。Python版は3.10以上が必要で、安定版が公開されています。

# TypeScript
npm install @openai/codex-sdk

# Python(安定版)
pip install openai-codex

2026年10月29日に確認した時点の最新版は、npmの@openai/codex-sdkが0.165.0、PyPIのopenai-codexが0.163.0でした。Pythonで先行版を試したい場合だけpip install --pre openai-codexを使います。また、Python版は自動で入る実行環境をそのまま使うので、特定のCodex CLIを使う必要があるときだけCodexConfig(codex_bin=...)で指定します。名前の似た非公式のパッケージもあるため、インストールする名前と、パッケージのリポジトリがGitHubのopenai/codexであることを確かめてください。

認証は既存のCodexのログインを使う

Python版は、すでにCodexにログインしていればその認証をそのまま使います。ブラウザでのChatGPTログイン、コード入力式のログイン、APIキーでのログインを、コードから始めることもできます。公式の非対話モードの資料によると、CODEX_API_KEYという環境変数はTypeScript SDKでも使えます。どの方法でも、APIキーをソースコードに直接書かず、環境変数や秘密情報の保管場所から読み込みます。CIでの認証の注意はcodex execの記事に、GitHub Actionsでの使い方はCodex GitHub Actionsの記事にまとめています。

作業フォルダーはGitリポジトリにする

TypeScript版のREADMEによると、Codexは既定で現在のフォルダーで動き、取り返しのつかない失敗を避けるため、そのフォルダーがGitリポジトリであることを求めます。skipGitRepoCheckでこの確認を外せますが、変更を元に戻す手段が別にある場合に限りましょう。依頼の前にコミットしておけば、Codexの変更だけを差分で確かめられます。

Codex SDKで最初の依頼を送る手順

最初の依頼は、ファイルを書き換えない「読み取りだけの調査」にします。どのフォルダーを読み、何を返してくれるのかを確かめてから、書き込みを許す依頼へ進むほうが安全です。TypeScriptでは次のように書きます。

import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread({
  workingDirectory: "/path/to/project",
  sandboxMode: "read-only",
});
const turn = await thread.run("テストが失敗する原因を調べ、修正の方針を3行で説明してください");

console.log(turn.finalResponse); // 最終的な返答の文章
console.log(turn.items);         // コマンドの実行などの記録
console.log(thread.id);          // 後で再開するために保存する

Pythonでは、withの中でCodexを起動し、スレッドを作って依頼します。

from openai_codex import Codex, Sandbox

with Codex() as codex:
    thread = codex.thread_start(cwd="/path/to/project", sandbox=Sandbox.read_only)
    result = thread.run("テストが失敗する原因を調べ、修正の方針を3行で説明してください")
    print(thread.id, result.status)
    print(result.final_response)

公式資料のPythonの例はモデルにGPT-6.1 Solを指定していますが、このモデルはログインしているアカウントで使える場合に限られます。使えない場合は、modelを書かずに既定のモデルで動かします。また、Python版のthread_startは、承認の依頼を自動のレビューに回す方式(ApprovalMode.auto_review)が既定です。人が確かめてから進めたい業務では、承認の方式も明示的に決めておきましょう。

Codex SDKで会話を続ける・後から再開する

同じスレッドのオブジェクトでrun()をもう一度呼ぶと、前の会話を踏まえて作業が続きます。最初の依頼で方針を説明させ、内容を確かめてから「その方針で実装して」と頼む、という二段階の使い方ができます。

// 同じスレッドで続ける
const next = await thread.run("説明した方針で修正し、テストを実行してください");

// 保存しておいたIDから再開する
const resumed = codex.resumeThread(savedThreadId);
await resumed.run("前回の続きから、残っている失敗を確認してください");

TypeScript版のソースコードでは、thread.idは最初のrun()でCodexから会話の開始を知らせるイベントが届いた時点で決まり、それまではnullです。スレッドを作った直後ではなく、最初の依頼が終わった後に保存します。Pythonでは、Getting Startedの例のとおりthread.idでIDを読み、APIリファレンスにあるcodex.thread_resume(thread_id)で再開できます。

スレッドIDと業務の対応を残しておく

TypeScript版のREADMEによると、スレッドは~/.codex/sessionsに保存されます。つまり会話の記録は、アプリを動かしているマシンの上にあります。複数のサーバーで処理を分ける設計なら、どのマシンで再開するのかも含めて決めておきます。アプリ側には、少なくとも次の情報を一緒に残しておくと、後から追いかけやすくなります。

残す情報使い道
スレッドID同じ会話を再開する
作業フォルダーと対象のブランチ別の場所で再開して、違うコードを触るのを防ぐ
依頼の目的と担当者何のための会話かを後から判断する
最後の状態と日時完了・失敗・確認待ちのどれかを一覧で見る

Codex SDKで書き込みの範囲と結果の形を決める

書き込みの範囲は、読み取り専用から始める

TypeScript版では、スレッドを作るときのsandboxModeで書き込みの範囲を選びます。値はread-only(読み取りだけ)、workspace-write(作業フォルダー内の書き込み)、danger-full-access(制限なし)の3つです。同じ場所で、承認の方針(approvalPolicy)やネットワークの利用可否、追加で触ってよいフォルダーも指定できます。

Python版ではSandbox.read_only、Sandbox.workspace_write、Sandbox.full_accessの3つが用意されています。公式資料によると、run()に渡した範囲はそのターンと、同じスレッドの以後のターンに効きます。そのため、修正の後に「差分を見るだけ」の確認をさせる場合は、確認の依頼で読み取り専用を指定し直します。その後のターンも読み取り専用のままになるので、再び書き込ませるときはSandbox.workspace_writeを指定し直します。

with Codex() as codex:
    thread = codex.thread_start(sandbox=Sandbox.workspace_write)
    thread.run("依頼された修正を行ってください")
    review = thread.run("差分だけを見て、問題点を挙げてください", sandbox=Sandbox.read_only)

制限なしのdanger-full-access(Pythonではfull_access)は、使い捨ての実行環境のように、影響の範囲が限られた場所でだけ使います。設定を細かく変えたい場合、TypeScript版ではnew Codex({ config: {...}, configOverrides: [...] })のように、Codexのクライアントを作るときに上書きを渡せます。公式資料によると、この上書きはCodexの設定ファイルそのものは書き換えません。Python版ではthread_start(config={...})に設定を渡せます。

結果の形はoutputSchemaで決める

結果をアプリの処理に渡すなら、文章のままではなく決まった形のJSONで受け取ると扱いやすくなります。TypeScriptではrun()の第2引数のoutputSchema、Pythonではrun()のoutput_schemaに、期待する形をJSON Schemaで渡します。形を指定しても、アプリ側では使う前に中身を確かめましょう。次の関数は、その確認を行う編集部の教材です。

// review-result.mjs(Codex Studio編集部の教材)
export const reviewSchema = {
  type: "object",
  properties: {
    summary: { type: "string" },
    status: { type: "string", enum: ["ok", "action_required"] },
    files: { type: "array", items: { type: "string" } },
  },
  required: ["summary", "status", "files"],
  additionalProperties: false,
};

export function parseReview(finalResponse) {
  let data;
  try {
    data = JSON.parse(finalResponse);
  } catch {
    return { ok: false, reason: "JSONとして読めない" };
  }
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
    return { ok: false, reason: "オブジェクトではない" };
  }
  if (typeof data.summary !== "string" || data.summary.trim() === "") {
    return { ok: false, reason: "summaryが空" };
  }
  if (!["ok", "action_required"].includes(data.status)) {
    return { ok: false, reason: "statusが想定外" };
  }
  if (!Array.isArray(data.files) || data.files.some((f) => typeof f !== "string")) {
    return { ok: false, reason: "filesが文字列の配列ではない" };
  }
  return { ok: true, value: data };
}

// 使う側:const turn = await thread.run("変更を確認して", { outputSchema: reviewSchema });
//         const checked = parseReview(turn.finalResponse);

この関数が確かめるのは、アプリが使う3つの項目の形だけです。編集部では、架空の最終応答8件をNode.jsでこの関数に通しました。形のそろった2件だけが通り、文章だけの返答、null、配列、空の要約、想定外の状態名、ファイル一覧が配列でないもの、の6件はそれぞれの理由で止まりました。これは教材の関数の検査で、Codexが実際にこうした返答を返すかを測ったものではありません。止まった結果をそのまま処理に流さず、人が確かめる列に回す設計にしておくと安全です。

途中経過の表示と中断の方法

run()は、作業が終わるまで途中のイベントをためてから結果を返します。進み具合を画面やログに出したい場合、TypeScriptではrunStreamed()を使い、イベントを1つずつ受け取ります。ソースコードにある主なイベントは次のとおりです。

イベント意味
thread.started会話が始まった。再開に使うIDが含まれる
item.started / item.updated / item.completedコマンドの実行や返答など、作業単位の開始・更新・完了
turn.completed依頼が完了した。トークンの使用量が含まれる
turn.failed / error依頼の失敗、または回復できないエラー

途中で止めたい場合、TypeScriptではrun()の第2引数にsignal(AbortSignal)を渡して取り消せます。Pythonではthread.turn()で依頼の操作用のオブジェクトを受け取り、stream()で途中経過を読み、steer()で追加の指示、interrupt()で中断ができます。

Codex SDKがうまく動かない時の確認順

失敗したときは、結果の受け取り方の違いを先に押さえます。TypeScript版のrun()は、依頼が失敗するとエラーを投げます。tryとcatchで受け止め、その時点のthread.idとエラーの文を記録しておきます。Python版のrun()は結果のオブジェクトを返すので、statusとerrorを確認します。最終的な答えがないまま終わった場合、final_responseはNoneになります。

症状最初に確かめること
Gitリポジトリのエラーで起動しない作業フォルダーの指定。確認を外すのは、変更を戻す手段がある時だけ
モデルに関するエラーになる指定したモデルがそのアカウントで使えるか。外して既定のモデルで試す
ファイルが変わらない書き込みの範囲が読み取り専用のままになっていないか
アプリの処理が結果を読めない結果の形を指定したか、アプリ側の確認で止まっていないか
Pythonで混雑のエラーが出る公式のretry_on_overloadで、間隔を延ばしながら再試行する
PythonでExternalMessageなどの新しい機能を使うとCodexErrorになるcodex_binで古いCodexを指定していないか

他のアプリやツールから受け取った文章を依頼に含める場合は、その中の指示を利用者の指示として扱わないことも大切です。Python版には、信頼できない外部の文章を区別して渡すためのExternalMessageがあり、公式資料はこれが利用者の承認にはならないと説明しています。外部の文章を普通の依頼文に混ぜるより、出どころを分けて渡しましょう。

まとめ:Codex SDKは読み取りだけの依頼から組み込む

Codex SDKをアプリに組み込むときは、まず読み取り専用で一件の調査を頼み、スレッドIDの保存、結果の形の確認、失敗の受け止め方を決めます。そのうえで書き込みを許す依頼へ進めば、何をどこまで任せたのかを後から追いかけられます。SDKの関数は数行で呼べますが、業務に使えるかどうかは、範囲と確認の決め方で変わります。

社内ツールや開発の流れにCodexをどう組み込むか、任せる範囲や確認の手順から整理したい場合は、法人向けのご相談も受け付けています。