For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション
Theme

Codex App Server

app-server プロトコルを使って Codex を製品に組み込む方法

Codex app-server は、Codex の VS Code 拡張機能など、多機能なクライアントを支えるインターフェースです。認証、会話履歴、承認、エージェントイベントのストリーミングまで、自社製品に Codex を深く統合したい場合に使用します。app-server の実装は Codex の GitHub リポジトリ(openai/codex/codex-rs/app-server)で公開されています。Codex のオープンソースコンポーネントの一覧は、オープンソースのページを参照してください。

ジョブを自動化する場合や CI で Codex を実行する場合は、Codex SDK を使用してください。

CLI ターミナル UI の接続

リモートターミナル UI モードでは、あるマシンで app-server を実行し、別のマシンから Codex CLI のターミナルインターフェースを接続できます。まず WebSocket リスナーを起動します。

codex app-server --listen ws://127.0.0.1:4500

次に、ターミナル UI を接続します。

codex --remote ws://127.0.0.1:4500

ローカル以外から接続する場合は、WebSocket 認証を設定し、TLS で接続を保護してください。Bearer トークンは環境変数に格納し、コマンドラインには環境変数名を渡します。

export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
  --remote-auth-token-env CODEX_REMOTE_TOKEN

--remote オプションは ws://、wss://、unix://、unix://PATH の各エンドポイントに対応しています。暗号化されていない WebSocket は、localhost または SSH ポートフォワーディング経由で接続する場合にのみ使用してください。

リモートの Code Mode ホストへの接続

デフォルトでは、app-server はローカルの Code Mode ホストを起動します。同じ app-server プロセス内の複数のスレッドでリモートホストを共有するには、そのホストの HTTP/2 gRPC エンドポイントを --code-mode-host に渡します。

codex app-server --code-mode-host https://code-mode.example.com

リモートホストへの接続には HTTPS を使用して、ツールの引数と実行結果を保護してください。HTTP はループバック接続または安全なトンネル経由でのみ使用してください。URL にはホスト名と任意のポートを指定できます。認証情報、パス、クエリ文字列、フラグメントは含めないでください。クライアントから app-server への接続は、別途 --listen で設定します。

プロトコル

MCP と同様に、codex app-server は JSON-RPC 2.0 メッセージによる双方向通信に対応しています(通信時は "jsonrpc":"2.0" ヘッダーを省略します)。

使用できるトランスポートは次のとおりです。

  • stdio(--listen stdio://、デフォルト):改行区切りの JSON(JSONL)
  • websocket(--listen ws://IP:PORT、実験的でサポート対象外):WebSocket のテキストフレームごとに 1 件の JSON-RPC メッセージ
  • Unix ソケット(--listen unix:// または --listen unix://PATH):標準の HTTP Upgrade ハンドシェイクを使い、Codex のデフォルトの app-server 制御ソケットまたは指定した Unix ソケットパスを介して確立する WebSocket 接続
  • off(--listen off):ローカルトランスポートを公開しない設定

--listen ws://IP:PORT で実行すると、同じリスナーが基本的な HTTP ヘルスプローブにも応答します。

  • GET /readyz は、リスナーが新規接続を受け付けられるようになると 200 OK を返します。
  • GET /healthz は 200 OK を返します。ただし、リクエストに Origin ヘッダーがない場合に限ります。
  • Origin ヘッダーを含むリクエストは 403 Forbidden で拒否されます。

WebSocket トランスポートは実験的で、サポート対象外です。ws://127.0.0.1:PORT などのローカルリスナーは、localhost や SSH ポートフォワーディングを使う場合に適しています。段階的な提供期間中は、ループバック以外の WebSocket リスナーもデフォルトで未認証の接続を許可するため、リモートに公開する前に WebSocket 認証を設定してください。

WebSocket 認証に使用できるフラグは次のとおりです。

  • --ws-auth capability-token --ws-token-file /absolute/path
  • --ws-auth capability-token --ws-token-sha256 HEX
  • --ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path

署名付き Bearer トークンでは、--ws-issuer、--ws-audience、--ws-max-clock-skew-seconds も設定できます。クライアントは WebSocket ハンドシェイクで Authorization: Bearer <token> として認証情報を提示し、app-server は JSON-RPC の initialize の前に認証を行います。

Bearer トークンをコマンドラインで直接渡すよりも、--ws-token-file の使用を推奨します。--ws-token-sha256 は、クライアントが元の高エントロピートークンを別のローカルシークレットストアに保管している場合にのみ使用してください。ハッシュは検証用であり、クライアントには元のトークンが必要です。

WebSocket モードでは、app-server は容量に上限のあるキューを使用します。受信キューがいっぱいになると、サーバーは新規リクエストを拒否し、JSON-RPC エラーコード -32001 とメッセージ "Server overloaded; retry later." を返します。クライアントは待機時間を指数関数的に延ばし、ジッターを加えて再試行してください。

メッセージスキーマ

リクエストには method、params、id が含まれます。

以下の例では GPT-6.1 Sol を使用します。利用するには、サインイン中のアカウントまたはワークスペースにこのモデルへのアクセス権が必要です。必要に応じて model/list で利用可能なモデルを選択してください。

{ "method": "thread/start", "id": 10, "params": { "model": "gpt-6.1-sol" } }

レスポンスには、リクエストと同じ id と、result または error が含まれます。

{ "id": 10, "result": { "thread": { "id": "thr_123" } } }
{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }

通知では id を省略し、method と params のみを使用します。

{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }

CLI から TypeScript スキーマまたは JSON Schema バンドルを生成できます。生成される成果物は、コマンドを実行した Codex のバージョンに正確に対応します。

codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemas

利用開始の手順

  1. codex app-server(デフォルトの stdio トランスポート)、codex app-server --listen ws://127.0.0.1:4500(TCP 上の WebSocket)、または codex app-server --listen unix://(デフォルトの Unix ソケット)でサーバーを起動します。
  2. 選択したトランスポートでクライアントを接続し、initialize を送信してから initialized 通知を送信します。
  3. スレッドとターンを開始し、接続中のトランスポートストリームから通知を継続して読み取ります。

Node.js / TypeScript の例を示します。

import { spawn } from "node:child_process";
import readline from "node:readline";
const proc = spawn("codex", ["app-server"], {
  stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
  proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
  const msg = JSON.parse(line) as any;
  console.log("server:", msg);
  if (msg.id === 0 && msg.result) {
    send({ method: "initialized", params: {} });
    send({
      method: "thread/start",
      id: 1,
      params: { model: "gpt-6.1-sol" },
    });
  }
  if (msg.method === "turn/completed") {
    if (msg.params?.turn?.status !== "completed") {
      console.error(msg.params?.turn?.error ?? "The turn did not complete.");
      process.exitCode = 1;
    }
    proc.stdin.end();
    rl.close();
  }
  if (msg.error) {
    console.error(msg.error);
    process.exitCode = 1;
    proc.stdin.end();
    rl.close();
  }
  if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
    threadId = msg.result.thread.id;
    send({
      method: "turn/start",
      id: 2,
      params: {
        threadId,
        input: [{ type: "text", text: "Summarize this repo." }],
      },
    });
  }
});
send({
  method: "initialize",
  id: 0,
  params: {
    clientInfo: {
      name: "my_product",
      title: "My Product",
      version: "0.1.0",
    },
  },
});
proc.on("error", (error) => {
  console.error(error);
  process.exitCode = 1;
  rl.close();
});
proc.on("exit", (code) => {
  if (code !== 0) process.exitCode = code ?? 1;
});

基本概念

  • スレッド:ユーザーと Codex エージェントの会話です。スレッドにはターンが含まれます。
  • ターン:ユーザーからの 1 件のリクエストと、それに応じてエージェントが行う作業です。ターンにはアイテムが含まれ、進捗が逐次配信されます。
  • アイテム:入力または出力の単位です。ユーザーメッセージ、エージェントメッセージ、コマンド実行、ファイル変更、ツール呼び出しなどがあります。

スレッド API で会話を作成、一覧表示、アーカイブできます。ターン API で会話を進め、ターン通知で進捗を受信します。

ライフサイクルの概要

  • 接続ごとの初期化:トランスポート接続を開いた直後に、クライアントのメタデータを含む initialize リクエストを送信し、続いて initialized を送信します。このハンドシェイクが済むまで、サーバーはその接続で他のリクエストを受け付けません。
  • スレッドの開始または再開:新しい会話には thread/start、既存の会話の続きには thread/resume、履歴を新しいスレッド ID に分岐させるには thread/fork を呼び出します。
  • ターンの開始:turn/start に対象の threadId とユーザー入力を渡します。任意のフィールドでモデル、作業ディレクトリ、サンドボックスポリシーを上書きできます。
  • 実行中のターンへの追加入力:turn/steer を呼び出すと、新しいターンを作成せずに、進行中のターンにユーザー入力を追加できます。
  • イベントの受信:turn/start の後は、標準出力から thread/archived、thread/unarchived、item/started、item/completed、item/agentMessage/delta、ツールの進捗などの通知を継続して読み取ります。
  • ターンの終了:サーバーは turn/completed で最終ステータスを通知します。これはモデルの処理が終了したとき、または turn/interrupt によるキャンセル後に送信されます。

初期化

トランスポート接続ごとに initialize リクエストを 1 回送信し、続いて initialized 通知を送信してから、他のメソッドを呼び出してください。初期化前のリクエストには Not initialized エラーが返り、同じ接続で initialize を再度呼び出すと Already initialized が返ります。

サーバーは、上流サービスに提示するユーザーエージェント文字列と、実行環境を表す platformFamily および platformOs の値を返します。統合先を識別できるように clientInfo を設定してください。

initialize.params.capabilities では、次のクライアント機能も指定できます。

  • optOutNotificationMethods:この接続で抑制する通知メソッドの正確な名前を指定します。完全一致のみで、ワイルドカードや前方一致は使えません。未知の名前は受け付けますが、無視されます。
  • requestAttestation:サーバーからの attestation/generate リクエストを受け取る設定です。上流サービス向けのアテステーションに対応するデスクトップホストは、内容を解釈する必要のない { "token": "..." } 値を返します。
  • mcpServerOpenaiFormElicitation:下流の MCP サーバーが OpenAI 拡張フォーム形式の mcpServer/elicitation/request を送信できるようにします。

重要:OpenAI コンプライアンス・ログ・プラットフォームでクライアントを識別できるように clientInfo.name を設定してください。企業向けに新しい Codex 統合を開発する場合は、既知のクライアント一覧への登録について OpenAI にお問い合わせください。詳細は Codex ログリファレンスを参照してください。

Codex の VS Code 拡張機能の例を示します。

{
  "method": "initialize",
  "id": 0,
  "params": {
    "clientInfo": {
      "name": "codex_vscode",
      "title": "Codex VS Code Extension",
      "version": "0.1.0"
    }
  }
}

特定の通知を受け取らない場合の例です。

{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true,
      "optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
    }
  }
}

実験的 API の有効化

app-server の一部のメソッドやフィールドは、experimentalApi 機能を明示的に有効にした場合にのみ使用できます。

  • capabilities を省略するか、experimentalApi を false に設定すると、安定版 API のみを使用できます。サーバーは実験的なメソッドやフィールドを拒否します。
  • capabilities.experimentalApi を true に設定すると、実験的なメソッドやフィールドが有効になります。
{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true
    }
  }
}

クライアントが有効化せずに実験的なメソッドやフィールドを送信すると、app-server はリクエストを拒否し、次のメッセージを返します。

<descriptor> requires experimentalApi capability

API の概要

  • thread/start:新しいスレッドを作成し、thread/started を送信します。クライアントはそのスレッドのターンとアイテムのイベントを自動的に購読します。
  • thread/resume:ID を指定して既存のスレッドを再開します。以降の turn/start 呼び出しはそのスレッドにターンを追加します。
  • thread/fork:保存済みの履歴をコピーし、新しいスレッド ID にフォークします。lastTurnId を渡すと、そのターンまでの履歴をコピーし、後続のターンは除外します。ephemeral: true を渡すと、メモリ内にフォークを作成します。新しいスレッドについて thread/started を送信し、返されるスレッドには、取得できる場合は forkedFromId が含まれます。
  • thread/read:スレッドを再開せず、ID を指定して保存済みのメタデータを読み取ります。履歴は thread/turns/list と thread/items/list で読み込みます。返される thread オブジェクトには実行時の status が含まれます。
  • thread/list:保存済みのスレッドとその実行時の状態をページ単位で取得します。ページネーションとフィルターを参照してください。
  • thread/turns/list:保存済みのスレッドを再開せずにターン履歴をページ単位で取得します。itemsView でターンのアイテムを省略するか、要約を取得するか、すべて読み込むかを指定します。
  • thread/items/list:永続化されたスレッドのアイテムをページ単位で取得します。必要に応じて 1 つの turnId に絞り込めます。使用中のスレッドストアがアイテムのページネーションに対応している必要があります。
  • thread/loaded/list:現在メモリに読み込まれているスレッドの ID を一覧表示します。
  • thread/name/set:読み込み済みのスレッドまたは永続化された実行記録(ロールアウト)の表示名を設定または更新し、thread/name/updated を送信します。
  • thread/goal/set:スレッドの目標を設定し、thread/goal/updated を送信します。
  • thread/goal/get:スレッドの現在の目標を読み取ります。
  • thread/goal/clear:スレッドの目標を消去し、thread/goal/cleared を送信します。
  • thread/metadata/update:スレッドに保存されている Git メタデータを更新します。
  • thread/archive:スレッドのログファイルをアーカイブディレクトリに移動し、派生した子孫スレッドのうち、未アーカイブのログのアーカイブも試みます。成功時は {} を返し、アーカイブしたスレッドごとに thread/archived を送信します。
  • thread/delete:永続化されたアクティブまたはアーカイブ済みのスレッドと、そこから派生した子孫スレッドを完全に削除します。成功時は {} を返し、削除したスレッドごとに thread/deleted を送信します。
  • thread/unsubscribe:この接続でスレッドのターンおよびアイテムのイベント購読を解除します。最後の購読者が解除した場合、購読者がいないままスレッドが一定期間非アクティブになると、サーバーはスレッドをアンロードし、thread/closed を送信します。
  • thread/unarchive:アーカイブ済みのスレッドのロールアウトをアクティブなセッションのディレクトリに戻します。復元した thread を返し、thread/unarchived を送信します。
  • thread/status/changed:読み込み済みのスレッドの実行時の status が変化したときに送信される通知です。
  • thread/compact/start:スレッドの会話履歴のコンパクションを開始します。直ちに {} を返し、進捗は turn/* と item/* の通知で配信します。
  • thread/shellCommand:スレッドに対して、ユーザーが指示したシェルコマンドを実行します。スレッドのサンドボックスポリシーは継承せず、サンドボックスの外でフルアクセスで実行します。
  • thread/backgroundTerminals/clean:スレッドで実行中のすべてのバックグラウンド ターミナルを停止します(実験的な機能で、capabilities.experimentalApi が必要です)。
  • thread/backgroundTerminals/list:読み込み済みのスレッドで実行中のバックグラウンド ターミナルを一覧表示します(実験的な機能で、capabilities.experimentalApi が必要です)。
  • thread/backgroundTerminals/terminate:app-server の processId を指定して、実行中のバックグラウンド ターミナルを 1 つ終了します(実験的な機能で、capabilities.experimentalApi が必要です)。
  • thread/revert:ページネーションに対応する永続スレッドの履歴から、指定したターンとそれ以降のすべてのターンを削除します。更新したメタデータと履歴カーソルを返してから、thread/reverted を送信します。
  • turn/start:ユーザー入力または独立したツール出力をスレッドに追加し、Codex による生成を開始します。初期状態の turn を返し、イベントを配信します。collaborationMode で settings.developer_instructions: null は「選択したモードの組み込み指示を使用する」という意味です。
  • thread/inject_items:ユーザーのターンを開始せずに、読み込み済みのスレッドでモデルが参照する履歴に、生の Responses API アイテムを追加します。
  • turn/steer:スレッドで進行中のターンにユーザー入力を追加し、入力を受け付けた turnId を返します。
  • turn/interrupt:進行中のターンのキャンセルを要求します。成功時は {} を返し、ターンは status: "interrupted" で終了します。
  • review/start:スレッドで Codex レビュアーを起動し、enteredReviewMode と exitedReviewMode のアイテムを送信します。
  • command/exec:スレッドやターンを開始せず、サーバーのサンドボックスで単一のコマンドを実行します。
  • command/exec/write:stdin のバイト列を実行中の command/exec セッションに書き込むか、stdin を閉じます。
  • command/exec/resize:PTY を使用する実行中の command/exec セッションのサイズを変更します。
  • command/exec/terminate:実行中の command/exec セッションを停止します。
  • command/exec/outputDelta(通知):ストリーミング中の command/exec セッションから、標準出力と標準エラー出力を Base64 エンコードしたチャンクで配信します。
  • process/spawn:Codex のサンドボックス外で明示的にプロセスセッションを開始します(実験的な機能で、capabilities.experimentalApi が必要です)。
  • process/writeStdin:実行中の process/spawn セッションの標準入力にバイト列を書き込むか、標準入力を閉じます(実験的)。
  • process/resizePty:PTY を使用する実行中のプロセスセッションのサイズを変更します(実験的)。
  • process/kill:実行中のプロセスセッションを終了します(実験的)。
  • process/outputDelta と process/exited(通知):プロセスの出力と終了ステータスをそれぞれ配信します(実験的)。
  • model/list:利用可能なモデルを一覧表示します(includeHidden: true を設定すると hidden: true の項目も含まれます)。各項目には推論強度の選択肢、任意の upgrade、inputModalities が含まれます。
  • modelProvider/capabilities/read:モデルとプロバイダーの組み合わせごとに、プロバイダーが対応する機能の範囲を読み取ります。
  • experimentalFeature/list:機能フラグとそのライフサイクル段階のメタデータを、カーソルによるページネーションで取得します。
  • experimentalFeature/enablement/set:apps や plugins など、対応する機能キーのメモリ内の実行時設定を部分更新します。
  • environment/info:設定済みの実行環境に接続し、シェルとデフォルトの作業ディレクトリを返します(実験的)。
  • permissionProfile/list:ベータ版の権限プロファイルと、有効な要件で各プロファイルの使用が許可されているかどうかを、カーソルによるページネーションで取得します。
  • collaborationMode/list:コラボレーションモードのプリセットを一覧表示します(実験的、ページネーションなし)。
  • skills/list:1 つ以上の cwd に対応するスキルを一覧表示します。forceReload と任意の perCwdExtraUserRoots に対応しています。
  • skills/extraRoots/set:単体のスキルを検出するための追加ルートをプロセス単位で置き換えます。設定は永続化されません。
  • skills/changed(通知):監視対象のローカルスキルファイルが変更されると送信されます。
  • hooks/list:1 つ以上の cwd で検出したライフサイクルフックを一覧表示します。
  • marketplace/add:リモートのプラグインマーケットプレイスを追加し、ユーザーのマーケットプレイス設定に保存します。
  • marketplace/remove:設定済みのマーケットプレイスを削除します。インストール済みのマーケットプレイスのルートがあれば、それも削除します。
  • marketplace/upgrade:設定済みの Git マーケットプレイスを更新します。名前を省略すると、設定済みのすべての Git マーケットプレイスを更新します。
  • plugin/list:開発中です。検出したプラグインマーケットプレイスとプラグインの状態を一覧表示します。インストールと認証のポリシーに関するメタデータ、マーケットプレイスの読み込みエラー、注目プラグインの ID、ローカル、Git、パッケージレジストリ、リモートの各プラグイン提供元のメタデータが含まれます。概要には、リモートの version、ローカルの localVersion、ライト/ダークテーマ用の構造化アイコン、installPolicySource が含まれる場合があります。現在のリモート項目でこの値は null、WORKSPACE_SETTING、IMPLICIT_CANONICAL_APP のいずれかです。現時点では、本番クライアントから呼び出さないでください。
  • plugin/read:開発中です。マーケットプレイスのパスまたはリモートマーケットプレイス名と、プラグイン名を指定して、プラグインを 1 件読み取ります。同梱のスキル、アプリ、MCP サーバー名のほか、リモートカタログが提供する場合はリモートプラグインの shareUrl も含まれます。現時点では、本番クライアントから呼び出さないでください。
  • plugin/install:開発中です。マーケットプレイスのパスまたはリモートマーケットプレイス名を指定してプラグインをインストールします。現時点では、本番クライアントから呼び出さないでください。
  • plugin/uninstall:開発中です。インストール済みのプラグインをアンインストールします。現時点では、本番クライアントから呼び出さないでください。
  • plugin/skill/read:リモートマーケットプレイス、プラグイン ID、スキル名を指定し、必要なときにリモートプラグインのスキルの Markdown を読み取ります。
  • app/installed:インストール済みアプリの実行時の状態を読み取ります。各アプリが実際に有効か、呼び出し可能かを確認できます。
  • app/list:利用可能なアプリ(コネクタ)をページ単位で一覧表示します。アクセスの可否と有効状態のメタデータも含まれます。
  • app/read:指定したアプリ ID のメタデータと、必要に応じて表示専用のツール概要を取得します。
  • skills/config/write:パスを指定してスキルを有効または無効にします。
  • mcpServer/oauth/login:設定済みの MCP サーバーで OAuth ログインを開始します。返された HTTP または HTTPS の authorizationUrl を開き、loginId を照合して対応する mcpServer/oauthLogin/completed 通知を特定します。
  • tool/requestUserInput:ツール呼び出しのために、ユーザーに 1~3 個の短い質問を提示します(実験的)。質問には isOther を設定して自由記述の選択肢を用意できます。
  • mcpServer/elicitation/request(サーバーリクエスト):MCP サーバーの要求に応じて、クライアントに構造化フォームへの入力または URL フローの確認を求めます。
  • item/permissions/requestApproval(サーバーリクエスト):組み込みの request_permissions ツールが要求したネットワーク権限またはファイルシステム権限のうち、許可する権限をクライアントに指定してもらいます。
  • config/mcpServer/reload:MCP サーバーの設定をディスクから再読み込みし、読み込み済みのスレッドの更新をキューに追加します。
  • mcpServerStatus/list:MCP サーバー、ツール、リソース、認証状態を一覧表示します(カーソルと件数上限によるページネーション)。すべてのデータを取得するには detail: "full"、リソースを省くには detail: "toolsAndAuthOnly" を使用します。どちらのモードでも、サーバーが通知した機能が serverCapabilities に含まれます。初期化に成功するまでは null です。serverName を渡すと 1 台のサーバーに絞り込めます。threadId を指定すると、そのスレッドの MCP 接続を再利用します。
  • mcpServer/resource/read:初期化済みの MCP サーバーを介して、MCP リソースを 1 件読み取ります。
  • mcpServer/tool/call:スレッドに設定された MCP サーバーのツールを呼び出します。
  • mcpServer/startupStatus/updated(通知):読み込み済みのスレッドで、設定済みの MCP サーバーの起動状態が変化したときに送信されます。
  • windowsSandbox/readiness:Windows サンドボックスの準備状態を確認します。updateRequired が返った場合は windowsSandbox/setupStart を呼び出し、windowsSandbox/setupCompleted を待ちます。
  • feedback/upload:分類、任意の理由とログ、会話 ID、任意の extraLogFiles 添付ファイルを含むフィードバックレポートを送信します。
  • config/read:各設定レイヤーの優先順位を適用したうえで、ディスク上の実効設定を取得します。
  • externalAgentConfig/detect:includeHome と任意の cwds を指定して、移行可能な外部エージェントのデータを検出します。検出した各項目には cwd が含まれます(ホームの場合は null)。
  • externalAgentConfig/import:migrationItems に cwd(ホームの場合は null)を含めて明示的に渡し、選択した外部エージェントの移行項目を適用します。設定、スキル、AGENTS.md、プラグイン、MCP サーバー設定、サブエージェント、フック、コマンド、セッションに対応しています。インポート対象がある場合は、処理に応じて externalAgentConfig/import/progress と externalAgentConfig/import/completed を送信します。プラグインとセッションのインポートは非同期で完了することがあります。
  • config/value/write:設定のキーと値の組を 1 つ、ディスク上のユーザーの config.toml に書き込みます。
  • config/batchWrite:ディスク上のユーザーの config.toml に複数の設定変更をアトミックに適用します。
  • configRequirements/read:requirements.toml、MDM、またはその両方から、許可リストや固定の featureRequirements などの要件を取得します。experimentalApi を有効にしたクライアントは、管理対象のネットワーク要件も読み取れます。
  • fs/readFile、fs/writeFile、fs/createDirectory、fs/getMetadata、fs/readDirectory、fs/remove、fs/copy、fs/watch、fs/unwatch、fs/changed(通知):app-server v2 のファイルシステム API を介して絶対パスを扱います。

プラグインの概要には共用体 source が含まれます。ローカルプラグインは { "type": "local", "path": ... }、Git ベースのマーケットプレイス項目は { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }、パッケージレジストリの項目は { "type": "npm", "package": ..., "version": ..., "registry": ... }、リモートカタログの項目は { "type": "remote" } を返します。リモートにしか存在しないカタログ項目では PluginMarketplaceEntry.path が null の場合があります。このようなプラグインを読み取ったりインストールしたりする際は、remoteMarketplaceName を marketplacePath の代わりに渡してください。

モデル

モデルの一覧取得(model/list)

model/list を呼び出し、利用可能なモデルと推論強度をモデル選択 UI に表示します。

以下はレスポンスの構造を示す例です。利用可能なモデル、推論強度、デフォルト値はクライアントとアカウントによって異なるため、例の値をハードコードせず、返された値を使用してください。

{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
  "data": [{
    "id": "gpt-6.1-sol",
    "model": "gpt-6.1-sol",
    "displayName": "GPT-6.1 Sol",
    "hidden": false,
    "defaultReasoningEffort": "medium",
    "supportedReasoningEfforts": [{
      "reasoningEffort": "medium",
      "description": "Balances speed and reasoning depth for everyday tasks"
    }],
    "inputModalities": ["text", "image"],
    "supportsPersonality": false,
    "isDefault": true
  }],
  "nextCursor": null
} }

各モデルの項目には、次のフィールドが含まれる場合があります。

  • supportedReasoningEfforts:モデルが対応する推論強度の選択肢
  • defaultReasoningEffort:クライアントに推奨されるデフォルトの推論強度
  • upgrade:クライアントが移行を案内するときに推奨する移行先モデルの ID(任意)
  • upgradeInfo:クライアントが移行を案内するときに使用するアップグレードのメタデータ(任意)
  • hidden:デフォルトのモデル選択リストで非表示かどうか
  • inputModalities:モデルが対応する入力の種類(例:text、image)
  • supportsPersonality:互換性のための非推奨フィールドで、常に false です。モデルはパーソナリティの選択に対応しなくなりました。
  • isDefault:デフォルトとして推奨されるモデルかどうか

起動時のプロバイダーが管理要件を満たさなくなると、model/list は -32600 を返し、クライアントに Codex の再起動を求めます。

デフォルトでは、model/list は選択リストに表示するモデルのみを返します。全件を取得してクライアント側で絞り込む場合は、includeHidden: true を設定し、hidden を使ってフィルタリングします。

古いモデルカタログで inputModalities がない場合は、後方互換性を保つため ["text", "image"] として扱ってください。

実験的な機能の一覧取得(experimentalFeature/list)

このエンドポイントでは、機能フラグと、そのメタデータおよびライフサイクル段階を取得できます。

{ "method": "experimentalFeature/list", "id": 7, "params": { "limit": 20 } }
{ "id": 7, "result": {
  "data": [{
    "name": "unified_exec",
    "stage": "beta",
    "displayName": "Unified exec",
    "description": "Use the unified PTY-backed execution tool.",
    "announcement": "Beta rollout for improved command execution reliability.",
    "enabled": false,
    "defaultEnabled": false
  }],
  "nextCursor": null
} }

stage の値は beta、underDevelopment、stable、deprecated、removed のいずれかです。ベータ以外のフラグでは、displayName、description、announcement が null の場合があります。

実行環境の確認(実験的)

設定済みのリモート環境で作業を開始する前に、environment/info で環境を確認できます。このメソッドには capabilities.experimentalApi = true が必要です。

{ "method": "environment/info", "id": 8, "params": { "environmentId": "devbox" } }
{ "id": 8, "result": {
  "shell": { "name": "zsh", "path": "/bin/zsh" },
  "cwd": "file:///workspace/project"
} }

cwd は null の場合があります。値がある場合は、その環境固有のパス構文を使用した正規の file: URI です。未知の環境 ID を指定した場合や、接続またはプロトコルに障害が発生した場合は、リクエストエラーが返ります。

スレッド

  • thread/read は、スレッドを購読せずに保存済みのメタデータを読み取ります。
  • thread/turns/list は、保存済みのスレッドを再開せずにターン履歴をページ単位で取得します。itemsView で、ターンのアイテムを省略するか、要約を取得するか、すべて読み込むかを選択します。
  • thread/items/list は、永続化されたスレッドのアイテムをページ単位で取得します。必要に応じて 1 つのターンに絞り込めます。
  • thread/list は保存済みのスレッドをページ単位で取得します。特定のセクションのスレッドを取得するには sectionId を、画面に表示済みのスレッドを除外するには excludedThreadIds を指定します。
  • thread/loaded/list は、現在メモリに読み込まれているスレッドの ID を返します。
  • thread/archive はスレッドの永続化された JSONL ログをアーカイブディレクトリに移動し、派生した子孫スレッドのうち、未アーカイブのログのアーカイブも試みます。
  • thread/delete は、永続化されたアクティブまたはアーカイブ済みのスレッドと、そこから派生した子孫スレッドを完全に削除します。
  • thread/metadata/update は、スレッドに保存されている gitInfo を更新します。
  • thread/unsubscribe は、現在の接続で読み込み済みのスレッドの購読を解除します。その後、非アクティブ状態が一定期間続くと thread/closed が送信されることがあります。
  • thread/unarchive は、アーカイブ済みのスレッドのロールアウトをアクティブなセッションのディレクトリに戻します。
  • thread/compact/start はコンパクションを開始し、直ちに {} を返します。
  • thread/revert は、ページネーションに対応する永続スレッドの履歴から、指定したターンとそれ以降のすべてのターンを削除します。ローカルファイルには影響しません。
  • thread/inject_items は、ユーザーのターンを開始せずに、読み込み済みのスレッドでモデルが参照する履歴に、生の Responses API アイテムを追加します。

スレッドの開始と再開

Codex で新しい会話を始めるには、新しいスレッドを開始します。

{ "method": "thread/start", "id": 10, "params": {
"model": "gpt-6.1-sol",
"cwd": "/Users/me/project",
"approvalPolicy": "never",
"sandbox": "workspace-write",
"serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
"thread": {
  "id": "thr_123",
  "sessionId": "thr_123",
  "preview": "",
  "ephemeral": false,
  "modelProvider": "openai",
  "createdAt": 1730910000
}
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }

serviceName は任意です。app-server のスレッド単位のメトリクスに統合先のサービス名を付ける場合に設定します。

thread/start、thread/resume、thread/fork は instructionSources を返します。これは、読み込んだ指示ファイルのパスの配列です。リモート環境を含め、各パスはファイルの取得元の環境に固有の絶対パス構文で表されます。

新しい永続ローカルスレッドの履歴は、デフォルトでページネーションに対応しています。履歴は thread/turns/list と thread/items/list で読み込みます。historyMode を "legacy" または "paginated" に明示的に設定する thread/start の機能は実験的であり、capabilities.experimentalApi = true が必要です。

capabilities.experimentalApi を有効にしたベータ版クライアントは、permissions に名前付き権限プロファイルの ID を渡せます。これは従来の sandbox フィールドに代わるものです。permissions と sandbox は同時に送信しないでください。permissionProfile/list にプロジェクトの cwd を指定すると、利用可能なプロファイルと、管理要件が各プロファイルを許可しているかどうかを確認できます。

thread.sessionId は、現在実行中のセッションツリーのルートを識別します。ルートスレッドは自身のスレッド ID をセッション ID に使用し、フォークしたスレッドは派生元のルートのセッション ID を引き継ぎます。クライアントはスレッド ID から推定せず、thread.sessionId からセッション ID を読み取ってください。

保存済みのセッションを続けるには、thread/resume に以前記録した thread.id を渡します。excludeTurns: true を渡してスレッドのメタデータと現在のセッション状態を取得し、ページネーション用のメソッドで履歴を読み込みます。

{ "method": "thread/resume", "id": 11, "params": {
  "threadId": "thr_123",
  "excludeTurns": true
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }

ページネーションに対応するスレッドでは、thread/resume と thread/fork で全履歴を返す方式は非推奨で、deprecationNotice が送信されます。どちらのメソッドも、実験的 API を有効にせずに excludeTurns: true を指定できます。thread/resume のレスポンスには turnsBackwardsCursor と itemsBackwardsCursor が含まれることもあります。それぞれを対応するページネーション用のメソッドに sortDirection: "desc" とともに渡します。最初のページにはカーソルの基準となる項目も含まれます。

スレッドを再開しただけでは thread.updatedAt(またはロールアウトファイルの更新日時)は更新されません。タイムスタンプはターンを開始すると更新されます。

有効な MCP サーバーを設定で required に指定した場合、そのサーバーの初期化に失敗すると、thread/start と thread/resume も失敗します。サーバーなしで処理を続行することはありません。

dynamicTools は thread/start の実験的なフィールドです(capabilities.experimentalApi = true が必要です)。Codex はこれらの動的ツールをスレッドのロールアウトのメタデータに保存し、新しい動的ツールが指定されていなければ thread/resume 時に復元します。

設定中のモデルプロバイダーがスレッドに保存されたプロバイダーと異なる場合、thread/resume と新しい入力に対して -32600 が返り、data.type は modelProviderMismatch になります。履歴を表示するには、ターンをページ単位で取得できる thread/turns/list を使用してください。そのスレッドを続けるには、保存されているプロバイダーに戻します。現在のプロバイダーを使う場合は、thread/fork を呼び出して既存の履歴から新しいスレッドを開始します。

ロールアウトに記録されたモデルと異なるモデルで再開すると、Codex は警告を送信し、次のターンに限りモデル切り替えの指示を適用します。

スレッドの目標管理

thread/goal/set、thread/goal/get、thread/goal/clear で、TUI の /goal に表示される永続化された目標の状態を管理できます。

{ "method": "thread/goal/set", "id": 13, "params": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000,
  "tokensUsed": 0,
  "timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
  "threadId": "thr_123",
  "goal": {
    "threadId": "thr_123",
    "objective": "Finish the migration and keep tests green",
    "status": "active",
    "tokenBudget": 40000,
    "tokensUsed": 0,
    "timeUsedSeconds": 0
  }
} }

目標の内容は空にできず、上限は 4,000 文字です。新しい内容を指定すると目標が置き換わり、使用量の集計がリセットされます。終了状態にない現在の目標と同じ内容を指定するか、objective を省略すると、使用履歴を保持したままステータスまたはトークン予算を更新できます。

保存済みのセッションから分岐するには、thread/fork に thread.id を渡します。新しいスレッド ID が作成され、そのスレッドの thread/started 通知が送信されます。lastTurnId を渡すと、指定したターンを含むそこまでの履歴がコピーされ、それ以降のターンは除外されます。

{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456", "excludeTurns": true } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }

app-server は、進行中のターンの lastTurnId を拒否します。派生元スレッドでターンが進行中にこのフィールドを省略すると、フォークには未完了のターンがそのまま残るのではなく、中断を示すマーカーが記録されます。

ephemeral: true を渡すと、保存済みスレッドの一覧に追加せずにメモリ内にフォークを作成できます。

{
  "method": "thread/fork",
  "id": 13,
  "params": {
    "threadId": "thr_123",
    "ephemeral": true,
    "excludeTurns": true
  }
}
{
  "id": 13,
  "result": {
    "thread": {
      "id": "thr_789",
      "sessionId": "thr_789",
      "forkedFromId": "thr_123",
      "ephemeral": true
    }
  }
}

ページネーションに対応するスレッドの一時フォークには excludeTurns: true が必要です。

ユーザー向けのスレッドタイトルが設定されている場合、app-server は thread.name にその値を設定して、thread/list、thread/read、thread/resume、thread/unarchive のレスポンスを返します。thread/start と thread/fork では、タイトルが設定されるまで name が省略されるか、null が返ることがあります。

保存済みスレッドの読み取り(再開なし)

スレッドを再開したりイベントを購読したりせずに保存済みのデータを取得するには、thread/read を使用します。

  • includeTurns:false または省略時はスレッドの概要のみを返します。true に設定すると全履歴を読み込みますが、ページネーションに対応するスレッドではこの方法は非推奨で、deprecationNotice が送信されます。代わりにページネーション用のメソッドを使用してください。
  • 返される thread オブジェクトには実行時の status が含まれます(notLoaded、idle、systemError、または active と activeFlags)。
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123" } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }

thread/resume と異なり、thread/read はスレッドをメモリに読み込まず、thread/started も送信しません。

スレッドのターン一覧

thread/turns/list を使うと、保存済みのスレッドを再開せずにターン履歴をページ単位で取得できます。デフォルトでは新しい順に返るため、nextCursor で古いターンを取得できます。レスポンスには backwardsCursor も含まれます。これを cursor として渡し、sortDirection に逆の方向を指定すると、取得方向が反転します。基準となるターンも再度含まれるため、そのターンの更新を取得できます。

itemsView は、レスポンスに含めるターンのアイテムデータの詳細度を制御します。

  • notLoaded はアイテムを省略します。
  • summary はアイテムの要約データを返します。指定を省略した場合のデフォルトです。
  • full はアイテムの全データを返します。
{ "method": "thread/turns/list", "id": 20, "params": {
  "threadId": "thr_123",
  "limit": 50,
  "sortDirection": "desc",
  "itemsView": "summary"
} }
{ "id": 20, "result": {
  "data": [],
  "nextCursor": "older-turns-cursor-or-null",
  "backwardsCursor": "newer-turns-cursor-or-null"
} }

スレッドのアイテム一覧

thread/items/list は、スレッドを再開せずに永続化されたアイテムをページ単位で取得します。turnId を渡すと結果を 1 つのターンに絞り込み、省略するとスレッド全体のアイテムを取得します。デフォルトは古い順(sortDirection: "asc")です。使用中のスレッドストアがアイテムのページネーションに対応していない場合、サーバーはメソッドがサポートされていないことを示すエラーを返します。

続きを取得するには、前回のレスポンスに含まれる不透明な nextCursor を渡します。既知のアイテムの次から取得するには、基準となるアイテムと空でない turnId を渡します。

{ "method": "thread/items/list", "id": 21, "params": {
  "threadId": "thr_123",
  "turnId": "turn_456",
  "cursor": { "type": "item", "itemId": "item_123" },
  "sortDirection": "asc",
  "limit": 50
} }
{ "id": 21, "result": {
  "data": [],
  "nextCursor": null,
  "backwardsCursor": null
} }

基準となるアイテム自体は結果に含まれません。昇順ではそれより新しいアイテム、降順ではそれより古いアイテムが返ります。基準のアイテムは、指定したターンの参照可能な履歴に含まれている必要があります。turnId がない場合、アイテム ID が空の場合、またはアイテムが未知もしくは対象範囲外の場合は、パラメータエラー(-32602)が返ります。続きを取得するには、返された文字列 nextCursor を使用します。各結果には turnId、item、記録されていれば開始時刻と完了時刻が含まれます。

スレッドの一覧取得(ページネーションとフィルター)

thread/list を使って履歴 UI を表示できます。結果はデフォルトで createdAt の新しい順に返ります。フィルターはページネーションの前に適用されます。次のパラメータを組み合わせて渡せます。

  • cursor:前回のレスポンスに含まれる不透明な文字列です。最初のページでは省略します。
  • limit:未設定の場合、サーバーが適切なデフォルトのページサイズを使用します。
  • sortKey:created_at(デフォルト)、updated_at、recency_at、section_position のいずれかです。section_position を使うには、null 以外のセクション ID を sectionId に指定します。
  • sortDirection:asc または desc を指定します。sortDirection を省略すると、section_position は昇順、時刻に基づくキーは降順になります。
  • sectionId:セクション ID を指定するとそのセクションのスレッドを、null を指定すると未割り当てのスレッドを取得します。フィールドを省略すると、すべてのセクションのスレッドと未割り当てのスレッドが対象です。
  • excludedThreadIds:除外するスレッド ID を最大 100 件指定できます。重複する ID も 100 件の上限に数えます。サーバーは該当するスレッドを除外してからページの件数上限を適用します。各カーソルとともに同じ除外リストを送信してください。
  • modelProviders:特定のプロバイダーに絞り込みます。[] を渡すとすべてのプロバイダーが対象です。省略するか null を渡すと、サーバーは設定済みのプロバイダーを使用します。ただし、スレッド間の親子関係で絞り込む場合は、すべてのプロバイダーが対象になります。
  • sourceKinds:スレッドの生成元を絞り込みます。省略するか [] を渡すと、デフォルトで対話型の生成元である cli と vscode のみが対象になります。
  • archived:true の場合はアーカイブ済みのスレッドのみを返します。false または省略時は未アーカイブのスレッドを返します(デフォルト)。
  • cwd:セッションの現在の作業ディレクトリが、指定したパスまたは配列内のいずれかのパスと完全に一致するスレッドに絞り込みます。相対パスは app-server プロセスの作業ディレクトリを基準に解決します。
  • useStateDbOnly:true の場合は、メタデータ修復のための JSONL スレッドログのスキャンを行わず、状態データベースの結果を返します。省略するか false を渡すと、デフォルトのスキャンと修復を行います。
  • searchTerm:抽出したタイトルに指定の文字列を含むスレッドに絞り込みます。大文字と小文字は区別されます。
  • parentThreadId:指定した親スレッドの直接の子スレッドに絞り込みます。このフィルターは実験的で、capabilities.experimentalApi = true が必要です。
  • ancestorThreadId:指定したスレッドから派生したすべての子孫スレッドに、階層の深さを問わず絞り込みます。このフィルターは実験的で、capabilities.experimentalApi = true が必要です。parentThreadId と併用しないでください。

sourceKinds には次の値を指定できます。

  • cli
  • vscode
  • exec
  • appServer
  • subAgent
  • subAgentReview
  • subAgentCompact
  • subAgentThreadSpawn
  • subAgentOther
  • unknown

例を示します。

{ "method": "thread/list", "id": 20, "params": {
  "cursor": null,
  "limit": 25,
  "sortKey": "created_at"
} }
{ "id": 20, "result": {
  "data": [
    { "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "section": { "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318", "name": "Pinned", "appearance": null }, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
    { "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "section": null, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
  ],
  "nextCursor": "opaque-token-or-null"
} }

nextCursor が null なら、最後のページです。

セクションによるスレッドの整理

threadSection/create で名前付きのセクションを作成し、返された section.id を thread/section/move に渡します。beforeThreadId を渡すと、セクション内の指定したスレッドの直前に挿入します。省略すると末尾に追加します。スレッドをセクションから外すには sectionId: null を渡します。カスタムセクションの一覧をページ単位で取得するには threadSection/list、名前を変更するには threadSection/update、削除するには threadSection/delete を使用します。スレッドをピン留めするには、threadSection/list が返す組み込みの Pinned セクションに移動します。

スレッドに関連付けたリソースの管理

添付機能を使うと、Pull Request などのリソースを保存済みのスレッドに関連付けられます。スレッドを再開せずにこれらの参照を管理できます。

  • thread/attachment/add には threadId、attachmentType、identityKey、JSON 形式の payload を渡します。同じスレッドに同じ種類とキーで再度追加すると、既存の添付情報が返ります。
  • thread/attachment/list はスレッドの添付情報をページ単位で取得します。リソースを参照しているスレッドを探すには、thread/attachmentOwner/list にそのリソースの attachmentType と identityKey を渡します。
  • thread/attachment/remove には threadId、attachmentType、identityKey を渡します。関連付けを解除した後もリソース自体は利用できます。
  • thread/attachment/updated は、関連付けが変わったときに created または deleted の操作を通知します。

保存済みスレッドのメタデータ更新

thread/metadata/update を使うと、スレッドを再開せずに保存済みのメタデータを部分更新できます。gitInfo に更新したい Git フィールドを指定します。値を保持するフィールドは省略し、値を消去するフィールドには null を渡します。

{ "method": "thread/metadata/update", "id": 21, "params": {
  "threadId": "thr_123",
  "gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
  "thread": {
    "id": "thr_123",
    "gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
  }
} }

スレッドの状態変化の追跡

thread/status/changed は、読み込み済みスレッドの実行時の状態が変化するたびに送信されます。ペイロードには threadId と新しい status が含まれます。

{
  "method": "thread/status/changed",
  "params": {
    "threadId": "thr_123",
    "status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
  }
}

読み込み済みスレッドの一覧

thread/loaded/list は、現在メモリに読み込まれているスレッドの ID を返します。

{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }

読み込み済みスレッドの購読解除

thread/unsubscribe は、現在の接続でスレッドの購読を解除します。レスポンスのステータスは次のいずれかです。

  • unsubscribed:この接続で購読していたスレッドの購読を解除した場合
  • notSubscribed:この接続でそのスレッドを購読していなかった場合
  • notLoaded:スレッドが読み込まれていない場合

最後の購読者が購読を解除した後、スレッドがデフォルトで 60 秒間アイドル状態にあると、app-server はスレッドをアンロードします。この待機時間は thread_unload_delay_secs で変更できます。アンロード時には、app-server が thread/status/changed で notLoaded への遷移を通知し、thread/closed 通知を送信します。

{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }

その後、猶予期間が過ぎると次の通知が届きます。

{ "method": "thread/status/changed", "params": {
    "threadId": "thr_123",
    "status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }

スレッドのアーカイブ

thread/archive を使用すると、ディスク上に JSONL ファイルとして保存されたスレッドログが、アーカイブ済みセッションのディレクトリに移動します。スレッドをアーカイブすると、そこから派生した未アーカイブの子孫スレッドについてもアーカイブを試みます。

{ "method": "thread/archive", "id": 22, "params": { "threadId": "thr_b" } }
{ "id": 22, "result": {} }
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
{ "method": "thread/archived", "params": { "threadId": "thr_child" } }

アーカイブ済みのスレッドは、以降の thread/list 呼び出しで archived: true を渡さない限り表示されません。サーバーは実際にアーカイブしたスレッドごとに thread/archived 通知を 1 件送信します。派生した子孫スレッドをアーカイブできなくても、そのスレッドの通知を送信せずにリクエスト自体は成功することがあります。

スレッドの削除

thread/delete は、永続化されたアクティブまたはアーカイブ済みのスレッドと、そこから派生した子孫スレッドを完全に削除します。サーバーは既存のロールアウトファイルと関連メタデータを削除してから成功を返します。存在しないロールアウトファイルは削除済みとして扱います。一時的なルートスレッドは削除できません。

{ "method": "thread/delete", "id": 23, "params": { "threadId": "thr_b" } }
{ "id": 23, "result": {} }
{ "method": "thread/deleted", "params": { "threadId": "thr_b" } }
{ "method": "thread/deleted", "params": { "threadId": "thr_child" } }

スレッドのアーカイブ解除

thread/unarchive は、アーカイブ済みのスレッドのロールアウトをアクティブなセッションのディレクトリに戻します。

{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
{ "id": 24, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes" } } }
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }

スレッドのコンパクションの開始

thread/compact/start はスレッド履歴のコンパクションを手動で開始します。リクエストには直ちに {} が返ります。

app-server は標準の turn/* および item/* 通知を同じ threadId で送信して進捗を伝えます。これには contextCompaction アイテムのライフサイクル(item/started に続いて item/completed)が含まれます。

{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }

スレッドでのシェルコマンドの実行

thread/shellCommand は、ユーザーがスレッド内で明示的に指示したシェルコマンドに使用します。リクエストには直ちに {} が返り、進捗は標準の turn/* および item/* 通知で配信されます。

この API はスレッドのサンドボックスポリシーを継承せず、サンドボックス外でフルアクセスで実行されます。クライアントは、ユーザーが明示的に実行を指示したコマンドに限ってこの API を提供してください。

スレッドでターンが進行中の場合、コマンドはそのターンの補助操作として実行され、整形された出力がターンのメッセージストリームに挿入されます。スレッドがアイドル状態の場合は、app-server がシェルコマンド専用のターンを開始します。

実行時間の上限は timeoutMs にミリ秒単位で設定します。省略するか null を渡すと、デフォルトの 1 時間が適用されます。0 は即時タイムアウトを指定し、負の値は拒否されます。タイムアウトを設定しても、RPC の受付応答は直ちに返ります。

{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }

バックグラウンド ターミナルの停止

thread/backgroundTerminals/clean は、スレッドに関連付けられた実行中のバックグラウンド ターミナルをすべて停止します。このメソッドは実験的で、capabilities.experimentalApi = true が必要です。

{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }

thread/backgroundTerminals/list で、読み込み済みのスレッドで実行中のバックグラウンド ターミナルを確認できます。リクエストは標準の cursor と limit によるページネーションに対応し、返される processId は app-server のプロセス ID です。このメソッドは実験的で、capabilities.experimentalApi = true が必要です。

{ "method": "thread/backgroundTerminals/list", "id": 28, "params": { "threadId": "thr_b" } }
{ "id": 28, "result": { "data": [
  {
    "itemId": "item_456",
    "processId": "42",
    "command": "python3 -m http.server",
    "cwd": "/workspace",
    "osPid": null,
    "cpuPercent": null,
    "rssKb": null
  }
], "nextCursor": null } }

thread/backgroundTerminals/terminate にその processId を渡すと、指定したバックグラウンド ターミナルを停止できます。このメソッドは実験的で、capabilities.experimentalApi = true が必要です。

{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }

スレッド履歴の巻き戻し

thread/revert は、ページネーションに対応する永続スレッドの会話履歴から、beforeTurnId で指定したターンと、それ以降のすべてのターンを削除します。ローカルファイルの変更は元に戻しません。スレッドが読み込まれていない場合は、先に再開してください。一時スレッドと従来形式の履歴を持つスレッドは対象外です。

{ "method": "thread/revert", "id": 30, "params": { "threadId": "thr_b", "beforeTurnId": "turn_456" } }
{ "id": 30, "result": {
  "thread": { "id": "thr_b", "ephemeral": false, "turns": [] },
  "turnsBackwardsCursor": "retained-turn-cursor-or-null",
  "itemsBackwardsCursor": "retained-item-cursor-or-null"
} }
{ "method": "thread/reverted", "params": { "threadId": "thr_b" } }

返される thread.turns は常に空です。返されたカーソルを thread/turns/list または thread/items/list に sortDirection: "desc" とともに渡すと、カーソルの基準となる項目を含め、残っている履歴を読み込めます。

thread/rollback は削除されており、呼び出すと未知のメソッドを示すエラーが返ります。以前に保存されたスレッドにある既存のロールバックマーカーは引き続き読み取れます。

ターン

input フィールドにはアイテムのリストを渡します。

  • { "type": "text", "text": "Explain this diff" }
  • { "type": "image", "url": "https://.../design.png" }
  • { "type": "localImage", "path": "/tmp/screenshot.png" }

ターンごとに設定(モデル、推論強度、cwd、サンドボックスポリシー、要約)を上書きできます。指定した設定は、同じスレッドの後続ターンのデフォルトになります。outputSchema は現在のターンにのみ適用されます。sandboxPolicy.type = "externalSandbox" の場合は networkAccess を restricted または enabled に設定します。workspaceWrite の場合、networkAccess は引き続きブール値です。

turn/start.collaborationMode で settings.developer_instructions: null を指定すると、モードの指示を消去するのではなく、選択したモードの組み込み指示を使用します。

サンドボックスの読み取りアクセス(ReadOnlyAccess)

sandboxPolicy では、読み取りアクセスを明示的に制御できます。

  • readOnly:任意の access(デフォルトは { "type": "fullAccess" }、またはアクセス可能なルートを限定)
  • workspaceWrite:任意の readOnlyAccess(デフォルトは { "type": "fullAccess" }、またはアクセス可能なルートを限定)

読み取りアクセスを制限する場合は、次の形式を使用します。

{
  "type": "restricted",
  "includePlatformDefaults": true,
  "readableRoots": ["/Users/me/shared-read-only"]
}

macOS では、includePlatformDefaults: true を設定すると、読み取りを制限したセッションに、プラットフォームのデフォルトとして選定された Seatbelt ポリシーが追加されます。これにより、/System 全体へのアクセスを許可せずにツールとの互換性を高められます。

設定例を示します。

{ "type": "readOnly", "access": { "type": "fullAccess" } }
{
  "type": "workspaceWrite",
  "writableRoots": ["/Users/me/project"],
  "readOnlyAccess": {
    "type": "restricted",
    "includePlatformDefaults": true,
    "readableRoots": ["/Users/me/shared-read-only"]
  },
  "networkAccess": false
}

ターンの開始

{ "method": "turn/start", "id": 30, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Run tests" } ],
"cwd": "/Users/me/project",
"approvalPolicy": "on-request",
"sandboxPolicy": {
  "type": "workspaceWrite",
  "writableRoots": ["/Users/me/project"],
  "networkAccess": true
},
"model": "gpt-6.1-sol",
"effort": "medium",
"summary": "concise",
"outputSchema": {
  "type": "object",
  "properties": { "answer": { "type": "string" } },
  "required": ["answer"],
  "additionalProperties": false
}
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }

新しく開始する 1 ターンだけサービスティアを変更するには、serviceTierForTurn を設定します。標準速度には "default" を指定します。フィールドを省略すると、スレッドのサービスティアを引き継ぎます。このターンと後続のターンのサービスティアを変更するには、serviceTier を設定します。

クライアントで実行したツールの出力を使ってターンを開始するには、toolOutput に空でない name、任意の namespace、文字列またはコンテンツアイテムの配列を値とする output を指定します。input は空配列にしてください。toolOutput と空でないユーザー入力は併用できません。

{
  "method": "turn/start",
  "id": 31,
  "params": {
    "threadId": "thr_123",
    "input": [],
    "toolOutput": {
      "name": "run_tests",
      "namespace": null,
      "output": "All 42 tests passed."
    }
  }
}

この出力は会話内でもツール出力として扱われ、通知と永続化された履歴には functionCallOutput アイテムとして現れます。通常のターンがすでに進行中の場合、Codex はそのターン用のキューに出力を追加します。

スレッドへのアイテムの挿入

thread/inject_items を使うと、ユーザーのターンを開始せずに、あらかじめ作成した Responses API アイテムを読み込み済みスレッドのプロンプト履歴に追加できます。これらのアイテムはロールアウトに保存され、以降のモデルリクエストに含まれます。

{ "method": "thread/inject_items", "id": 31, "params": {
  "threadId": "thr_123",
  "items": [
    {
      "type": "message",
      "role": "assistant",
      "content": [{ "type": "output_text", "text": "Previously computed context." }]
    }
  ]
} }
{ "id": 31, "result": {} }

進行中のターンへの追加入力

turn/steer を使うと、現在進行中のターンにユーザー入力を追加できます。

  • expectedTurnId は必須で、進行中のターンの ID と一致する必要があります。
  • スレッドで進行中のターンがない場合、リクエストは失敗します。
  • turn/steer は新しい turn/started 通知を送信しません。
  • turn/steer はターン単位の設定の上書き(model、cwd、sandboxPolicy、outputSchema)を受け付けません。
{ "method": "turn/steer", "id": 32, "params": {
  "threadId": "thr_123",
  "input": [ { "type": "text", "text": "Actually focus on failing tests first." } ],
  "expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }

スキルを呼び出すターンの開始

スキルを明示的に呼び出すには、テキスト入力に $<skill-name> を含め、併せて skill 入力アイテムを追加します。

{ "method": "turn/start", "id": 33, "params": {
  "threadId": "thr_123",
  "input": [
    { "type": "text", "text": "$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage." },
    { "type": "skill", "name": "skill-creator", "path": "/Users/me/.codex/skills/skill-creator/SKILL.md" }
  ]
} }
{ "id": 33, "result": { "turn": { "id": "turn_457", "status": "inProgress", "items": [], "error": null } } }

ターンの中断

{ "method": "turn/interrupt", "id": 31, "params": { "threadId": "thr_123", "turnId": "turn_456" } }
{ "id": 31, "result": {} }

成功すると、ターンは status: "interrupted" で終了します。

レビュー

review/start はスレッドで Codex レビュアーを実行し、レビューアイテムを配信します。次の対象を指定できます。

  • uncommittedChanges
  • baseBranch(指定したブランチとの差分)
  • commit(特定のコミットのレビュー)
  • custom(自由記述の指示)

review/start は指定したスレッドでレビューを実行します。delivery は省略するか、"inline" を指定します。レビュー用に別のスレッドを使う場合、既存の履歴を引き継ぐには thread/fork、履歴のないスレッドを開始するには thread/start を使用します。その後、新しいスレッド ID を指定して review/start を呼び出します。

リクエストとレスポンスの例を示します。

{ "method": "review/start", "id": 40, "params": {
  "threadId": "thr_123",
  "delivery": "inline",
  "target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
  "turn": {
    "id": "turn_900",
    "status": "inProgress",
    "items": [
      { "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
    ],
    "error": null
  },
  "reviewThreadId": "thr_123"
} }

Codex は通常の turn/started 通知に続いて、item/started で enteredReviewMode アイテムを配信します。

{
  "method": "item/started",
  "params": {
    "item": {
      "type": "enteredReviewMode",
      "id": "turn_900",
      "review": "current changes"
    }
  }
}

レビュアーが終了すると、サーバーは item/started と item/completed を送信します。これらには、最終的なレビュー本文を含む exitedReviewMode アイテムが含まれます。

{
  "method": "item/completed",
  "params": {
    "item": {
      "type": "exitedReviewMode",
      "id": "turn_900",
      "review": "Looks solid overall..."
    }
  }
}

この通知を使ってクライアントにレビュー結果を表示します。

プロセスの実行

process/* は、プロセスを明示的に制御する実験的な API です。capabilities.experimentalApi = true が必要で、Codex のサンドボックス外で実行されます。クライアントがサンドボックスを使わずにローカルプロセスの制御を意図的に提供する場合にのみ使用してください。

process/spawn に processHandle を指定してプロセスを開始します。そのハンドルを標準入力、サイズ変更、終了の各リクエストで使用します。出力は process/outputDelta 通知で配信され、完了は process/exited で通知されます。

{ "method": "process/spawn", "id": 48, "params": {
  "command": ["python3", "-m", "pytest", "-q"],
  "processHandle": "pytest-1",
  "cwd": "/Users/me/project",
  "tty": true
} }
{ "id": 48, "result": {} }
{ "method": "process/outputDelta", "params": {
  "processHandle": "pytest-1",
  "stream": "stdout",
  "deltaBase64": "Li4u"
} }
{ "method": "process/exited", "params": {
  "processHandle": "pytest-1",
  "exitCode": 0
} }

入力を送信するには、process/writeStdin に deltaBase64、closeStdin、またはその両方を指定します。PTY のサイズ変更には process/resizePty を、実行中のプロセスの終了には process/kill を使用します。

コマンドの実行

command/exec はスレッドを作成せずに、サーバーのサンドボックス内で単一のコマンド(argv 配列)を実行します。

{ "method": "command/exec", "id": 50, "params": {
  "command": ["ls", "-la"],
  "cwd": "/Users/me/project",
  "sandboxPolicy": { "type": "workspaceWrite" },
  "timeoutMs": 10000
} }
{ "id": 50, "result": { "exitCode": 0, "stdout": "...", "stderr": "" } }

サーバープロセスをすでにサンドボックス内で実行しており、Codex 独自のサンドボックス制御を省略したい場合は、sandboxPolicy.type = "externalSandbox" を使用します。外部サンドボックスモードでは networkAccess を restricted(デフォルト)または enabled に設定します。readOnly と workspaceWrite では、前述の任意の access / readOnlyAccess と同じ構造を使用します。

留意事項は次のとおりです。

  • サーバーは空の command 配列を拒否します。
  • sandboxPolicy は turn/start と同じ形式を受け付けます(例:dangerFullAccess、readOnly、workspaceWrite、externalSandbox)。
  • timeoutMs を省略すると、サーバーのデフォルト値が適用されます。
  • PTY を使用するセッションでは tty: true を設定し、後から操作する場合は processId を command/exec/write、command/exec/resize、command/exec/terminate に指定します。
  • streamStdoutStderr: true を設定すると、コマンドの実行中に command/exec/outputDelta 通知を受け取れます。

管理者要件の読み取り(configRequirements/read)

configRequirements/read で、requirements.toml、MDM、またはその両方から読み込まれた実効管理者要件を確認できます。

{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
  "requirements": {
    "allowedApprovalPolicies": ["on-request", "never"],
    "allowedSandboxModes": ["read-only", "workspace-write"],
    "featureRequirements": {
      "unified_exec": false
    }
  }
} }

要件が未設定の場合、result.requirements は null です。result.supportsIndependentSpeedModes が true の場合、fast_mode と ultrafast_mode の要件は個別に適用されます。古いサーバーはこのフィールドを省略し、両方に fast_mode を使用します。対応するキーと値は、requirements.toml のリファレンスを参照してください。

Windows サンドボックスのセットアップ(windowsSandbox/setupStart)

セットアップを促す前に windowsSandbox/readiness を呼び出してください。MXC と設定済みの従来型サンドボックスは、どちらも ready を返すことがあります。従来型サンドボックスが updateRequired を返した場合は、windowsSandbox/setupStart を呼び出して非同期でセットアップを開始します。Windows サンドボックスが無効な場合、またはホストが別の OS を実行している場合、準備状態の確認結果は notConfigured です。

{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }

app-server はバックグラウンドでセットアップを開始し、完了時に通知を送信します。

{
  "method": "windowsSandbox/setupCompleted",
  "params": { "mode": "elevated", "success": true, "error": null }
}

利用できるモードは次のとおりです。

  • elevated:昇格した権限で Windows サンドボックスのセットアップを実行します。
  • unelevated:従来のセットアップおよび事前チェックの手順を実行します。

ファイルシステム

v2 のファイルシステム API は絶対パスを扱います。ファイルやディレクトリの変更後にクライアント側で UI の状態を無効化する必要がある場合は、fs/watch を使用します。

{ "method": "fs/watch", "id": 54, "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
  "path": "/Users/me/project/.git/HEAD"
} }
{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }
{ "method": "fs/changed", "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
  "changedPaths": ["/Users/me/project/.git/HEAD"]
} }
{ "method": "fs/unwatch", "id": 55, "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"
} }
{ "id": 55, "result": {} }

ファイルを監視すると、そのファイルパスの変更が fs/changed で通知されます。置き換えや名前変更による更新も対象です。

イベント

イベント通知は、スレッドとターンのライフサイクル、およびターン内のアイテムについてサーバーが配信するストリームです。スレッドを開始または再開した後は、接続中のトランスポートストリームを継続して読み取り、thread/started、thread/archived、thread/unarchived、thread/closed、thread/status/changed、turn/*、item/*、serverRequest/resolved の通知を受信します。

特定の通知の抑制

クライアントは、initialize.params.capabilities.optOutNotificationMethods にメソッド名を正確に指定することで、接続ごとに特定の通知を抑制できます。

  • 完全一致のみです。item/agentMessage/delta を指定すると、そのメソッドのみが抑制されます。
  • 未知のメソッド名は無視されます。
  • 現行の thread/*、turn/*、item/*、および関連する v2 通知に適用されます。
  • リクエスト、レスポンス、エラーには適用されません。

ファイルのあいまい検索イベント(実験的)

ファイルのあいまい検索セッション API は、クエリごとに次の通知を送信します。

  • fuzzyFileSearch/sessionUpdated:{ sessionId, query, files } に、実行中のクエリの現時点での一致結果が含まれます。
  • fuzzyFileSearch/sessionCompleted:そのクエリのインデックス作成と照合が完了すると { sessionId } を送信します。

警告イベント

  • configWarning:回復可能な設定または初期化の問題を示す { summary, details?, path?, range? }
  • warning:致命的ではない実行時の警告を示す { threadId?, message }

Windows サンドボックスのセットアップイベント

  • windowsSandbox/setupCompleted:{ mode, success, error } を windowsSandbox/setupStart リクエストの完了後に送信します。

ターンイベント

  • turn/started:{ turn } にはターン ID、空の items、status: "inProgress" が含まれます。
  • turn/completed:{ turn } の turn.status は completed、interrupted、failed のいずれかです。失敗時は { error: { message, codexErrorInfo?, additionalDetails? } } が含まれます。
  • turn/diff/updated:{ threadId, turnId, diff } に、そのターン内のすべてのファイル変更をまとめた最新の unified diff が含まれます。
  • turn/plan/updated:{ turnId, explanation?, plan } を、エージェントがプランを共有または変更するたびに送信します。各 plan 項目は { step, status } で、status は pending、inProgress、completed のいずれかです。
  • hook/started と hook/completed:{ threadId, turnId?, run } を、同期ライフサイクルフックの開始時と最終的な実行概要の確定時にそれぞれ送信します。非同期フックでは送信されません。
  • model/safetyBuffering/updated:{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel } を、安全性の確認のためにレスポンスを一時的にバッファリングし始めたときに送信します。
  • model/rerouted:{ threadId, turnId, fromModel, toModel, reason } を、サービスがリクエストを別のモデルに振り分けたときに送信します。
  • model/verification:{ threadId, turnId, verifications } を、サービスが追加のアカウント確認を必要とするときに送信します。
  • thread/tokenUsage/updated:アクティブなスレッドの使用量の更新

turn/diff/updated と turn/plan/updated には、アイテムイベントの配信中であっても、現時点では空の items 配列が含まれます。ターンのアイテムの状態は item/* 通知を基準にしてください。

アイテム

ThreadItem は、ターンのレスポンスと item/* 通知に含まれるタグ付き共用体です。主なアイテム型は次のとおりです。

  • userMessage:{id, content} の content はユーザー入力(text、image、localImage)のリストです。
  • functionCallOutput:{id, name, namespace, output} は turn/start.toolOutput で指定した独立したツール出力を表します。namespace は null の場合があります。
  • agentMessage:{id, text, phase?} には、その時点までに生成されたエージェントの応答が含まれます。phase がある場合は Responses API の通信形式の値(commentary、partial_answer、final_answer)を使用します。partial_answer は確定済みの回答テキストですが、後に追加の出力やツール呼び出しが続くことがあります。
  • plan:{id, text} にはプランモードで提案されたプランの本文が含まれます。最終的な plan は item/completed で受信したものを正としてください。
  • reasoning:{id, summary, content} の summary には配信された推論の要約が、content には生の推論ブロックが含まれます。
  • commandExecution:{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}
  • fileChange:{id, changes, status} は提案された編集を表し、changes は {path, kind, diff} のリストです。
  • mcpToolCall:呼び出しの id、server、tool、status、arguments を記録します。 appContext、mcpAppUi、pluginId、readOnlyHint、result、error、durationMs も含まれます。これらのフィールドの値はいずれも null の場合があります。従来の mcpAppResourceUri フィールドは任意です。 信頼済みの MCP アプリでは、appContext に connectorId が含まれます。他のフィールド(linkId、resourceUri、appName、actionName)は null の場合があります。 ツールの記述子にリソース URI と表示モード(inline または fullscreen)が指定されている場合、mcpAppUi には resourceUri と preferredModelDisplayMode が含まれます。この表示用メタデータなしで保存された呼び出しについては、app-server は null を mcpAppUi の値として返します。
  • dynamicToolCall:クライアントが実行する動的ツールの呼び出しを表す {id, tool, arguments, status, contentItems?, success?, durationMs?}
  • collabToolCall:{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}
  • webSearch:エージェントが発行したウェブ検索リクエストを表す {id, query, action?}
  • imageView:{id, path} を、エージェントが画像ビューアーツールを呼び出したときに送信します。
  • enteredReviewMode:{id, review} を、レビュアーの開始時に送信します。
  • exitedReviewMode:{id, review} を、レビュアーの終了時に送信します。
  • contextCompaction:{id} を、Codex が会話履歴のコンパクションを行うときに送信します。

webSearch.action のアクションの type には、search(query?、queries?)、openPage(url?)、findInPage(url?、pattern?)を指定できます。

App Server では、従来の thread/compacted 通知は非推奨です。代わりに contextCompaction アイテムを使用してください。

すべてのアイテムには、次の 2 つの共通ライフサイクルイベントがあります。

  • item/started:新しい作業単位の開始時に item 全体を送信します。item.id は差分通知で使用される itemId と一致します。
  • item/completed:作業完了時に最終的な item を送信します。この状態を正としてください。

アイテムの差分通知

  • item/agentMessage/delta:配信されたテキストをエージェントのメッセージに追加します。
  • item/plan/delta:提案するプランの本文を逐次配信します。最終的な plan アイテムは、差分を連結した結果と完全には一致しないことがあります。
  • item/reasoning/summaryTextDelta:読みやすい形式の推論の要約を配信します。新しい要約セクションが始まると summaryIndex が増加します。
  • item/reasoning/summaryPartAdded:推論の要約セクションの境界を示します。
  • item/reasoning/textDelta:生の推論テキストを配信します(モデルが対応している場合)。
  • item/commandExecution/outputDelta:コマンドの標準出力と標準エラー出力を配信します。差分は受信順に追加してください。
  • item/fileChange/outputDelta:従来の apply_patch テキスト出力との互換性のための非推奨通知です。現行の app-server はこの通知を送信しません。代わりに fileChange アイテムと turn/diff/updated を使用してください。

エラー

app-server が正常終了の処理中に新しい作業を拒否すると、コードが -32600 で data.reason が serverShuttingDown の JSON-RPC エラーを返します。

error 通知には、error オブジェクトが含まれます。このオブジェクトには message と任意の additionalDetails があり、codexErrorInfo フィールドは null の場合があります。willRetry が true の場合、サーバーは再試行し、ターンは進行中のままです。ターンが失敗すると status: "failed" で終了します。codexErrorInfo の主な値は contextWindowExceeded、usageLimitExceeded、badRequest、unauthorized、sandboxError です。上流へのリクエストが失敗した場合は、{ "httpConnectionFailed": { "httpStatusCode": 503 } } のようなオブジェクトになることもあります。

承認

ユーザーの Codex 設定によっては、コマンドの実行やファイル変更に承認が必要です。app-server がクライアントに JSON-RPC リクエストを送信し、クライアントは判断結果をペイロードとして返します。

  • コマンド実行に対する判断:accept、acceptForSession、decline、cancel、または { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }

  • ファイル変更に対する判断:accept、acceptForSession、decline、cancel

  • リクエストには threadId と turnId が含まれます。これらを使って UI の状態を進行中の会話に関連付けてください。

  • サーバーは判断結果に応じて作業を再開または拒否し、item/completed でアイテムを終了します。

コマンド実行の承認

メッセージは次の順序でやり取りされます。

  1. item/started は、保留中の commandExecution アイテムを示します。これには command、cwd などのフィールドが含まれます。
  2. item/commandExecution/requestApproval には itemId、threadId、turnId と、任意の reason、command、cwd、commandActions、proposedExecpolicyAmendment、networkApprovalContext、availableDecisions が含まれます。initialize.params.capabilities.experimentalApi = true の場合、ペイロードには、コマンドごとに要求するサンドボックスアクセスを記述した実験的な additionalPermissions も含まれることがあります。additionalPermissions 内のファイルシステムパスは、通信時にはすべて絶対パスです。
  3. クライアントは、前述のコマンド実行に対する判断のいずれかを返します。
  4. serverRequest/resolved は、保留中のリクエストへの応答またはリクエストの消去が済んだことを通知します。
  5. item/completed は、最終的な commandExecution アイテムを status: completed | failed | declined とともに返します。

networkApprovalContext がある場合、承認の対象は管理対象のネットワークアクセスです。一般的なシェルコマンドの実行承認とは区別してください。現行の v2 スキーマには接続先の host と protocol が含まれます。クライアントはネットワークアクセス専用の確認画面を表示し、command がユーザーにとって意味のあるシェルコマンドのプレビューになるとは想定しないでください。

Codex は同時に発生したネットワーク承認リクエストを接続先(host、プロトコル、ポート)ごとにまとめます。そのため、app-server からの 1 回の確認で、同じ接続先に対してキューに入っている複数のリクエストを進められることがあります。同じホストでもポートが異なる場合は別々に扱われます。

ファイル変更の承認

メッセージは次の順序でやり取りされます。

  1. item/started は、提案された changes と status: "inProgress" を含む fileChange アイテムを送信します。
  2. item/fileChange/requestApproval には itemId、threadId、turnId、任意の reason と grantRoot が含まれます。
  3. クライアントは、前述のファイル変更に対する判断のいずれかを返します。
  4. serverRequest/resolved は、保留中のリクエストへの応答またはリクエストの消去が済んだことを通知します。
  5. item/completed は、最終的な fileChange アイテムを status: completed | failed | declined とともに返します。

tool/requestUserInput

クライアントが item/tool/requestUserInput に応答すると、app-server は serverRequest/resolved で { threadId, requestId } を送信します。クライアントが応答する前にターンの開始、完了、中断によって保留中のリクエストが消去された場合も、サーバーは同じ通知を送信します。

リクエストパラメータの autoResolutionMs には、ミリ秒単位の整数のタイムアウト値または null が入ります。値がある場合、ユーザーが応答しなければ、ホストクライアントはその時間の経過後にプロンプトを自動的に解決できます。

権限リクエスト

組み込みの request_permissions ツールは item/permissions/requestApproval を送信します。これには threadId、turnId、itemId、environmentId、cwd、任意の reason、要求するネットワーク権限またはファイルシステム権限が含まれます。permissions には許可する権限のみを含めて応答してください。scope を "session" に設定すると、同じセッションの後続ターンでも権限が保持されます。ターン内に限定するには、省略するか "turn" を使用します。要求されていない権限は無視されます。

MCP サーバーからの入力要求

MCP サーバーは mcpServer/elicitation/request でターンに割り込んで入力を求めることができます。リクエストには threadId、任意の turnId、serverName と、次のいずれかの形式のデータが含まれます。

  • mode: "form" または mode: "openai/form" と、message および requestedSchema
  • mode: "url" と、message、url、elicitationId

受け入れる場合は action: "accept" と要求された content を返します。拒否またはキャンセルの場合は action: "decline" または "cancel" と content: null を返します。その後、app-server は serverRequest/resolved を送信します。openai/form 形式を受信するには、initialize.params.capabilities.mcpServerOpenaiFormElicitation を有効にしてください。

動的ツールの呼び出し(実験的)

dynamicTools は thread/start の実験的なフィールドであり、対応する item/tool/call のリクエストとレスポンスのフローも実験的 API です。

動的ツール名と名前空間名は、Responses API の命名制約に従う必要があります。Codex の組み込みツールが使用する予約済みの名前空間名は避けてください。

ターン中に動的ツールが呼び出されると、app-server との間で次のやり取りが行われます。

  1. item/started には item.type = "dynamicToolCall"、status = "inProgress"、tool、arguments が含まれます。
  2. item/tool/call が、サーバーからクライアントへのリクエストとして送信されます。
  3. クライアントは、結果のコンテンツアイテムを含むレスポンスペイロードを返します。
  4. item/completed には item.type = "dynamicToolCall"、最終的な status、および返された contentItems または success の値が含まれます。

MCP ツール呼び出しの承認(アプリ)

アプリ(コネクタ)のツール呼び出しにも承認が必要な場合があります。アプリのツール呼び出しに副作用がある場合、サーバーは tool/requestUserInput を使い、承認、拒否、キャンセルなどの選択肢を示して承認を求めることがあります。破壊的操作を示すアノテーションがある場合は、より低い権限で動作することを示すヒントが併記されていても、必ず承認が求められます。ユーザーが拒否またはキャンセルすると、ツールは実行されず、関連する mcpToolCall アイテムがエラーで終了します。

スキル

スキルを呼び出すには、ユーザーのテキスト入力に $<skill-name> を含めます。skill 入力アイテムも追加することを推奨します。これにより、モデルによる名前解決に頼らず、サーバーがスキルの指示全文を挿入できます。

{
  "method": "turn/start",
  "id": 101,
  "params": {
    "threadId": "thread-1",
    "input": [
      {
        "type": "text",
        "text": "$skill-creator Add a new skill for triaging flaky CI."
      },
      {
        "type": "skill",
        "name": "skill-creator",
        "path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
      }
    ]
  }
}

skill アイテムを省略しても、モデルは $<skill-name> マーカーを解析し、スキルを探そうとします。その分、応答に時間がかかることがあります。

例を示します。

$skill-creator CI で断続的に発生する失敗の原因を切り分けるスキルを新しく追加し、その使い方を手順ごとに説明してください。

skills/list で利用可能なスキルを取得します。必要に応じて cwds で対象を絞り込み、forceReload を指定できます。perCwdExtraUserRoots を含めると、追加の絶対パスを user スコープとして特定の cwd ごとにスキャンできます。app-server は、項目の cwd が cwds に含まれていなければ、その項目を無視します。skills/list は cwd ごとにキャッシュした結果を再利用する場合があります。ディスクから再読み込みするには forceReload: true を設定してください。サーバーは、定義されていれば interface と dependencies を SKILL.json から読み取ります。

{ "method": "skills/list", "id": 25, "params": {
  "cwds": ["/Users/me/project", "/Users/me/other-project"],
  "forceReload": true,
  "perCwdExtraUserRoots": [
    {
      "cwd": "/Users/me/project",
      "extraUserRoots": ["/Users/me/shared-skills"]
    }
  ]
} }
{ "id": 25, "result": {
  "data": [{
    "cwd": "/Users/me/project",
    "skills": [
      {
        "name": "skill-creator",
        "description": "Create or update a Codex skill",
        "enabled": true,
        "interface": {
          "displayName": "Skill Creator",
          "shortDescription": "Create or update a Codex skill"
        },
        "dependencies": {
          "tools": [
            {
              "type": "env_var",
              "value": "GITHUB_TOKEN",
              "description": "GitHub API token"
            },
            {
              "type": "mcp",
              "value": "github",
              "transport": "streamable_http",
              "url": "https://example.com/mcp"
            }
          ]
        }
      }
    ],
    "errors": []
  }]
} }

監視対象のローカルスキルファイルが変更されると、サーバーは skills/changed 通知も送信します。これをキャッシュの無効化を示す通知として扱い、必要に応じて現在のパラメータで skills/list を再実行してください。

パスを指定してスキルを有効または無効にする例です。

{
  "method": "skills/config/write",
  "id": 26,
  "params": {
    "path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
    "enabled": false
  }
}

アプリ(コネクタ)

app/installed で、インストール済みアプリの実行時の状態を記録した最新の確定済みスナップショットを読み取ります。各結果にはアプリの id、runtimeName(または null)、実効 enabled 状態、callable 状態が含まれます。アプリを呼び出せるのは、実効設定で有効になっており、モデルから参照できるツールのうち少なくとも 1 つがアプリとツールの両方のポリシーを満たしている場合に限ります。

{
  "method": "app/installed",
  "id": 49,
  "params": {
    "threadId": "thread-1",
    "forceRefresh": false
  }
}
{
  "id": 49,
  "result": {
    "apps": [
      {
        "id": "demo-app",
        "runtimeName": "Demo App",
        "enabled": true,
        "callable": true
      }
    ]
  }
}

threadId を省略すると、読み込み済みスレッドの設定の代わりにグローバル設定を使用します。forceRefresh: true を設定すると、読み取り前にコネクタの実行時スナップショットを更新します。グローバルまたはワークスペースのポリシーでアクセスをブロックされたアプリでも、検出された場合は enabled と callable が false の状態で表示されることがあります。

app/list で利用可能なアプリを取得します。CLI / TUI ではユーザーが /apps でアプリを選択します。カスタムクライアントでは app/list を直接呼び出します。各項目には isAccessible(ユーザーがアクセス可能)と isEnabled(config.toml で有効)が含まれるため、インストールやアクセスの可否と、ローカルでの有効状態を区別できます。アプリの項目には任意の branding、appMetadata、labels フィールドも含まれることがあります。

{ "method": "app/list", "id": 50, "params": {
  "cursor": null,
  "limit": 50,
  "threadId": "thread-1",
  "forceRefetch": false
} }
{ "id": 50, "result": {
  "data": [
    {
      "id": "demo-app",
      "name": "Demo App",
      "description": "Example connector for documentation.",
      "logoUrl": "https://example.com/demo-app.png",
      "logoUrlDark": null,
      "distributionChannel": null,
      "branding": null,
      "appMetadata": null,
      "labels": null,
      "installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
      "isAccessible": true,
      "isEnabled": true
    }
  ],
  "nextCursor": null
} }

threadId を指定した場合、アプリ機能の有効判定(features.apps)にはそのスレッドの設定スナップショットが使用されます。省略した場合、app-server は最新のグローバル設定を使用します。

app/list は、アクセス可能なアプリとディレクトリ内のアプリの両方を読み込んでから結果を返します。forceRefetch: true を設定すると、アプリのキャッシュを使わず最新のデータを取得します。キャッシュの項目は更新に成功した場合にのみ置き換えられます。

また、サーバーはどちらかの取得元(アクセス可能なアプリまたはディレクトリ内のアプリ)の読み込みが完了するたびに、app/list/updated 通知を送信します。各通知には、両方の取得元を統合した最新のアプリ一覧が含まれます。

{
  "method": "app/list/updated",
  "params": {
    "data": [
      {
        "id": "demo-app",
        "name": "Demo App",
        "description": "Example connector for documentation.",
        "logoUrl": "https://example.com/demo-app.png",
        "logoUrlDark": null,
        "distributionChannel": null,
        "branding": null,
        "appMetadata": null,
        "labels": null,
        "installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
        "isAccessible": true,
        "isEnabled": true
      }
    ]
  }
}

アプリ ID がすでにわかっていて、インストール済みアプリの実行時の状態ではなくメタデータが必要な場合は、app/read を使用します。appIds には最大 100 件を渡せます。ID が重複する場合、サーバーは最初の出現のみを採用し、apps と missingAppIds の両方でその順序を保持します。未知のアプリやアクセスできないアプリは missingAppIds に含まれ、リクエスト全体が失敗することはありません。

{
  "method": "app/read",
  "id": 52,
  "params": {
    "appIds": ["demo-app", "missing-app"],
    "includeTools": true
  }
}
{
  "id": 52,
  "result": {
    "apps": [
      {
        "id": "demo-app",
        "name": "Demo App",
        "description": "Example connector for documentation.",
        "iconUrl": null,
        "iconUrlDark": null,
        "distributionChannel": null,
        "installUrl": null,
        "pluginDisplayNames": [],
        "toolSummaries": [
          {
            "name": "search",
            "title": "Search",
            "description": "Search the app.",
            "isEnabled": true,
            "disabledReason": null,
            "isReadOnly": true
          }
        ]
      }
    ],
    "missingAppIds": ["missing-app"]
  }
}

includeTools: true を設定すると、表示専用の公開ツール概要を取得できます。メタデータのレスポンスにはインストール済みアプリの実行時の状態は含まれず、ツール呼び出しを認可するものでもありません。app/installed で実効 enabled 状態と callable 状態を確認してください。

アプリを呼び出すには、テキスト入力に $<app-slug> を挿入し、mention 入力アイテムに app://<id> パスを指定して追加します(推奨)。

{
  "method": "turn/start",
  "id": 51,
  "params": {
    "threadId": "thread-1",
    "input": [
      {
        "type": "text",
        "text": "$demo-app Pull the latest updates from the team."
      },
      {
        "type": "mention",
        "name": "Demo App",
        "path": "app://demo-app"
      }
    ]
  }
}

アプリ設定の RPC 使用例

config/read、config/value/write、config/batchWrite で config.toml のアプリ設定を確認または更新できます。

実効アプリ設定の構造(_default とツールごとの上書きを含む)を読み取る例です。

{ "method": "config/read", "id": 60, "params": { "includeLayers": false } }
{ "id": 60, "result": {
  "config": {
    "apps": {
      "_default": {
        "enabled": true,
        "destructive_enabled": true,
        "open_world_enabled": true,
        "approvals_reviewer": "user",
        "default_tools_approval_mode": "auto"
      },
      "google_drive": {
        "enabled": true,
        "destructive_enabled": false,
        "approvals_reviewer": "auto_review",
        "default_tools_approval_mode": "prompt",
        "tools": {
          "files/delete": { "enabled": false, "approval_mode": "approve" }
        }
      }
    }
  }
} }

apps._default.approvals_reviewer は、アプリごとの設定で上書きしない限り、すべてのアプリの承認リクエストのレビュアーを指定します。両方を省略すると、アプリはトップレベルの approvals_reviewer の値を継承します。apps._default.default_tools_approval_mode は、アプリごとまたはツールごとの上書きがないツールに適用する承認モードを指定します。管理対象の承認モード要件は、ツールの承認モード設定よりも優先されます。

アプリの設定を 1 件更新する例です。

{
  "method": "config/value/write",
  "id": 61,
  "params": {
    "keyPath": "apps.google_drive.default_tools_approval_mode",
    "value": "prompt",
    "mergeStrategy": "replace"
  }
}

複数のアプリ設定の変更をアトミックに適用する例です。

{
  "method": "config/batchWrite",
  "id": 62,
  "params": {
    "edits": [
      {
        "keyPath": "apps._default.destructive_enabled",
        "value": false,
        "mergeStrategy": "upsert"
      },
      {
        "keyPath": "apps.google_drive.tools.files/delete.approval_mode",
        "value": "approve",
        "mergeStrategy": "upsert"
      }
    ]
  }
}

外部エージェント設定の検出とインポート

externalAgentConfig/detect で移行可能な外部エージェントのデータを検出し、選択した項目を externalAgentConfig/import に渡します。

検出の例です。

{ "method": "externalAgentConfig/detect", "id": 63, "params": {
  "includeHome": true,
  "cwds": ["/Users/me/project"]
} }
{ "id": 63, "result": {
  "items": [
    {
      "itemType": "AGENTS_MD",
      "description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
      "cwd": "/Users/me/project"
    },
    {
      "itemType": "SKILLS",
      "description": "Copy skill folders from /Users/me/.claude/skills to /Users/me/.agents/skills.",
      "cwd": null
    }
  ]
} }

インポートの例です。

{ "method": "externalAgentConfig/import", "id": 64, "params": {
  "migrationItems": [
    {
      "itemType": "AGENTS_MD",
      "description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
      "cwd": "/Users/me/project"
    }
  ],
  "source": "claude-code"
} }
{ "id": 64, "result": { "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868" } }

インポート時に指定できる任意のトップレベルパラメータ source は、選択した移行項目の生成元の製品を示します。

サーバーは項目の種類ごとに処理が完了すると externalAgentConfig/import/progress を送信し、同期およびバックグラウンドのインポートがすべて完了すると externalAgentConfig/import/completed を送信します。これらの通知には、レスポンスと同じ importId と itemTypeResults が含まれ、種類ごとの successes と failures を確認できます。完了通知はレスポンスの直後、またはバックグラウンドで実行するリモートインポートが完了した後に届きます。

{ "method": "externalAgentConfig/import/progress", "params": {
  "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
  "itemTypeResults": [
    {
      "itemType": "AGENTS_MD",
      "successes": [
        { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
      ],
      "failures": []
    }
  ]
} }
{ "method": "externalAgentConfig/import/completed", "params": {
  "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
  "itemTypeResults": [
    {
      "itemType": "AGENTS_MD",
      "successes": [
        { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
      ],
      "failures": []
    }
  ]
} }

完了済みのインポート履歴を読み取る例です。

{ "method": "externalAgentConfig/import/readHistories", "id": 65 }
{ "id": 65, "result": { "data": [
  {
    "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
    "completedAtMs": 1781784000000,
    "successes": [
      { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
    ],
    "failures": []
  }
] } }

対応する itemType の値は AGENTS_MD、CONFIG、SKILLS、PLUGINS、MCP_SERVER_CONFIG、SUBAGENTS、HOOKS、COMMANDS、SESSIONS です。PLUGINS 項目の場合、details.plugins に各 marketplaceName と Codex が移行を試みる pluginNames が含まれます。検出結果には、まだ移行作業が必要な項目のみが含まれます。たとえば、Codex は AGENTS.md がすでに存在し、空でなければ AGENTS の移行をスキップします。また、スキルのインポートで既存のスキルディレクトリが上書きされることはありません。

.claude/settings.json からプラグインを検出する場合、Codex は extraKnownMarketplaces から設定済みのマーケットプレイスの取得元を読み取ります。enabledPlugins に claude-plugins-official のプラグインが含まれていて、そのマーケットプレイスの取得元が未設定の場合、Codex は取得元を anthropics/claude-plugins-official と推定します。

認証エンドポイント

Codex app-server 認証を使って構築したローカルアプリケーションやオープンソースアプリケーションでは、引き続きこの認証を使用できます。ただし、ユーザーが自身の使用状況をより把握しやすく、管理しやすくなるよう、「ChatGPT でサインイン」への移行を推奨します。「ChatGPT でサインイン」の開発者向けドキュメントと実装クックブックを参照してください。商用サービスやホスティング型サービスでの app-server 認証の利用は、これまでも許可されていません。こうした用途に対応するために「ChatGPT でサインイン」を提供しています。皆さんがどのような製品を作るのか楽しみにしています。パートナー向けウェイトリストにご登録ください。

認証とアカウントを扱う JSON-RPC API には、リクエスト/レスポンス型のメソッドと、サーバーからの通知(id なし)があります。認証状態の確認、ログインの開始やキャンセル、ログアウト、ChatGPT のレート制限の確認、クレジットを使い切った場合や使用上限に達した場合のワークスペース所有者への通知に使用できます。

認証モード

Codex は次の認証モードに対応しています。account/updated.authMode は現在のモードを示し、取得できる場合は現在の ChatGPT の planType も通知に含まれます。account/read でもアカウントとプランの詳細を確認できます。

  • API キー(apikey):呼び出し元が type: "apiKey" とともに OpenAI API キーを指定し、Codex が API リクエスト用に保存します。
  • Codex 管理の ChatGPT 認証(chatgpt):Codex が ChatGPT の OAuth フローを管理し、トークンを保存して自動更新します。ブラウザフローでは type: "chatgpt"、デバイスコードフローでは type: "chatgptDeviceCode" を指定して開始します。
  • 外部管理の ChatGPT トークン(chatgptAuthTokens):ユーザーの ChatGPT 認証ライフサイクルをすでに管理しているホストアプリ向けの実験的なモードです。ホストアプリは accessToken、chatgptAccountId、任意の chatgptPlanType を直接指定し、要求されたときにトークンを更新する必要があります。
  • Amazon Bedrock:account/read は Bedrock アカウントを type: "amazonBedrock" として返し、認証情報の取得元が Codex 管理の Bedrock API キー(credentialSource: "codexManaged")か、外部の AWS 認証情報チェーン(credentialSource: "awsManaged")かを示します。account/updated.authMode は、Codex 管理の Bedrock API キーに bedrockApiKey を使用します。

API の概要

  • account/read:現在のアカウント情報を取得します。必要に応じてトークンも更新できます。
  • account/login/start:ログインを開始します(apiKey、chatgpt、chatgptDeviceCode、または実験的な chatgptAuthTokens)。
  • account/login/completed(通知):ログインの試行が終了したときに、成功かエラーかを問わず送信されます。
  • account/login/cancel:保留中の Codex 管理の ChatGPT ログインを loginId で指定してキャンセルします。
  • account/logout:サインアウトし、account/updated を送信します。
  • account/updated(通知):認証モードが変わるたびに送信されます(authMode は apikey、chatgpt、chatgptAuthTokens、agentIdentity、personalAccessToken、bedrockApiKey、null のいずれか)。取得できる場合は planType も含まれます。
  • account/chatgptAuthTokens/refresh(サーバーリクエスト):認可エラーの後、外部管理の ChatGPT トークンの更新を要求します。
  • account/rateLimits/read:ChatGPT のレート制限を取得します。
  • account/rateLimits/updated(通知):ユーザーの ChatGPT のレート制限が変わるたびに送信されます。
  • account/sendAddCreditsNudgeEmail:クレジットを使い切った場合や使用上限に達した場合に、ワークスペース所有者へのメール送信を ChatGPT に依頼します。
  • account/rateLimitResetCredit/consume:呼び出し元が指定した idempotencyKey の値を使用し、獲得済みのレート制限リセットを 1 回使用します。
  • account/usage/read:ChatGPT アカウントのトークン使用状況の概要と日別集計を取得します。
  • account/workspaceMessages/read:有効なワークスペースメッセージを取得します。利用可能な場合は通知の見出しも含まれます。
  • mcpServer/oauthLogin/completed(通知):mcpServer/oauth/login フローの終了後に送信されます。ペイロードには { name, threadId, loginId?, success, error? } が含まれます。古いサーバーは loginId を省略します。アプリ単位またはプラグインの OAuth フローでは、threadId が null の場合があります。
  • mcpServer/startupStatus/updated(通知):設定済みの MCP サーバーの起動状態が変わると送信されます。ペイロードには { threadId, name, status, error, failureReason } が含まれます。アプリ単位の起動では threadId が null になります。起動に失敗した際の failureReason: "reauthenticationRequired" は、保存済みの OAuth 認証情報の有効期限が切れ、更新できなかったことを示します。クライアントはサーバーに再接続する手段をユーザーに提示してください。

1)認証状態の確認

リクエストは次のとおりです。

{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }

レスポンスの例を示します。

{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } }
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } }
{
  "id": 1,
  "result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "amazonBedrock",
      "credentialSource": "codexManaged"
    },
    "requiresOpenaiAuth": false
  }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "amazonBedrock",
      "credentialSource": "awsManaged"
    },
    "requiresOpenaiAuth": false
  }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "chatgpt",
      "email": "user@example.com",
      "planType": "pro"
    },
    "requiresOpenaiAuth": true
  }
}

各フィールドの意味は次のとおりです。

  • refreshToken(ブール値):true を設定すると、Codex 管理の ChatGPT 認証モードでトークンを強制的に更新します。外部トークンモード(chatgptAuthTokens)では、app-server はこのフラグを無視します。
  • email は、ChatGPT アカウントにメールアドレスがない場合は null です。
  • requiresOpenaiAuth は、使用中のプロバイダーに応じた値です。false の場合、Codex は OpenAI の認証情報なしで実行できます。
  • Amazon Bedrock は、Codex 管理の Bedrock API キーを使用する場合に credentialSource: "codexManaged" を返します。外部の AWS 認証情報を使用する設定では credentialSource: "awsManaged" を返します。これは選択された認証情報の取得元を示す値であり、AWS 認証情報チェーンで実際に認証情報を解決できるかどうかを検証するものではありません。

2)API キーでのログイン

  1. 次のリクエストを送信します。

    {
      "method": "account/login/start",
      "id": 2,
      "params": { "type": "apiKey", "apiKey": "sk-..." }
    }
  2. 次のレスポンスが返ります。

    { "id": 2, "result": { "type": "apiKey" } }
  3. 次の通知が届きます。

    {
      "method": "account/login/completed",
      "params": { "loginId": null, "success": true, "error": null }
    }
    {
      "method": "account/updated",
      "params": { "authMode": "apikey", "planType": null }
    }

3)ChatGPT でのログイン(ブラウザフロー)

  1. 次のリクエストで開始します。

    {
      "method": "account/login/start",
      "id": 3,
      "params": {
        "type": "chatgpt",
        "useHostedLoginSuccessPage": true,
        "appBrand": "chatgpt"
      }
    }

    デフォルトでは、ブラウザのコールバックが成功するとローカルのログイン成功ページにリダイレクトされます。組織のセットアップが不要な場合にホスト型の成功ページを使用するには、useHostedLoginSuccessPage: true を設定します。ホスト型の成功ページが有効な場合、appBrand には "codex" または "chatgpt" を指定できます。省略した場合や null の場合は、デフォルトの "codex" が使われます。

    {
      "id": 3,
      "result": {
        "type": "chatgpt",
        "loginId": "<uuid>",
        "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
      }
    }
  2. ブラウザで authUrl を開きます。ローカルのコールバックは app-server が受け付けます。

  3. 次の通知を待ちます。

    {
      "method": "account/login/completed",
      "params": { "loginId": "<uuid>", "success": true, "error": null }
    }
    {
      "method": "account/updated",
      "params": { "authMode": "chatgpt", "planType": "plus" }
    }

3b)ChatGPT でのログイン(デバイスコードフロー)

サインイン手順をクライアント側で管理する場合や、ブラウザのコールバックが安定しない場合は、このフローを使用します。

  1. 次のリクエストで開始します。

    {
      "method": "account/login/start",
      "id": 4,
      "params": { "type": "chatgptDeviceCode" }
    }
    {
      "id": 4,
      "result": {
        "type": "chatgptDeviceCode",
        "loginId": "<uuid>",
        "verificationUrl": "https://auth.openai.com/codex/device",
        "userCode": "ABCD-1234"
      }
    }
  2. verificationUrl と userCode をユーザーに表示します。ユーザー向けの操作画面はフロントエンドで実装します。

  3. 次の通知を待ちます。

    {
      "method": "account/login/completed",
      "params": { "loginId": "<uuid>", "success": true, "error": null }
    }
    {
      "method": "account/updated",
      "params": { "authMode": "chatgpt", "planType": "plus" }
    }

3c)外部管理の ChatGPT トークンでのログイン(chatgptAuthTokens)

この実験的なモードは、ホストアプリケーションがユーザーの ChatGPT 認証ライフサイクルを管理し、トークンを直接提供する場合にのみ使用してください。このログイン方式を使用する前に、クライアントは capabilities.experimentalApi = true を initialize 時に設定する必要があります。

  1. 次のリクエストを送信します。

    {
      "method": "account/login/start",
      "id": 7,
      "params": {
        "type": "chatgptAuthTokens",
        "accessToken": "<jwt>",
        "chatgptAccountId": "org-123",
        "chatgptPlanType": "business"
      }
    }
  2. 次のレスポンスが返ります。

    { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  3. 次の通知が届きます。

    {
      "method": "account/login/completed",
      "params": { "loginId": null, "success": true, "error": null }
    }
    {
      "method": "account/updated",
      "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
    }

サーバーが 401 Unauthorized を受信すると、ホストアプリに更新済みのトークンを要求することがあります。

{
  "method": "account/chatgptAuthTokens/refresh",
  "id": 8,
  "params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }

トークン更新に成功したという応答を受け取ると、サーバーは元のリクエストを再試行します。更新リクエストは約 10 秒でタイムアウトします。

4)ChatGPT ログインのキャンセル

{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }

5)ログアウト

{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }

6)レート制限(ChatGPT)

{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": {
  "rateLimits": {
    "limitId": "codex",
    "limitName": null,
    "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
    "secondary": null,
    "rateLimitReachedType": null
  },
  "rateLimitsByLimitId": {
    "codex": {
      "limitId": "codex",
      "limitName": null,
      "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
      "secondary": null,
      "rateLimitReachedType": null
    },
    "codex_other": {
      "limitId": "codex_other",
      "limitName": "codex_other",
      "primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },
      "secondary": null,
      "rateLimitReachedType": null
    }
  },
  "rateLimitResetCredits": {
    "availableCount": 2,
    "credits": [{
      "id": "RateLimitResetCredit_1",
      "resetType": "codexRateLimits",
      "status": "available",
      "grantedAt": 1781654400,
      "expiresAt": 1784246400,
      "title": "Rate-limit reset",
      "description": "Reset an eligible Codex rate-limit window."
    }]
  }
} }
{ "method": "account/rateLimits/updated", "params": {
  "rateLimits": {
    "limitId": "codex",
    "primary": { "usedPercent": 31, "windowDurationMins": 15, "resetsAt": 1730948100 }
  }
} }

各フィールドの意味は次のとおりです。

  • rateLimits は、後方互換性のための単一バケット形式です。
  • rateLimitsByLimitId がある場合は、計測対象の limit_id(例:codex)をキーとする複数バケット形式です。
  • limitId は計測対象のバケットの識別子です。
  • limitName はバケットの任意の表示名です。
  • usedPercent は、割り当て期間内の現在の使用率です。
  • windowDurationMins は、割り当て期間の長さを分単位で示します。
  • resetsAt は、次回のリセット時刻を示す Unix タイムスタンプ(秒)です。
  • planType は、サーバーがバケットに関連付けられた ChatGPT プランを返す場合に含まれます。
  • credits は、サーバーがワークスペースの残りクレジットの詳細を返す場合に含まれます。
  • rateLimitReachedType は、上限に達した場合にサーバーが判定した制限状態を示します。
  • rateLimitResetCredits には、サービスが提供する場合、獲得済みで利用可能なリセット回数が含まれます。それ以外の場合は null です。
  • rateLimitResetCredits.credits は、回数のみがわかっている場合は null です。空配列は、サービスが詳細を取得した結果、利用可能なクレジットがなかったことを意味します。サービスが詳細の件数を制限することがあるため、利用可能な総数は availableCount を基準にしてください。
  • 各詳細項目には、不透明な id、resetType、status、grantedAt、expiresAt(null の場合あり)、title(null の場合あり)、description(null の場合あり)が含まれます。
  • リセットを使用した後は、account/rateLimits/read で最新の状態を取得してください。

7)トークン使用量(ChatGPT)

account/usage/read で ChatGPT のトークン使用状況の概要フィールドと、提供されていれば日別集計を取得できます。

{ "method": "account/usage/read", "id": 7 }
{ "id": 7, "result": {
  "summary": {
    "lifetimeTokens": 1234567,
    "peakDailyTokens": 45678,
    "longestRunningTurnSec": 540,
    "currentStreakDays": 8,
    "longestStreakDays": 14
  },
  "dailyUsageBuckets": [
    { "startDate": "2026-06-18", "tokens": 12345 }
  ]
} }

各フィールドと認証の要件は次のとおりです。

  • summary 内の値は、サービスがその指標を返していない場合は null になることがあります。
  • dailyUsageBuckets は null の場合があります。値がある場合、各バケットには startDate と tokens が含まれます。
  • このエンドポイントには Codex サービスによる認証が必要です。ChatGPT、外部管理の ChatGPT トークン、エージェント ID、個人アクセストークンによる認証に対応しています。API キーのみの認証や Bedrock 認証では使用できません。

8)獲得済みのレート制限リセット(ChatGPT)

account/rateLimitResetCredit/consume で、獲得済みのリセットを 1 回使用します。

{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }

各フィールドの意味と使用方法は次のとおりです。

  • idempotencyKey は空にできません。論理的に 1 回の引き換え操作ごとに UUID を使用し、その操作を再試行する場合は同じ値を再利用してください。
  • creditId は任意です。指定する場合は、account/rateLimits/read から取得した空でない不透明な ID を使用します。省略すると、サービスが次に利用可能なクレジットを選択します。
  • reset は、クレジットが 1 件使用されたことを示します。
  • alreadyRedeemed は、同じ引き換えがすでに完了していることを示します。冪等な成功として扱い、アカウントのレート制限を再取得してください。
  • nothingToReset は、リセット対象となるレート制限期間がないことを示します。
  • noCredit は、アカウントに利用可能な獲得済みリセットクレジットがないことを示します。
  • リセットを使用した後は、このレスポンスから更新後の制限期間を推定せず、account/rateLimits/read で取得してください。

9)ワークスペース所有者への上限到達の通知

account/sendAddCreditsNudgeEmail を使用すると、クレジットを使い切った場合や使用上限に達した場合に、ワークスペース所有者へのメール送信を ChatGPT に依頼できます。

{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }

ワークスペースのクレジットを使い切った場合は creditType: "credits"、ワークスペースの使用上限に達した場合は creditType: "usage_limit" を使用します。所有者に最近通知したばかりの場合、レスポンスのステータスは cooldown_active になります。

10)ワークスペースメッセージ(ChatGPT)

account/workspaceMessages/read で、現在のワークスペースの有効なメッセージを取得します。利用可能な場合は通知の見出しも含まれます。

{ "method": "account/workspaceMessages/read", "id": 10 }
{ "id": 10, "result": { "featureEnabled": true, "messages": [
  { "messageId": "msg_123", "messageType": "headline", "messageBody": "Workspace maintenance starts at 5pm.", "createdAt": 1781395200, "archivedAt": null }
] } }