繁體中文

Codex 應用伺服器

使用App Server協議將 Codex 嵌入到你的產品中

Codex 應用伺服器是 Codex 用於支援富客戶端的介面(例如,Codex VS Code 擴充套件)。當你想要在自己的產品中進行深度整合時,請使用它:身份驗證、對話歷史記錄、核准和流式智能體事件。App Server實現在 Codex GitHub 儲存庫 (openai/codex/codex-rs/app-server) 中開源。有關開源 Codex 元件的完整列表,請參閱開源 頁面。

連線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 後面的連線。將不記名令牌儲存在環境變數中並 傳遞它的名稱而不是將令牌放在命令列上:

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 端點。僅對 localhost 或 SSH 使用普通 WebSocket 埠轉發連線。

連線遠端 Code Mode host

預設情況下,App Server 會啟動本機 Code Mode host。如需改用遠端 host,請傳入它的安全 WebSocket URL:

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

--code-mode-host 控制 App Server 到 Code Mode host 的出站連線。它不會改變 --listen;後者控制客戶端如何連線 App Server。同一 App Server 程序中的所有 thread 共享所選的 Code Mode host 連線。

連線遠端 host 時請使用 wss://ws:// 僅應用於 localhost 或通過 SSH 轉發的連線。App Server 命令和 WebSocket 傳輸仍是實驗性功能,不支援生產工作負載。

協議

MCP 一樣,codex app-server 支援使用 JSON-RPC 2.0 訊息的雙向通訊(線上路上省略 "jsonrpc":"2.0" 標頭)。

支援的運輸:

  • stdio--listen stdio://,預設):換行符分隔的JSON(JSONL)。
  • websocket--listen ws://IP:PORT,實驗性且不受支援):1 JSON-每個 WebSocket 文本框架的 RPC 訊息。
  • Unix 套接字(--listen unix://--listen unix://PATH):WebSocket 通過 Codex 的預設App Server控制套接字或自定義 Unix 進行連線 套接字路徑,使用標準 HTTP 升級握手。
  • off (--listen off):不要公開本機傳輸。

當你使用 --listen ws://IP:PORT 執行時,相同的偵聽器還提供基本的服務 HTTP 健康探針:

  • 一旦偵聽器接受新連線,GET /readyz 將返回 200 OK
  • 當 request 不包含 Origin 時,GET /healthz 返回 200 OK 標頭。
  • 帶有 Origin 標頭的請求將被拒絕,並顯示 403 Forbidden

WebSocket 傳輸是實驗性的且不受支援。本機聽眾,例如 ws://127.0.0.1:PORT 適用於本機主機和 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

對於簽名的不記名令牌,你還可以設定 --ws-issuer--ws-audience--ws-max-clock-skew-seconds。客戶將憑證呈現為 WebSocket 握手期間的 Authorization: Bearer <token> 和App Server 在 JSON-RPC initialize 之前強制執行身份驗證。

優先選擇 --ws-token-file 而不是在命令列上傳遞原始不記名令牌。使用 --ws-token-sha256 僅當客戶端將原始高熵令牌儲存在 單獨的本機秘密儲存;雜湊只是一個驗證者,客戶端仍然需要 原始令牌。

在WebSocket模式下,App Server使用有界佇列。當request入口滿時, 伺服器拒絕新請求,並顯示 JSON-RPC 錯誤程式碼 -32001 和訊息 "Server overloaded; retry later." 客戶端應以指數方式重試 增加延遲和抖動。

訊息架構

請求包括methodparamsid

{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.6-terra" } }

響應用 resulterror 回顯 id

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

通知省略 id 並僅使用 methodparams

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

你可以從 CLI 生成 TypeScript 架構或 JSON 架構捆綁包。每個輸出都特定於你執行的 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 notification。
  3. 啟動 thread 和 turn,然後繼續從活動傳輸流讀取通知。

範例(Node.js / TypeScript):




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 === 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",
    },
  },
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.6-terra" } });

核心原語

  • thread:使用者和 Codex 代理之間的對話。thread包含匝數。
  • :單使用者request和代理工作如下。turn包含專案並流增量更新。
  • 專案:輸入或輸出的單位(使用者訊息、智能體訊息、命令執行、檔案更改、工具呼叫等)。

使用 thread API 建立、列出或存檔對話。與 turn API 進行對話,並通過 turn 通知傳輸進度。

生命週期概述

  • 每個連線初始化一次:開啟傳輸連線後,立即傳送帶有客戶端後設資料的 initialize request,然後發出 initialized。在此握手之前,伺服器拒絕該連線上的任何 request。
  • 開始(或恢復)thread:呼叫 thread/start 進行新對話,呼叫 thread/resume 繼續現有對話,或呼叫 thread/fork 將歷史記錄分支到新的 thread id。
  • 開始 turn:使用目標 threadId 和使用者輸入呼叫 turn/start。可選欄位覆蓋模型、個性、cwd、沙箱策略等。
  • 操縱活動的 turn:呼叫 turn/steer 將使用者輸入附加到當前正在執行的 turn,而不建立新的 turn。
  • 流事件:在 turn/start 之後,繼續閱讀標準輸出上的通知:thread/archivedthread/unarchiveditem/starteditem/completeditem/agentMessage/delta、工具進度和其他更新。
  • 完成 turn:當模型完成時或 turn/interrupt 取消後,伺服器會發出帶有最終狀態的 turn/completed

初始化

在呼叫該連線上的任何其他方法之前,客戶端必須為每個傳輸連線傳送一個 initialize request,然後使用 initialized notification 進行確認。在初始化之前傳送的請求會收到 Not initialized 錯誤,並且在同一連線上重複 initialize 呼叫會返回 Already initialized

伺服器返回將呈現給上游服務的user agent 字串以及描述執行時目標的 platformFamilyplatformOs 值。設定 clientInfo 以識別你的整合。

initialize.params.capabilities 還支援以下客戶端功能:

  • optOutNotificationMethods - 要抑制的確切 notification 方法名稱 這個連線。匹配精確(無萬用字元或字首);未知的名字 被接受和被忽略。
  • requestAttestation - 選擇伺服器啟動的 attestation/generate request。提供上游證明的桌面主機響應 不透明的 { "token": "..." } 值。
  • mcpServerOpenaiFormElicitation - 允許下游 MCP 伺服器傳送 OpenAI mcpServer/elicitation/request 的擴充套件形式變體。

重要:使用 clientInfo.name 來識別 OpenAI 合規日誌平台的客戶端。如果你正在開發供企業使用的新 Codex 整合,請聯絡 OpenAI 以將其新增到已知客戶列表中。有關更多上下文,請參閱 Codex 日誌參考

範例(來自 Codex VS Code 擴充套件):

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

notification 選擇退出的範例:

{
  "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;發出 thread/started 並自動為你訂閱該 thread 的 turn/item 事件。
  • thread/resume - 通過 id 重新開啟現有的 thread,以便稍後 turn/start 呼叫附加到它。
  • thread/fork - 通過複製已儲存的歷史記錄,將 thread 分叉為新的 thread id。傳入 lastTurnId 可複製到該 turn 為止的歷史記錄並忽略後續 turn;傳入 ephemeral: true 可建立僅駐留記憶體的分叉。它會為新 thread 發出 thread/started;返回的 thread 在可用時包含 forkedFromId
  • thread/read - 通過id讀取儲存的thread而不恢復它;設定 includeTurns 返回完整的 turn 歷史記錄。返回的 thread 物件包括執行時 status
  • thread/list - 翻閱儲存的 thread 日誌;支援基於游標的分頁以及 modelProviderssourceKindsarchivedisPinnedcwduseStateDbOnlysearchTerm 和實驗性 parentThreadIdancestorThreadId 過濾器。返回的 thread 物件包括執行時 status
  • thread/turns/list - 實驗性的;翻閱儲存的 thread 的 turn 歷史記錄而不恢復它。 itemsView 控制 turn 專案是否被省略、彙總或完全載入。
  • thread/items/list - 實驗性的;翻閱持久化的 thread 專案,可選擇限制為一個 turnId。活動的 thread 儲存必須支援 item 分頁。
  • thread/loaded/list - 列出當前載入到記憶體中的 thread id。
  • thread/name/set - 為載入的 thread 或持久部署設定或更新 thread 的面向使用者的名稱;發出 thread/name/updated
  • thread/goal/set - 為 thread 設定目標;發出 thread/goal/updated
  • thread/goal/get - 讀取 thread 的當前目標。
  • thread/goal/clear - 清除thread的目標;發出 thread/goal/cleared
  • thread/metadata/update - 修補由 SQLite 支援的已儲存 thread 後設資料,包括持久化的 gitInfoisPinned
  • thread/archive - 將 thread 的日誌檔案移動到存檔目錄中,並嘗試存檔尚未存檔的衍生後代 thread 日誌;成功時返回 {} 併為每個存檔的 thread 發出 thread/archived
  • thread/delete - 永久刪除持久的活動或存檔的 thread 以及任何生成的後代thread;成功時返回 {} ,併為每個刪除的 thread 發出 thread/deleted
  • thread/unsubscribe - 從 thread turn/item 事件取消訂閱此連線。如果這是最後一個訂閱者,則伺服器在無訂閱者不活動寬限期後解除安裝 thread 併發出 thread/closed
  • thread/unarchive - 將存檔的 thread 部署恢復到活動會話目錄中;返回恢復的 thread 併發出 thread/unarchived
  • thread/status/changed - 當載入的 thread 的執行時 status 更改時發出 notification。
  • thread/compact/start - 觸發 thread 的對話歷史壓縮;立即返回 {},同時通過 turn/*item/* 通知傳輸進度。
  • thread/shellCommand - 針對 thread 執行使用者啟動的 shell 命令。它在沙箱外部執行,具有完全存取權限,並且不繼承 thread 沙箱策略。
  • thread/backgroundTerminals/clean - 停止 thread 的所有正在執行的後臺終端(實驗性;需要 capabilities.experimentalApi)。
  • thread/backgroundTerminals/list - 列出載入的 thread 的正在執行的後臺終端(實驗性;需要 capabilities.experimentalApi)。
  • thread/backgroundTerminals/terminate - 通過App Server processId 終止一個正在執行的後臺終端(實驗性;需要 capabilities.experimentalApi)。
  • thread/rollback - 已棄用;從記憶體上下文中刪除最後 N 輪並保留回滾標記;返回更新後的 thread
  • turn/start - 將使用者輸入新增到 thread 並開始 Codex 生成;使用初始 turn 進行響應並流式傳輸事件。對於collaborationModesettings.developer_instructions: null表示“使用所選模式的內建指令”。
  • thread/inject_items - 將原始響應 API 項附加到載入的 thread 的模型可見歷史記錄中,而無需啟動使用者 turn。
  • turn/steer - 將使用者輸入附加到 thread 的活動中的 turn;返回接受的 turnId
  • turn/interrupt - request 取消飛行中的 turn;成功是{},turn以status: "interrupted"結束。
  • review/start - 為 thread 啟動 Codex 審閱者;發出 enteredReviewModeexitedReviewMode 專案。
  • command/exec - 在伺服器沙箱下執行單個命令,而不啟動 thread/turn。
  • command/exec/write - 將 stdin 位元組寫入正在執行的 command/exec 會話或關閉 stdin
  • command/exec/resize - 調整正在執行的 PTY 支援的 command/exec 會話的大小。
  • command/exec/terminate - 停止正在執行的 command/exec 會話。
  • command/exec/outputDelta(通知) - 從流 command/exec 會話中發出 Base64 編碼的 stdout/stderr 塊。
  • process/spawn - 在 Codex 的沙箱外部啟動顯式程序會話(實驗性;需要 capabilities.experimentalApi)。
  • process/writeStdin - 將標準輸入位元組寫入正在執行的 process/spawn 會話或關閉標準輸入(實驗性)。
  • process/resizePty - 調整正在執行的 PTY 支援的程序會話的大小(實驗性)。
  • process/kill - 終止正在執行的程序會話(實驗性)。
  • process/outputDeltaprocess/exited(通知) - 為流處理輸出和程序退出狀態發出(實驗)。
  • model/list - 列出可用模型(設定 includeHidden: true 以包括帶有 hidden: true 的條目)以及工作量選項、可選 upgradeinputModalities
  • modelProvider/capabilities/read - 讀取模型/提供者組合的提供者能力範圍。
  • experimentalFeature/list - 列出具有生命週期階段後設資料和游標分頁的功能標誌。
  • experimentalFeature/enablement/set - 為支援的功能鍵(例如 appsplugins)修補記憶體執行時設定。
  • environment/info - 實驗性的;連線到設定的執行環境並返回其 shell 和預設工作目錄。
  • permissionProfile/list - 列出 beta 權限設定檔以及有效要求是否允許它們,並帶有游標分頁。
  • collaborationMode/list - 列出協作模式預設(實驗性,無分頁)。
  • skills/list - 列出一個或多個 cwd 值的技能(支援 forceReload 和可選的 perCwdExtraUserRoots)。
  • skills/extraRoots/set - 替換用於發現獨立技能而不保留它們的程序級額外根。
  • skills/changed(通知)- 當觀察本機技能檔案更改時發出。
  • hooks/list - 列出一個或多個 cwd 值的已發現生命週期掛鉤。
  • marketplace/add - 新增遠端外掛市場並將其儲存到使用者的市場設定中。
  • marketplace/remove - 刪除已設定的市場及其已安裝的市場根(如果存在)。
  • marketplace/upgrade - 當你省略市場名稱時,重新整理已設定的 Git 市場或所有已設定的 Git 市場。
  • plugin/list - 正在開發中;列出已發現的外掛市場和外掛狀態,包括安裝/身份驗證策略後設資料、市場載入錯誤、特色外掛 ID 以及本機、Git、包登錄檔或遠端外掛源後設資料。摘要可以包括遠端 version、本機 localVersion、結構化亮/暗圖示和 installPolicySource,對於當前遠端行,可以是 nullWORKSPACE_SETTINGIMPLICIT_CANONICAL_APP。暫時不要從生產客戶端呼叫此方法。
  • plugin/read - 正在開發中;通過市場路徑或遠端市場名稱和外掛名稱讀取一個外掛,包括捆綁的技能、應用、MCP 伺服器名稱以及遠端外掛 shareUrl(當遠端目錄提供遠端外掛時)。暫時不要從生產客戶端呼叫此方法。
  • plugin/install - 正在開發中;從市場路徑或遠端市場名稱安裝外掛。暫時不要從生產客戶端呼叫此方法。
  • plugin/uninstall - 正在開發中;解除安裝已安裝的外掛。暫時不要從生產客戶端呼叫此方法。
  • plugin/skill/read - 通過遠端市場、外掛 ID 和技能名稱按需讀取遠端外掛技能 Markdown。
  • app/installed - 讀取已安裝應用的執行時狀態,包括每個應用最終生效的啟用狀態和可呼叫狀態。
  • app/list - 列出可用的應用(連接器),具有分頁以及可存取性/啟用的後設資料。
  • app/read - 獲取指定 app id 的後設資料和可選的僅供展示的工具摘要。
  • skills/config/write - 按路徑啟用或停用技能。
  • mcpServer/oauth/login - 為已設定的 MCP 伺服器啟動 OAuth 登入;返回授權 URL 並在完成時發出 mcpServer/oauthLogin/completed
  • tool/requestUserInput - 提示使用者 1-3 個簡短問題以進行工具呼叫(實驗);問題可以設定 isOther 為自由格式選項。
  • mcpServer/elicitation/request(伺服器 request) - 要求客戶端進行結構化表單輸入或確認 MCP 伺服器請求的 URL 流。
  • item/permissions/requestApproval(伺服器 request) - 要求客戶端授予內建 request_permissions 工具請求的網路或檔案系統權限的子集。
  • config/mcpServer/reload - 從磁碟重新載入 MCP 伺服器設定併為載入的thread排隊重新整理。
  • mcpServerStatus/list - 列出 MCP 伺服器、工具、資源和身份驗證狀態(游標+限制分頁)。使用 detail: "full" 獲取完整資料,或使用 detail: "toolsAndAuthOnly" 省略資源。
  • mcpServer/resource/read - 通過初始化的 MCP 伺服器讀取單個 MCP 資源。
  • mcpServer/tool/call - 呼叫 thread 設定的 MCP 伺服器上的工具。
  • mcpServer/startupStatus/updated(通知)- 當已設定的 MCP 伺服器的啟動狀態針對已載入的 thread 發生更改時發出。
  • windowsSandbox/setupStart - 啟動 elevatedunelevated 模式的 Windows 沙箱設定;快速返回並稍後發出 windowsSandbox/setupCompleted
  • feedback/upload - 提交回饋報告(分類+可選原因/日誌+對話ID,以及可選extraLogFiles附件)。
  • config/read - 解決設定分層後,在磁碟上獲取有效設定。
  • externalAgentConfig/detect - 檢測可以使用 includeHome 和可選的 cwds 遷移的外部智能體產物;每個檢測到的 item 包括 cwdnull 用於家庭)。
  • externalAgentConfig/import - 通過傳遞顯式 migrationItemscwdnull 用於 home)來應用選定的外部代理遷移專案。支援的 item 類型包括設定、技能、AGENTS.md、外掛、MCP 伺服器設定、子智能體、掛鉤、命令和會話;當工作完成時,非空匯入會發出 externalAgentConfig/import/progressexternalAgentConfig/import/completed 。外掛和會話匯入可以非同步完成。
  • config/value/write - 將單個設定鍵/值寫入磁碟上使用者的 config.toml
  • config/batchWrite - 將設定編輯自動應用到磁碟上使用者的 config.toml
  • configRequirements/read - 從 requirements.toml 和/或 MDM 獲取要求,包括精確託管設定、allowlist、固定的 featureRequirements 以及駐留/網路要求(如果尚未設定任何要求,則為 null)。
  • fs/readFilefs/writeFilefs/createDirectoryfs/getMetadatafs/readDirectoryfs/removefs/copyfs/watchfs/unwatchfs/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 來發現可用模型及其功能。

{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
  "data": [{
    "id": "gpt-5.6-sol",
    "model": "gpt-5.6-sol",
    "displayName": "GPT-5.6-Sol",
    "hidden": false,
    "defaultReasoningEffort": "low",
    "supportedReasoningEfforts": [{
      "reasoningEffort": "low",
      "description": "Fast responses with lighter reasoning"
    }],
    "inputModalities": ["text", "image"],
    "supportsPersonality": true,
    "isDefault": true
  }],
  "nextCursor": null
} }

每個模型條目可以包括:

  • supportedReasoningEfforts - 模型支援的工作量選項。
  • defaultReasoningEffort - 建議客戶的預設工作量。
  • upgrade - 客戶端中遷移提示的可選推薦升級模型 ID。
  • upgradeInfo - 客戶端中遷移提示的可選升級後設資料。
  • hidden - 模型是否在預設選擇器列表中隱藏。
  • inputModalities - 模型支援的輸入類型(例如 textimage)。
  • supportsPersonality - 模型是否支援個性特定指令,例如/personality
  • isDefault - 該模型是否是推薦的預設值。

預設情況下,model/list 僅返回選擇器可見的模型。如果你需要完整列表並希望使用 hidden 在客戶端進行過濾,請設定 includeHidden: true

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 可以是 betaunderDevelopmentstabledeprecatedremoved。對於非 beta 標誌,displayNamedescriptionannouncement 可能是 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 和連線或 協議失敗返回 request 錯誤。

thread

  • thread/read 讀取一個儲存的 thread 而不訂閱它;設定 includeTurns 以包括轉彎。
  • thread/turns/list 是實驗性的,可以通過儲存的 thread 的 turn 歷史記錄進行分頁,而無需 恢復它。使用itemsView選擇是否省略turn項, 總結的,或者說滿載的。
  • thread/items/list 是實驗性的,可對持久的 thread 專案進行分頁,可以選擇限制為一個 turn。
  • thread/list 支援游標分頁以及 modelProviderssourceKindsarchivedisPinnedcwduseStateDbOnlysearchTerm 和實驗性 parentThreadIdancestorThreadId 過濾。
  • thread/loaded/list 返回當前記憶體中的 thread ID。
  • thread/archive 將 thread 的持久 JSONL 日誌移動到存檔目錄中,並嘗試存檔尚未存檔的生成的後代 thread 日誌。
  • thread/delete 永久刪除持久的活動或存檔的 thread 及其生成的後代thread
  • thread/metadata/update 修補已儲存的 thread 後設資料,包括持久化的 gitInfoisPinned
  • thread/unsubscribe 從已載入的 thread 取消訂閱當前連線,並可以在不活動寬限期後觸發 thread/closed
  • thread/unarchive 將存檔的 thread 轉出恢復到活動會話目錄中。
  • thread/compact/start 觸發壓縮並立即返回 {}
  • thread/rollback 已棄用。它從記憶體上下文中刪除最後 N 輪,並在 thread 的持久 JSONL 日誌中記錄回滾標記。
  • thread/inject_items 將原始響應 API 項附加到載入的 thread 的模型可見歷史記錄中,而無需啟動使用者 turn。

啟動或恢復 thread

當你需要新的 Codex 對話時,開始新的 thread。

{ "method": "thread/start", "id": 10, "params": {
  "model": "gpt-5.6-terra",
  "cwd": "/Users/me/project",
  "approvalPolicy": "never",
  "sandbox": "workspaceWrite",
  "personality": "friendly",
  "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 級別指標時,請設定它。

thread/startthread/resumethread/fork 返回 instructionSources,載入指令檔案路徑的陣列。每個路徑都使用 其源環境的本機絕對語法,包括遠端 環境。

實驗客戶端可以將thread/start上的historyMode設定為"legacy" (預設值)或 "paginated"。尚不支援分頁 thread 建立 並返回 JSON-RPC 錯誤 -32601。App Server可以列出並讀取摘要 現有分頁記錄,但完整歷史讀取、turn 分頁和恢復 在支援分頁歷史記錄之前關閉失敗。

選擇 capabilities.experimentalApi 的 Beta 客戶端可以傳遞一個命名的 permissions 中的權限設定檔 ID 而不是舊版 sandbox 欄位。 不要將 permissionssandbox 一起傳送。使用 permissionProfile/list 與專案 cwd 一起發現可用的設定檔 以及託管需求是否允許每一項。

thread.sessionId 標識當前即時會話樹根。根螺紋 使用自己的thread id作為會話id;分叉thread保留會話 ID 他們來自的根源。客戶端應該從中讀取會話 ID thread.sessionId,而不是從 thread id 派生。

要繼續儲存的會話,請使用你之前記錄的 thread.id 呼叫 thread/resume。 response 形狀與 thread/start 相匹配。你還可以傳遞 thread/start 支援的相同設定覆蓋,例如 personality

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

恢復 thread 本身不會更新 thread.updatedAt (或轉出檔案的修改時間)。當你啟動 turn 時,時間戳會更新。

如果你在設定中將啟用的 MCP 伺服器標記為 required,並且該伺服器無法初始化,則 thread/startthread/resume 將失敗,而不是在沒有它的情況下繼續。

thread/start上的dynamicTools是一個實驗場(需要capabilities.experimentalApi = true)。 Codex 將這些動態工具保留在 thread 推出後設資料中,並在你不提供新的動態工具時在 thread/resume 上恢復它們​​。

如果你使用與首次部署中記錄的模型不同的模型繼續,Codex 會發出警告,並在下一個 turn 上應用一次性模型切換指令。

管理 thread 目標

使用thread/goal/setthread/goal/getthread/goal/clear管理 /goal 在 TUI 中呈現相同的持久目標狀態。

{ "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 取代了目標並重置了使用情況統計。提供電流 非最終目標,或省略 objective,更新狀態或代幣預算 同時保留使用歷史記錄。

要從儲存的會話分支,請使用 thread.id 呼叫 thread/fork。這將建立一個新的 thread id 併為其發出 thread/started notification 。經過 lastTurnId 通過turn複製歷史記錄,包含在內,後面省略 輪流:

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

App Server拒絕正在進行的 lastTurnId。如果你在 源 thread 是 mid-turn,分叉記錄一箇中斷標記而不是 保留未標記的部分turn。

傳入 ephemeral: true 可建立僅駐留記憶體的分叉,而不會將它加入已儲存的 thread 列表:

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

分頁 thread 的臨時分叉還需要設定 excludeTurns: true。該欄位是實驗性的,需要 capabilities.experimentalApi = true

設定面向使用者的 thread 標題後,App Server會在 thread/listthread/readthread/resumethread/unarchivethread/rollback 響應上水合 thread.namethread/startthread/fork 可以省略 name(或返回 null),直到稍後設定標題。

讀取儲存的thread(不恢復)

當你想要儲存 thread 資料但不想恢復 thread 或訂閱其事件時,請使用 thread/read

  • includeTurns - 當true時,response包含thread的turn;當 false 或省略時,你僅獲得 thread 摘要。
  • 返回的 thread 物件包括執行時 statusnotLoadedidlesystemErroractiveactiveFlags)。
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }

thread/resume 不同,thread/read 不會將 thread 載入到記憶體中或發出 thread/started

列表 thread 輪次

thread/turns/list 是實驗性的。使用它來分頁儲存的 thread 的 turn 歷史記錄,而無需恢復它。結果預設為最新優先,因此客戶端可以使用 nextCursor 獲取較舊的輪次。 response還包括backwardsCursor;將其作為 cursorsortDirection: "asc" 傳遞,以從較早的頁面中獲取比第一個 item 更新的輪次。

itemsView 控制 response 包含多少 turn-item 資料:

  • notLoaded 省略專案。
  • summary 返回彙總的 item 資料,省略時為預設值。
  • full 返回完整的 item 資料。
{ "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 也是實驗性的。它對持久化專案進行分頁,無需 恢復thread。傳遞 turnId 將結果限制為一個 turn,或忽略它 對 thread 中的專案進行分頁。活動的 thread 儲存必須支援 item 分頁;否則,伺服器將返回不支援的方法錯誤。

列出主題(帶分頁和過濾器)

thread/list 允許你渲染歷史 UI。 createdAt 預設結果為最新優先。過濾器在分頁之前應用。通過以下任意組合:

  • cursor - 來自先前 response 的不透明字串;省略第一頁。
  • limit - 如果未設定,伺服器預設為合理的頁面大小。
  • sortKey - created_at(預設)、updated_atrecency_at
  • sortDirection - desc(預設)或 asc
  • modelProviders - 將結果限制為特定提供商; unset、null 或空陣列包含所有提供程式。
  • sourceKinds - 將結果限制為特定的 thread 源。當省略或 [] 時,伺服器預設僅使用互動式源:clivscode
  • archived - 當 true 時,僅列出已存檔的thread。當 false 或省略時,列出非歸檔thread(預設)。
  • isPinned - 提供此欄位時,只返回持久化置頂狀態與其相符的 thread;省略時同時返回已置頂和未置頂的 thread。
  • cwd - 將結果限制為會話當前工作目錄與此路徑或陣列中的路徑之一完全匹配的thread。從App Server程序工作目錄解析相對路徑。
  • useStateDbOnly - 當 true 時,返回狀態資料庫結果,而不掃描 JSONL thread 日誌來修復後設資料。忽略它或傳遞 false 以獲得預設的掃描和修復行為。
  • searchTerm - 將結果限制為提取的標題包含此區分大小寫的文本片段的thread
  • parentThreadId - 將結果限制為給定父 thread 的直接子thread。該過濾器是實驗性的,需要 capabilities.experimentalApi = true
  • ancestorThreadId - 將結果限制為給定 thread 在任何深度的生成後代。該過濾器是實驗性的,需要 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, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
    { "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
  ],
  "nextCursor": "opaque-token-or-null"
} }

nextCursornull 時,你已到達最後一頁。

更新儲存的 thread 後設資料

使用 thread/metadata/update 修補已儲存的 thread 後設資料,而無需恢復 thread。設定 isPinned 可置頂或取消置頂 thread;更新 gitInfo 可修改持久化的 Git 後設資料。省略的欄位保持不變;顯式 null 會清除已儲存的 Git 後設資料值。

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

跟蹤thread狀態變化

每當載入的 thread 的執行時狀態發生變化時,就會發出 thread/status/changed 。有效負載包括threadId和新的status

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

列出已載入的thread

thread/loaded/list 返回當前載入到記憶體中的 thread ID。

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

取消訂閱已載入的 thread

thread/unsubscribe 刪除當前連線對 thread 的訂閱。 response 狀態是以下之一:

  • unsubscribed 連線已訂閱且現已刪除。
  • notSubscribed 當連線未訂閱該 thread 時。
  • 當 thread 未載入時為 notLoaded

如果這是最後一個訂閱者,伺服器將保持載入 thread,直到 30 分鐘內沒有訂閱者且沒有 thread 活動。當寬限期到期時,應用伺服器解除安裝 thread 併發出 thread/status/changed 轉換到 notLoaded 加上 thread/closed

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

如果thread稍後過期:

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

存檔 thread

使用 thread/archive 將持久的 thread 日誌(作為 JSONL 檔案儲存在磁碟上)移動到存檔會話目錄中。歸檔 thread 還會嘗試歸檔尚未歸檔的生成的後代thread

{ "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" } }

除非你傳遞 archived: true,否則存檔的thread不會出現在以後對 thread/list 的呼叫中。伺服器為其實際歸檔的每個 thread 發出一個 thread/archived notification;如果無法存檔生成的後代,則 request 仍然可以成功,而無需該後代的存檔 notification。

刪除thread

使用 thread/delete 永久刪除持久的活動或存檔的 thread 及其衍生的後代thread。伺服器刪除現有的部署檔案並 返回成功之前關聯後設資料;處理丟失的推出檔案 因為已經刪除了。臨時根thread無法刪除。

{ "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

使用 thread/unarchive 將存檔的 thread 轉出移回活動會話目錄。

{ "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壓縮

使用 thread/compact/start 觸發 thread 的手動歷史壓縮。 request 立即返回 {}

App Server在同一 threadId 上以標準 turn/*item/* 通知的形式發出進度,包括 contextCompaction item 生命週期(item/started 然後 item/completed)。

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

執行 thread shell 命令

thread/shellCommand 用於屬於 thread 的使用者啟動的 shell 命令。 request 立即返回 {},同時進度流通過標準 turn/*item/* 通知。

該API在沙箱外執行,具有完全存取權限,並且不繼承thread沙箱策略。客戶端應該僅針對顯式使用者啟動的命令公開它。

如果 thread 已經有一個活動的 turn,則該命令作為 turn 上的輔助操作執行,並且其格式化輸出被注入到 turn 的訊息流中。如果 thread 空閒,app-server 會為 shell 命令啟動獨立的 turn。

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

清理後臺終端

使用 thread/backgroundTerminals/clean 停止與 thread 關聯的所有正在執行的後臺終端。此方法是實驗性的,需要 capabilities.experimentalApi = true

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

使用thread/backgroundTerminals/list檢查正在執行的後臺終端 對於已載入的 thread。 request 支援標準 cursorlimit 分頁,返回的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/terminateprocessId 來停止一個 後臺終端。該方法是實驗性的,需要 capabilities.experimentalApi = true

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

回滾最近的turn

thread/rollback 已棄用並將被刪除。它刪除了最後一個 numTurns 來自記憶體上下文的條目並在中保留回滾標記 推出日誌。返回的thread包括在之後填充的turns 回滾。

{ "method": "thread/rollback", "id": 30, "params": { "threadId": "thr_b", "numTurns": 1 } }
{ "id": 30, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes", "ephemeral": false } } }

轉彎

input 欄位接受item 列表:

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

你可以覆蓋每個 turn 的設定(模型、工作量、個性、cwd、沙箱策略、摘要)。指定後,這些設定將成為以後開啟同一 thread 的預設設定。 outputSchema僅適用於當前的turn。對於sandboxPolicy.type = "externalSandbox",將networkAccess設定為restrictedenabled;對於 workspaceWritenetworkAccess 仍然是布林值。

對於turn/start.collaborationModesettings.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 為受限讀取會話附加策劃的平台預設安全帶策略。這提高了工具相容性,而無需廣泛允許所有 /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
}

啟動turn

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

將專案注入 thread

使用 thread/inject_items 將預建置的響應 API 專案附加到載入的 thread 的提示歷史記錄中,而無需啟動使用者 turn。這些專案將保留到推出並包含在後續模型請求中。

{ "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

使用 turn/steer 將更多使用者輸入附加到活動的執行中 turn。

  • 包括expectedTurnId;它必須與活動的 turn id 匹配。
  • 如果thread上沒有活動的turn,則request失敗。
  • turn/steer 不會發出新的 turn/started notification。
  • turn/steer 不接受 turn 級別覆蓋(modelcwdsandboxPolicyoutputSchema)。
{ "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" } }

啟動一個turn(呼叫一個技能)

通過在文本輸入中包含 $<skill-name> 並在其旁邊新增 skill 輸入 item 來顯式呼叫技能。

{ "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 } } }

中斷 turn

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

成功後,turn 以 status: "interrupted" 結束。

審查

review/start 為 thread 執行 Codex 審閱器並流式傳輸審閱專案。目標包括:

  • uncommittedChanges
  • baseBranch(與分支的差異)
  • commit(檢視特定提交)
  • custom(自由格式指令)

使用 delivery: "inline"(預設)對現有 thread 執行審查,或使用 delivery: "detached" 分叉新審查 thread。

範例 request/response:

{ "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"
} }

對於獨立審查,請使用 "delivery": "detached"。 response 形狀相同,但 reviewThreadId 將是新評論 thread 的 id(與原來的 threadId 不同)。在流式傳輸評論 turn 之前,伺服器還會為新的 thread 發出 thread/started notification。

Codex 流式傳輸通常的 turn/started notification,後跟 item/startedenteredReviewMode item:

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

當審閱者完成時,伺服器發出 item/starteditem/completed ,其中包含 exitedReviewMode item 和最終審閱文本:

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

使用此 notification 在客戶端中呈現審閱者輸出。

流程執行

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/writeStdindeltaBase64closeStdin 或兩者一起傳送 輸入。使用 process/resizePty 進行 PTY 調整大小事件,使用 process/kill 進行 PTY 調整大小事件 終止正在執行的程序。

命令執行

command/exec 在伺服器沙箱下執行單個命令(argv 陣列),而無需建立 thread。

{ "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。對於 readOnlyworkspaceWrite,請使用與上面所示相同的可選 access / readOnlyAccess 結構。

筆記:

  • 伺服器拒絕空的 command 陣列。
  • sandboxPolicy 接受 turn/start 使用的相同形狀(例如,dangerFullAccessreadOnlyworkspaceWriteexternalSandbox)。
  • 當省略時,timeoutMs 回退到伺服器預設值。
  • 為 PTY 支援的會話設定 tty: true,並在計劃跟進 command/exec/writecommand/exec/resizecommand/exec/terminate 時使用 processId
  • 設定 streamStdoutStderr: true 以在命令執行時接收 command/exec/outputDelta 通知。

閱讀管理要求 (configRequirements/read)

使用 configRequirements/read 檢查從 requirements.toml 和/或 MDM 載入的有效管理要求。

{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
  "requirements": {
    "allowedApprovalPolicies": ["onRequest", "unlessTrusted"],
    "allowedSandboxModes": ["readOnly", "workspaceWrite"],
    "featureRequirements": {
      "personality": true,
      "unified_exec": false
    },
    "network": {
      "enabled": true,
      "allowedDomains": ["api.openai.com"],
      "allowUnixSockets": ["/tmp/example.sock"],
      "dangerouslyAllowAllUnixSockets": false
    }
  }
} }

不設定要求時,result.requirementsnull。有關支援的鍵和值的詳細資訊,請參閱 requirements.toml 上的文件。

Windows 沙箱設定 (windowsSandbox/setupStart)

自定義 Windows 客戶端可以非同步觸發沙箱設定,而不是阻止啟動檢查。

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

App Server在後臺啟動設定,然後發出完成 notification:

{
  "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 生命週期、turn 生命週期及其中的專案的流。啟動或恢復 thread 後,繼續讀取 thread/startedthread/archivedthread/unarchivedthread/closedthread/status/changedturn/*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 - windowsSandbox/setupStart request 完成後發出 { mode, success, error }

轉事件

  • turn/started - { turn } 具有 turn id、空 itemsstatus: "inProgress"
  • turn/completed - { turn },其中 turn.statuscompletedinterruptedfailed;故障攜帶{ error: { message, codexErrorInfo?, additionalDetails? } }
  • turn/diff/updated - { threadId, turnId, diff } 具有 turn 中每個檔案更改的最新聚合統一差異。
  • turn/plan/updated - 每當代理共享或更改其計劃時,{ turnId, explanation?, plan };每個 plan 條目都是 { step, status },其中 status 位於 pendinginProgresscompleted 中。
  • hook/startedhook/completed - 當生命週期掛鉤啟動且其最終執行摘要可用時,{ threadId, turnId?, run }
  • model/safetyBuffering/updated - { threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel },當 response 進入瞬態安全緩衝時。
  • model/rerouted - { threadId, turnId, fromModel, toModel, reason },當服務將 request 路由到另一個模型時。
  • model/verification - 當服務需要額外帳戶驗證時為 { threadId, turnId, verifications }
  • thread/tokenUsage/updated - 活動 thread 的使用更新。

即使 item 事件流式傳輸,turn/diff/updatedturn/plan/updated 目前也包含空的 items 陣列。使用 item/* 通知作為 turn 專案的事實來源。

專案

ThreadItem 是 turn 響應和 item/* 通知中攜帶的標記聯合。常見的item類型包括:

  • userMessage - {id, content},其中 content 是使用者輸入的列表(textimagelocalImage)。
  • agentMessage - {id, text, phase?} 包含累積的代理回覆。如果存在,phase 使用響應 API 線值(commentaryfinal_answer)。
  • plan - {id, text} 包含計劃模式下建議的計劃文本。將 item/completed 中的最終 plan item 視為權威。
  • 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?, pluginId?, result?, error?}。對於受信任的 MCP 應用,appContext 可以包括 connectorIdlinkIdresourceUriappNametemplateId 和穩定連接器 actionName。較舊的持久專案可以忽略較新的後設資料。使用 appContext.resourceUri 而不是已棄用的頂級 mcpAppResourceUri
  • dynamicToolCall - {id, tool, arguments, status, contentItems?, success?, durationMs?} 用於客戶端執行的動態工具呼叫。
  • collabToolCall - {id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}
  • webSearch - {id, query, action?} 用於代理發出的 Web 搜尋請求。
  • imageView - 當代理呼叫影像檢視器工具時發出 {id, path}
  • enteredReviewMode - 當審閱者開始時傳送 {id, review}
  • exitedReviewMode - 當審閱者完成時發出 {id, review}
  • contextCompaction - Codex 壓縮對話歷史記錄時發出 {id}

對於 webSearch.action,動作 type 可以是 searchquery?queries?)、openPageurl?)或 findInPageurl?pattern?)。

應用伺服器棄用舊版 thread/compacted notification;請改用 contextCompaction item。

所有專案都會發出兩個共享生命週期事件:

  • item/started - 當新的工作單元開始時發出完整的 itemitem.id 與 delta 使用的 itemId 匹配。
  • item/completed - 工作完成後傳送最終的 item;將此視為權威狀態。

專案增量

  • item/agentMessage/delta - 附加智能體訊息的流文本。
  • item/plan/delta - 流提議的計劃文本。最終的 plan item 可能不完全等於串聯的增量。
  • item/reasoning/summaryTextDelta - 流可讀的推理摘要;當新的摘要部分開啟時,summaryIndex 會遞增。
  • item/reasoning/summaryPartAdded - 標記推理摘要部分之間的邊界。
  • item/reasoning/textDelta - 流原始推理文本(當模型支援時)。
  • item/commandExecution/outputDelta - 流式傳輸命令的 stdout/stderr;按順序附加增量。
  • item/fileChange/outputDelta - 已棄用舊版 apply_patch 文本輸出的相容性 notification。當前的App Server版本不再發出它;使用 fileChange 物品和 turn/diff/updated 代替。

錯誤

如果 turn 失敗,伺服器會使用 { error: { message, codexErrorInfo?, additionalDetails? } } 發出 error 事件,然後使用 status: "failed" 完成 turn。當上遊 HTTP 狀態可用時,它會出現在 codexErrorInfo.httpStatusCode 中。

常見的 codexErrorInfo 值包括:

  • ContextWindowExceeded
  • UsageLimitExceeded
  • HttpConnectionFailed(4xx/5xx 上游錯誤)
  • ResponseStreamConnectionFailed
  • ResponseStreamDisconnected
  • ResponseTooManyFailedAttempts
  • BadRequestUnauthorizedSandboxErrorInternalServerErrorOther

當上遊 HTTP 狀態可用時,伺服器在相關 codexErrorInfo 變體上的 httpStatusCode 中轉發它。

核准

根據使用者的 Codex 設定,命令執行和檔案更改可能需要核准。App Server向客戶端傳送伺服器發起的 JSON-RPC request,客戶端以決策負載進行響應。

  • 命令執行決策:acceptacceptForSessiondeclinecancel{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }

  • 檔案更改決策:acceptacceptForSessiondeclinecancel

  • 請求包括 threadIdturnId - 使用它們將 UI 狀態範圍限定為活動對話。

  • 伺服器恢復或拒絕工作並以 item/completed 結束 item。

命令執行核准

訊息順序:

  1. item/started 顯示待處理的 commandExecution item 以及 commandcwd 和其他欄位。
  2. item/commandExecution/requestApproval 包括 itemIdthreadIdturnId、可選 reason、可選 command、可選 cwd、可選 commandActions、可選 proposedExecpolicyAmendment、可選 networkApprovalContext 和可選availableDecisions。當 initialize.params.capabilities.experimentalApi = true 時,有效負載還可以包括描述請求的每命令沙箱存取的實驗性 additionalPermissionsadditionalPermissions 內的任何檔案系統路徑都是絕對路徑。
  3. 客戶端以上述命令執行核准決策之一進行響應。
  4. serverRequest/resolved 確認待處理的 request 已被應答或清除。
  5. item/completed 返回最終的 commandExecution item 和 status: completed | failed | declined

networkApprovalContext 存在時,提示是用於託管網路存取(不是一般的 shell 命令核准)。當前v2 schema暴露了目標hostprotocol;客戶端應該呈現特定於網路的提示符,而不是依賴 command 作為對使用者有意義的 shell 命令預覽。

Codex 按目的地(host、協議和埠)對併發網路核准提示進行分組。因此,App Server可能會傳送一個提示,以解除對同一目的地的多個排隊請求的阻止,而同一主機上的不同埠將被單獨處理。

檔案變更審批

訊息順序:

  1. item/started 發出 fileChange item 以及建議的 changesstatus: "inProgress"
  2. item/fileChange/requestApproval 包括 itemIdthreadIdturnId、可選的 reason 和可選的 grantRoot
  3. 客戶以上述檔案變更核准決定之一進行響應。
  4. serverRequest/resolved 確認待處理的 request 已被應答或清除。
  5. item/completed 返回最終的 fileChange item 和 status: completed | failed | declined

tool/requestUserInput

當客戶端響應 item/tool/requestUserInput 時,App Server會發出 serverRequest/resolved{ threadId, requestId }。如果在客戶端應答之前通過 turn 啟動、turn 完成或 turn 中斷清除了掛起的 request,則伺服器會為該清除發出相同的 notification。

請求參數包括 autoResolutionMs 作為整數毫秒超時或 null。如果存在,主機客戶端可以在之後自動解決提示 如果使用者沒有應答,則間隔。

權限請求

內建request_permissions工具傳送 item/permissions/requestApprovalthreadIdturnIditemIdenvironmentIdcwd、可選的 reason 以及請求的網路或檔案系統 權限。使用僅包含授予的子集的 permissions 進行響應。 將 scope 設定為 "session" 以在同一輪中保留後續輪次的授權 會議;省略它或使用 "turn" 進行 turn 範圍的授權。權限 未請求的將被忽略。

MCP 伺服器引出請求

MCP 伺服器可以使用 mcpServer/elicitation/request 中斷 turn。這 request 包括 threadId、可選的 turnIdserverName 和以下之一 這些 request 形狀:

  • mode: "form"mode: "openai/form",其中 messagerequestedSchema
  • mode: "url"messageurlelicitationId

響應 action: "accept" 和請求的 content,或者 action: "decline""cancel"content: null。然後App Server發出 serverRequest/resolved。要接收 openai/form 變體,請選擇加入 initialize.params.capabilities.mcpServerOpenaiFormElicitation

動態工具呼叫(實驗性)

thread/start 上的 dynamicTools 和相應的 item/tool/call request 或 response 流是實驗性 API。

動態工具名稱和名稱空間名稱必須遵循 Responses API 命名 限制。避免內建 Codex 工具使用保留的名稱空間名稱。

當在 turn 期間呼叫動態工具時,App Server會發出:

  1. item/starteditem.type = "dynamicToolCall"status = "inProgress",加上 toolarguments
  2. item/tool/call作為伺服器,request作為客戶端。
  3. 帶有返回內容項的客戶端 response 有效負載。
  4. item/completeditem.type = "dynamicToolCall"、最終的 status 以及任何返回的 contentItemssuccess 值。

MCP 工具呼叫核准(應用)

應用(連接器)工具呼叫也可能需要核准。當應用工具呼叫有副作用時,伺服器可能會使用 tool/requestUserInput 和諸如接受拒絕取消等選項來引發核准。即使該工具還公佈了權限較低的提示,破壞性工具註釋也始終會觸發核准。如果使用者拒絕或取消,相關的 mcpToolCall item 將完成並出現錯誤,而不是執行該工具。

技能

通過在使用者文本輸入中包含 $<skill-name> 來呼叫技能。新增 skill 輸入 item(推薦),以便伺服器注入完整的技能指令,而不是依賴模型來解析名稱。

{
  "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 item,模型仍會解析 $<skill-name> 標記並嘗試定位技能,這可能會增加延遲。

例子:

$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage.

使用 skills/list 獲取可用技能(可以選擇由 cwdsforceReload 限定範圍)。你還可以包含 perCwdExtraUserRoots 以掃描額外的絕對路徑作為特定 cwd 值的 user 範圍。App Server會忽略 cwds 中不存在 cwd 的條目。 skills/list 可以重用每個 cwd 的快取結果;設定 forceReload: true 從磁碟重新整理。當存在時,伺服器從 SKILL.json 讀取 interfacedependencies

{ "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 讀取最近一次提交的已安裝應用執行時快照。每項結果都包含應用 idruntimeName(或 null)、最終生效的 enabled 狀態和 callable 狀態。只有當最終設定啟用了應用,且至少有一個模型可見工具符合應用與工具策略時,應用才可呼叫。

{
  "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 可使用全域設定,而不是已載入 thread 的設定。設定 forceRefresh: true 可在讀取前重新整理連接器執行時快照。當全域或工作區策略阻止應用存取時,已觀測到的應用仍可能出現,但 enabledcallable 都會設為 false

使用 app/list 獲取可用的應用。在CLI/TUI中,/apps是面向使用者的選擇器;在自定義客戶端中,直接呼叫app/list。每個條目都包含 isAccessible(使用者可用)和 isEnabled(在 config.toml 中啟用),因此客戶端可以區分安裝/存取與本機啟用狀態。應用條目還可以包括可選的 brandingappMetadatalabels 欄位。

{ "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) 將使用該 thread 的設定快照。省略時,App Server使用最新的全域設定。

app/list 在可存取應用和目錄應用載入後返回。設定 forceRefetch: true 以繞過應用快取並獲取新資料。僅當重新整理成功時才會替換快取條目。

每當源(可存取的應用或目錄應用)完成載入時,伺服器還會發出 app/list/updated 通知。每個 notification 都包含最新的合併應用列表。

{
  "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
      }
    ]
  }
}

當你已經知道 app id 並需要應用後設資料而非已安裝的執行時狀態時,請使用 app/read。最多可傳入 100 個 appIds。伺服器只保留每個重複 id 的第一次出現,並在 appsmissingAppIds 中保持該順序。未知或不可存取的應用會放入 missingAppIds,不會使整個 request 失敗。

{
  "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 可請求僅供展示的公開工具摘要。後設資料 response 不包含已安裝應用的執行時狀態,也不會授權工具呼叫;請使用 app/installed 檢查最終生效的 enabledcallable 狀態。

通過在文本輸入中插入 $<app-slug> 並新增帶有 app://<id> 路徑的 mention 輸入 item 來呼叫應用(推薦)。

{
  "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/readconfig/value/writeconfig/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_reviewerapps._default.default_tools_approval_mode 會為沒有單應用或單工具覆蓋項的工具設定後備審批模式。託管的審批模式要求優先於工具的審批模式設定。

更新單個應用設定:

{
  "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 匯入參數標記的產品 產生選定的遷移專案。

當 item 類型完成時,伺服器發出 externalAgentConfig/import/progress, 和externalAgentConfig/import/completed全部同步和後臺後 進口完成。這些通知包含相同的 importId response 和 itemTypeResults 以及每個類型的 successesfailures。 完成可能會在 response 之後或後臺遠端之後立即到達 匯入完成。

{ "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_MDCONFIGSKILLSPLUGINSMCP_SERVER_CONFIGSUBAGENTSHOOKSCOMMANDSSESSIONS。為了 PLUGINS 項,details.plugins 列出每個 marketplaceNamepluginNames Codex 可以嘗試遷移。檢測僅返回仍然存在的專案 有工作要做。例如,當 AGENTS.md 時,Codex 會跳過 AGENTS 遷移 已存在且非空,並且技能匯入不會覆蓋現有的 技能目錄。

當檢測到來自.claude/settings.json的外掛時,Codex讀取設定 市場來源來自 extraKnownMarketplaces。如果 enabledPlugins 包含 來自 claude-plugins-official 的外掛,但缺少市場源, Codex 推斷 anthropics/claude-plugins-official 為源。

身份驗證端點

JSON-RPC 身份驗證/帳戶表面公開 request/response 方法以及伺服器啟動的通知(無 id)。使用這些來確定身份驗證狀態、啟動或取消登入、登出、檢查 ChatGPT 速率限制,並通知工作區所有者有關耗盡的積分或使用限制。

認證方式

Codex支援這些認證方式。 account/updated.authMode 顯示活動模式,並包括當前的 ChatGPT planType(如果可用)。 account/read 還報告帳戶和計劃詳細資訊。

  • API key (apikey) - 呼叫者提供 OpenAI API key 和 type: "apiKey",並且 Codex 儲存它以用於 API 請求。
  • ChatGPT 託管 (chatgpt) - Codex 擁有 ChatGPT OAuth 流,保留令牌並自動重新整理它們。從瀏覽器流程的 type: "chatgpt" 開始,或從裝置程式碼流程的 type: "chatgptDeviceCode" 開始。
  • ChatGPT 外部令牌 (chatgptAuthTokens) - 實驗性的,適用於已經擁有使用者 ChatGPT 身份驗證生命週期的主機應用。主機應用直接提供 accessTokenchatgptAccountId 和可選的 chatgptPlanType,並且必須在詢問時重新整理令牌。
  • Amazon Bedrock - account/read 將 Bedrock 賬戶報告為 type: "amazonBedrock",並指示憑證是否來自 Codex 管理的 Bedrock API key (credentialSource: "codexManaged") 還是外部 AWS 憑證鏈 (credentialSource: "awsManaged")。 account/updated.authMode 使用 bedrockApiKey 作為 Codex 管理的 Bedrock API 金鑰。

API概覽

  • account/read - 獲取當前帳戶資訊;可選地重新整理令牌。
  • account/login/start - 開始登入(apiKeychatgptchatgptDeviceCode 或實驗性 chatgptAuthTokens)。
  • account/login/completed(通知)- 登入嘗試完成(成功或錯誤)時發出。
  • account/login/cancel - 通過 loginId 取消掛起的託管 ChatGPT 登入。
  • account/logout - 登出;觸發 account/updated
  • account/updated(通知)- 每當身份驗證模式更改時發出(authModeapikeychatgptchatgptAuthTokensagentIdentitypersonalAccessTokenbedrockApiKeynull),並包括 planType(如果可用)。
  • account/chatgptAuthTokens/refresh(伺服器 request) - 授權錯誤後 request 新鮮的外部管理的 ChatGPT 令牌。
  • account/rateLimits/read - 獲取 ChatGPT 速率限制。
  • account/rateLimits/updated(通知)- 每當使用者的 ChatGPT 速率限制發生變化時發出。
  • account/sendAddCreditsNudgeEmail - 要求 ChatGPT 通過電子郵件向工作區所有者傳送有關積分耗盡或達到使用限制的資訊。
  • account/rateLimitResetCredit/consume - 使用呼叫者提供的 idempotencyKey 值消耗一個已獲得的速率限制重置。
  • account/usage/read - 獲取 ChatGPT 賬戶代幣活動摘要和每日儲存桶。
  • account/workspaceMessages/read - 獲取活動工作區訊息,包括 notification 標題(如果可用)。
  • mcpServer/oauthLogin/completed(通知)- mcpServer/oauth/login 流程完成後發出;有效負載包括{ name, threadId, success, error? }。對於應用範圍或外掛 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 以在託管 ChatGPT 模式下強制重新整理令牌。在外部令牌模式(chatgptAuthTokens)下,App Server忽略此標誌。
  • 當 ChatGPT 帳戶沒有電子郵件地址時,emailnull
  • requiresOpenaiAuth 反映活躍提供者;當 false 時,Codex 可以在沒有 OpenAI 憑據的情況下執行。
  • Amazon Bedrock 在使用時報告 credentialSource: "codexManaged" 基岩 API key 由 Codex 管理。報告 credentialSource: "awsManaged" 用於外部 AWS 憑證路徑。這標識了所選的憑證 來源;它不驗證 AWS 憑證鏈是否可以解析 證書。

2)使用API key登入

  1. 傳送:
   {
     "method": "account/login/start",
     "id": 2,
     "params": { "type": "apiKey", "apiKey": "sk-..." }
   }
  1. 預計:
   { "id": 2, "result": { "type": "apiKey" } }
  1. 通知:
   {
     "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"
     }
   }
  1. 在瀏覽器中開啟authUrl;App Server託管本機回撥。
  2. 等待通知:
   {
     "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"
     }
   }
  1. 向用戶顯示verificationUrluserCode;前端擁有使用者體驗。
  2. 等待通知:
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3c) 使用外部管理的 ChatGPT 代幣登入 (chatgptAuthTokens)

僅當主機應用擁有使用者的 ChatGPT 身份驗證生命週期並直接提供令牌時,才使用此實驗模式。在使用此登入類型之前,客戶端必須在 initialize 期間設定 capabilities.experimentalApi = true

  1. 傳送:
   {
     "method": "account/login/start",
     "id": 7,
     "params": {
       "type": "chatgptAuthTokens",
       "accessToken": "<jwt>",
       "chatgptAccountId": "org-123",
       "chatgptPlanType": "business"
     }
   }
  1. 預計:
   { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  1. 通知:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
   }

當伺服器收到 401 Unauthorized 時,它可能會從主機應用重新整理 request 令牌:

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

伺服器在成功重新整理 response 後重試原始 request。請求大約 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 時間戳(秒)。
  • 當伺服器返回與儲存桶關聯的 ChatGPT 計劃時,會包含 planType
  • 當伺服器返回剩餘工作區信用詳細資訊時,將包含 credits
  • rateLimitReachedType 標識達到伺服器分類的限制狀態。
  • rateLimitResetCredits 包含服務提供時可用的贏得重置計數;否則為null
  • 當僅知道計數時,rateLimitResetCredits.creditsnull。空陣列意味著服務獲取了詳細資訊並且沒有返回可用的積分。該服務可以限制詳細資訊行,因此 availableCount 具有權威性。
  • 每個詳細資訊行包括不透明的 idresetTypestatusgrantedAtexpiresAt(可以是 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;當存在時,每個桶包括 startDatetokens
  • 端點需要 Codex 服務支援的身份驗證。 ChatGPT, 外部 ChatGPT 令牌、智能體身份和個人存取令牌身份驗證工作; 僅 API 金鑰,而 Bedrock 身份驗證則不然。

8) 賺取速率限制重置(ChatGPT)

使用 account/rateLimitResetCredit/consume 消耗一次獲得的重置。

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

現場筆記:

  • idempotencyKey 必須非空。對每個邏輯兌換嘗試使用 UUID,並在重試該嘗試時重複使用相同的值。
  • creditId 是可選的。當提供時,它必須是來自 account/rateLimits/read 的非空不透明 ID。省略時,服務會選擇下一個可用積分。
  • reset 表示積分已消耗。
  • alreadyRedeemed 表示之前完成的相同兌換。將其視為冪等成功並重新整理帳戶限制。
  • nothingToReset 表示沒有符合條件的速率限制視窗可以重置。
  • noCredit 表示該帳戶沒有可用的重置積分。
  • 使用重置後獲取 account/rateLimits/read,而不是從此 response 推斷更新的視窗。

9) 通知工作區所有者有關限制

使用 account/sendAddCreditsNudgeEmail 要求 ChatGPT 在積分耗盡或達到使用限制時向工作區所有者傳送電子郵件。

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

當工作區積分耗盡時使用 creditType: "credits",或者當達到工作區使用限制時使用 creditType: "usage_limit"。如果最近已通知所有者,則 response 狀態為 cooldown_active

10)工作區訊息(ChatGPT)

使用 account/workspaceMessages/read 獲取當前的活動訊息 工作區,包括 notification 標題(如果有)。

{ "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 }
] } }