Deutsch

Codex App Server

Codex App Server

Codex app-server ist die Schnittstelle, über die Codex funktionsreiche Clients unterstützt (beispielsweise die Codex-Erweiterung für VS Code). Verwenden Sie ihn, wenn Sie eine tiefgreifende Integration in Ihr eigenes Produkt benötigen: Authentifizierung, Gesprächsverlauf, Genehmigungen und gestreamte Agentenereignisse. Die Implementierung von app-server ist im Codex-GitHub-Repository als Open Source verfügbar (openai/codex/codex-rs/app-server). Eine vollständige Liste der Open-Source-Komponenten von Codex finden Sie auf der Seite Open Source.

Terminaloberfläche der CLI verbinden

Im Remote-Modus der Terminaloberfläche können Sie app-server auf einem Rechner ausführen und die Terminaloberfläche der Codex CLI von einem anderen aus verbinden. Starten Sie einen WebSocket-Listener:

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

Verbinden Sie anschließend die Terminaloberfläche:

codex --remote ws://127.0.0.1:4500

Konfigurieren Sie für eine nicht lokale Verbindung die WebSocket-Authentifizierung und sichern Sie die Verbindung mit TLS ab. Speichern Sie das Bearer-Token in einer Umgebungsvariable und übergeben Sie deren Namen, anstatt das Token in der Befehlszeile anzugeben:

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

Die Option --remote akzeptiert die Endpunkte ws://, wss://, unix:// und unix://PATH. Verwenden Sie unverschlüsselte WebSockets nur für localhost oder eine per SSH portweitergeleitete Verbindung.

Remote-Host für Code Mode verbinden

Standardmäßig startet app-server einen lokalen Host für Code Mode. Um stattdessen einen Remote-Host zu verwenden, übergeben Sie dessen sichere WebSocket-URL:

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

--code-mode-host steuert die ausgehende Verbindung von app-server zu seinem Host für Code Mode. Dies ändert --listen nicht; diese Einstellung steuert, wie Clients eine Verbindung zu app-server herstellen. Alle Threads im selben app-server-Prozess verwenden gemeinsam die ausgewählte Verbindung zum Host für Code Mode.

Verwenden Sie wss:// für einen Remote-Host. Verwenden Sie ws:// nur für localhost oder eine per SSH weitergeleitete Verbindung. Der app-server-Befehl und der WebSocket-Transport sind experimentell und werden für Produktionsworkloads nicht unterstützt.

Protokoll

Wie MCP unterstützt codex app-server bidirektionale Kommunikation über JSON-RPC-2.0-Nachrichten (wobei der "jsonrpc":"2.0"-Header bei der Übertragung weggelassen wird).

Unterstützte Transporte:

  • stdio (--listen stdio://, Standard): durch Zeilenumbrüche getrenntes JSON (JSONL).
  • websocket (--listen ws://IP:PORT, experimentell und nicht unterstützt): eine JSON-RPC-Nachricht pro WebSocket-Textframe.
  • Unix-Socket (--listen unix:// oder --listen unix://PATH): WebSocket- Verbindungen über den standardmäßigen app-server-Steuerungssocket von Codex oder einen benutzerdefinierten Unix- Socket-Pfad unter Verwendung des standardmäßigen HTTP-Upgrade-Handshakes.
  • off (--listen off): keinen lokalen Transport bereitstellen.

Wenn Sie app-server mit --listen ws://IP:PORT ausführen, stellt derselbe Listener auch grundlegende HTTP-Integritätsprüfungen bereit:

  • GET /readyz gibt 200 OK zurück, sobald der Listener neue Verbindungen akzeptiert.
  • GET /healthz gibt 200 OK zurück, wenn die Anfrage keinen Origin- Header enthält.
  • Anfragen mit einem Origin-Header werden mit 403 Forbidden abgelehnt.

Der WebSocket-Transport ist experimentell und wird nicht unterstützt. Lokale Listener wie ws://127.0.0.1:PORT eignen sich für localhost und Workflows mit SSH-Portweiterleitung. WebSocket-Listener außerhalb der Loopback-Schnittstelle erlauben während der Einführung derzeit standardmäßig nicht authentifizierte Verbindungen. Konfigurieren Sie daher die WebSocket-Authentifizierung, bevor Sie einen Listener remote bereitstellen.

Unterstützte Flags für die WebSocket-Authentifizierung:

  • --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

Für signierte Bearer-Token können Sie außerdem --ws-issuer, --ws-audience und --ws-max-clock-skew-seconds festlegen. Clients übermitteln die Anmeldedaten während des WebSocket-Handshakes als Authorization: Bearer <token>, und app-server erzwingt die Authentifizierung vor JSON-RPC initialize.

Bevorzugen Sie --ws-token-file, anstatt unbearbeitete Bearer-Token in der Befehlszeile zu übergeben. Verwenden Sie --ws-token-sha256 nur, wenn der Client das unbearbeitete Token mit hoher Entropie in einem separaten lokalen Geheimnisspeicher aufbewahrt; der Hash dient lediglich zur Verifizierung, und Clients benötigen weiterhin das ursprüngliche Token.

Im WebSocket-Modus verwendet app-server begrenzte Warteschlangen. Wenn der Eingang für Anfragen voll ist, lehnt der Server neue Anfragen mit dem JSON-RPC-Fehlercode -32001 und der Meldung "Server overloaded; retry later." ab. Clients sollten es nach einer exponentiell ansteigenden Verzögerung mit Jitter erneut versuchen.

Nachrichtenschema

Anfragen enthalten method, params und id:

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

Antworten geben den Wert von id zusammen mit entweder result oder error zurück:

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

Benachrichtigungen lassen id weg und verwenden nur method und params:

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

Sie können über die CLI ein TypeScript-Schema oder ein JSON-Schema-Bundle generieren. Jede Ausgabe gilt für die jeweils ausgeführte Codex-Version, sodass die generierten Artefakte exakt dieser Version entsprechen:

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

Erste Schritte

  1. Starten Sie den Server mit codex app-server (standardmäßiger stdio-Transport), codex app-server --listen ws://127.0.0.1:4500 (TCP-WebSocket) oder codex app-server --listen unix:// (standardmäßiger Unix-Socket).
  2. Verbinden Sie einen Client über den ausgewählten Transport und senden Sie anschließend initialize, gefolgt von der Benachrichtigung initialized.
  3. Starten Sie einen Thread und einen Turn und lesen Sie anschließend fortlaufend Benachrichtigungen aus dem aktiven Transportstream.

Beispiel (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" } });

Zentrale Grundelemente

  • Thread: Ein Gespräch zwischen einem Benutzer und dem Codex-Agenten. Threads enthalten Turns.
  • Turn: Eine einzelne Benutzeranfrage und die darauffolgende Arbeit des Agenten. Turns enthalten Elemente und streamen inkrementelle Aktualisierungen.
  • Element: Eine Ein- oder Ausgabeeinheit (Benutzernachricht, Agentennachricht, Befehlsausführungen, Dateiänderung, Tool-Aufruf und mehr).

Verwenden Sie die Thread-APIs, um Gespräche zu erstellen, aufzulisten oder zu archivieren. Steuern Sie ein Gespräch mit den Turn-APIs und streamen Sie den Fortschritt über Turn-Benachrichtigungen.

Überblick über den Lebenszyklus

  • Einmal pro Verbindung initialisieren: Senden Sie unmittelbar nach dem Öffnen einer Transportverbindung eine initialize-Anfrage mit den Metadaten Ihres Clients und geben Sie anschließend initialized aus. Der Server lehnt vor diesem Handshake alle Anfragen über diese Verbindung ab.
  • Thread starten (oder fortsetzen): Rufen Sie thread/start für ein neues Gespräch, thread/resume zum Fortsetzen eines vorhandenen Gesprächs oder thread/fork auf, um den Verlauf in eine neue Thread-ID zu verzweigen.
  • Turn beginnen: Rufen Sie turn/start mit der gewünschten threadId und der Benutzereingabe auf. Optionale Felder überschreiben Modell, Persönlichkeit, cwd, Sandbox-Richtlinie und weitere Einstellungen.
  • Aktiven Turn steuern: Rufen Sie turn/steer auf, um dem derzeit laufenden Turn eine Benutzereingabe hinzuzufügen, ohne einen neuen Turn zu erstellen.
  • Ereignisse streamen: Lesen Sie nach turn/start fortlaufend Benachrichtigungen auf stdout: thread/archived, thread/unarchived, item/started, item/completed, item/agentMessage/delta, Tool-Fortschritt und weitere Aktualisierungen.
  • Turn abschließen: Wenn das Modell fertig ist oder nach einer Abbruchanforderung über turn/interrupt, gibt der Server turn/completed mit dem endgültigen Status aus.

Initialisierung

Clients müssen pro Transportverbindung eine einzelne initialize-Anfrage senden, bevor sie eine andere Methode über diese Verbindung aufrufen, und dies anschließend mit einer initialized-Benachrichtigung bestätigen. Vor der Initialisierung gesendete Anfragen erhalten einen Not initialized-Fehler, und wiederholte initialize-Aufrufe über dieselbe Verbindung geben Already initialized zurück.

Der Server gibt die User-Agent-Zeichenfolge zurück, die er gegenüber vorgelagerten Diensten verwendet, sowie die Werte platformFamily und platformOs, die das Laufzeitziel beschreiben. Legen Sie clientInfo fest, um Ihre Integration zu identifizieren.

initialize.params.capabilities unterstützt außerdem diese Client-Funktionen:

  • optOutNotificationMethods – exakte Methodennamen von Benachrichtigungen, die für diese Verbindung unterdrückt werden sollen. Der Abgleich erfolgt exakt (keine Platzhalter oder Präfixe); unbekannte Namen werden akzeptiert und ignoriert.
  • requestAttestation – aktiviert die vom Server initiierte Anfrage attestation/generate. Desktop-Hosts, die eine vorgelagerte Attestierung bereitstellen, antworten mit einem undurchsichtigen { "token": "..." }-Wert.
  • mcpServerOpenaiFormElicitation – erlaubt nachgelagerten MCP-Servern, die erweiterte OpenAI-Variante von mcpServer/elicitation/request zu senden.

Wichtig: Verwenden Sie clientInfo.name, um Ihren Client für die OpenAI Compliance Logs Platform zu identifizieren. Wenn Sie eine neue Codex-Integration für den Einsatz in Unternehmen entwickeln, wenden Sie sich bitte an OpenAI, damit sie der Liste bekannter Clients hinzugefügt wird. Weitere Informationen finden Sie in der Referenz zu Codex-Protokollen.

Beispiel (aus der Codex-Erweiterung für VS Code):

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

Beispiel mit deaktivierten Benachrichtigungen:

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

Experimentelle API aktivieren

Einige Methoden und Felder von app-server sind bewusst durch die Fähigkeit experimentalApi geschützt.

  • Lassen Sie capabilities weg (oder setzen Sie experimentalApi auf false), um ausschließlich die stabile API-Oberfläche zu verwenden; der Server lehnt dann experimentelle Methoden und Felder ab.
  • Setzen Sie capabilities.experimentalApi auf true, um experimentelle Methoden und Felder zu aktivieren.
{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true
    }
  }
}

Wenn ein Client eine experimentelle Methode oder ein experimentelles Feld sendet, ohne diese Funktion aktiviert zu haben, lehnt app-server dies mit Folgendem ab:

<descriptor> requires experimentalApi capability

API-Überblick

  • thread/start – erstellt einen neuen Thread; gibt thread/started aus und abonniert Sie automatisch für Turn-/Item-Ereignisse dieses Threads.
  • thread/resume – öffnet einen vorhandenen Thread anhand seiner ID erneut, sodass spätere turn/start-Aufrufe daran angehängt werden.
  • thread/fork – verzweigt einen Thread unter einer neuen Thread-ID, indem der gespeicherte Verlauf kopiert wird. Übergeben Sie lastTurnId, um den Verlauf bis einschließlich dieses Turns zu kopieren und spätere Turns auszulassen, oder ephemeral: true, um einen In-Memory-Fork zu erstellen. Gibt für den neuen Thread thread/started aus; zurückgegebene Threads enthalten forkedFromId, sofern verfügbar.
  • thread/read – liest einen gespeicherten Thread anhand seiner ID, ohne ihn fortzusetzen; legen Sie includeTurns fest, um den vollständigen Turn-Verlauf zurückzugeben. Zurückgegebene thread-Objekte enthalten die Laufzeitangabe status.
  • thread/list – durchläuft gespeicherte Thread-Protokolle seitenweise; unterstützt Cursor-basierte Paginierung sowie modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm und die experimentellen Filter parentThreadId oder ancestorThreadId. Zurückgegebene thread-Objekte enthalten die Laufzeitangabe status.
  • thread/turns/list – experimentell; durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen. itemsView steuert, ob Turn-Items ausgelassen, zusammengefasst oder vollständig geladen werden.
  • thread/items/list – experimentell; durchläuft persistierte Thread-Items seitenweise, optional auf einen einzelnen turnId beschränkt. Der aktive Thread-Speicher muss die Item-Paginierung unterstützen.
  • thread/loaded/list – listet die IDs der derzeit im Arbeitsspeicher geladenen Threads auf.
  • thread/name/set – legt den für Benutzer sichtbaren Namen eines geladenen Threads oder eines persistierten Rollouts fest oder aktualisiert ihn; gibt thread/name/updated aus.
  • thread/goal/set – legt das Ziel eines Threads fest; gibt thread/goal/updated aus.
  • thread/goal/get – liest das aktuelle Ziel eines Threads.
  • thread/goal/clear – löscht das Ziel eines Threads; gibt thread/goal/cleared aus.
  • thread/metadata/update – aktualisiert die Metadaten SQLite-gestützter gespeicherter Threads, einschließlich der persistierten Werte gitInfo und isPinned.
  • thread/archive – verschiebt die Protokolldatei eines Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfahren-Threads zu archivieren, die noch nicht archiviert sind; gibt bei Erfolg {} zurück und gibt für jeden archivierten Thread thread/archived aus.
  • thread/delete – löscht einen persistierten aktiven oder archivierten Thread und alle erzeugten Nachfahren-Threads dauerhaft; gibt bei Erfolg {} zurück und gibt für jeden gelöschten Thread thread/deleted aus.
  • thread/unsubscribe – beendet das Abonnement dieser Verbindung für Turn-/Item-Ereignisse des Threads. War dies der letzte Abonnent, entlädt der Server den Thread nach einer Karenzzeit ohne Abonnenten und gibt thread/closed aus.
  • thread/unarchive – stellt den Rollout eines archivierten Threads im Verzeichnis der aktiven Sitzungen wieder her; gibt den wiederhergestellten thread zurück und gibt thread/unarchived aus.
  • thread/status/changed – Benachrichtigung, die ausgegeben wird, wenn sich die Laufzeitangabe status eines geladenen Threads ändert.
  • thread/compact/start – löst die Komprimierung des Konversationsverlaufs eines Threads aus; gibt sofort {} zurück, während der Fortschritt über die Benachrichtigungen turn/* und item/* gestreamt wird.
  • thread/shellCommand – führt einen vom Benutzer initiierten Shell-Befehl für einen Thread aus. Dieser wird außerhalb der Sandbox mit vollständigem Zugriff ausgeführt und übernimmt nicht die Sandbox-Richtlinie des Threads.
  • thread/backgroundTerminals/clean – beendet alle laufenden Hintergrundterminals eines Threads (experimentell; erfordert capabilities.experimentalApi).
  • thread/backgroundTerminals/list – listet laufende Hintergrundterminals eines geladenen Threads auf (experimentell; erfordert capabilities.experimentalApi).
  • thread/backgroundTerminals/terminate – beendet ein laufendes Hintergrundterminal anhand der app-server-processId (experimentell; erfordert capabilities.experimentalApi).
  • thread/rollback – veraltet; entfernt die letzten N Turns aus dem In-Memory-Kontext und persistiert eine Rollback-Markierung; gibt den aktualisierten thread zurück.
  • turn/start – fügt einem Thread eine Benutzereingabe oder eine eigenständige Tool-Ausgabe hinzu und startet die Codex-Generierung; antwortet mit dem anfänglichen turn und streamt Ereignisse. Bei collaborationMode bedeutet settings.developer_instructions: null „integrierte Anweisungen für den ausgewählten Modus verwenden“.
  • thread/inject_items – hängt unbearbeitete Responses API-Items an den für das Modell sichtbaren Verlauf eines geladenen Threads an, ohne einen Benutzer-Turn zu starten.
  • turn/steer – hängt eine Benutzereingabe an den aktiven, derzeit ausgeführten Turn eines Threads an; gibt den akzeptierten turnId zurück.
  • turn/interrupt – fordert den Abbruch eines derzeit ausgeführten Turns an; bei Erfolg wird {} zurückgegeben und der Turn endet mit status: "interrupted".
  • review/start – startet den Codex-Reviewer für einen Thread; gibt die Items enteredReviewMode und exitedReviewMode aus.
  • command/exec – führt einen einzelnen Befehl in der Server-Sandbox aus, ohne einen Thread/Turn zu starten.
  • command/exec/write – schreibt stdin-Bytes in eine laufende command/exec-Sitzung oder schließt stdin.
  • command/exec/resize – ändert die Größe einer laufenden PTY-gestützten command/exec-Sitzung.
  • command/exec/terminate – beendet eine laufende command/exec-Sitzung.
  • command/exec/outputDelta (Benachrichtigung) – wird für Base64-codierte stdout-/stderr-Blöcke einer streamenden command/exec-Sitzung ausgegeben.
  • process/spawn – startet eine explizite Prozesssitzung außerhalb der Codex-Sandbox (experimentell; erfordert capabilities.experimentalApi).
  • process/writeStdin – schreibt stdin-Bytes in eine laufende process/spawn-Sitzung oder schließt stdin (experimentell).
  • process/resizePty – ändert die Größe einer laufenden PTY-gestützten Prozesssitzung (experimentell).
  • process/kill – beendet eine laufende Prozesssitzung (experimentell).
  • process/outputDelta und process/exited (Benachrichtigung) – werden für die gestreamte Prozessausgabe und den Prozessbeendigungsstatus ausgegeben (experimentell).
  • model/list – listet verfügbare Modelle auf (legen Sie includeHidden: true fest, um Einträge mit hidden: true einzuschließen), einschließlich Optionen für den Reasoning-Aufwand, optionalem upgrade und inputModalities.
  • modelProvider/capabilities/read – liest die Grenzen der Anbieterfunktionen für Modell-/Anbieterkombinationen.
  • experimentalFeature/list – listet Feature-Flags mit Metadaten zur Lebenszyklusphase und Cursor-Paginierung auf.
  • experimentalFeature/enablement/set – aktualisiert In-Memory-Laufzeiteinstellungen für unterstützte Feature-Schlüssel wie apps und plugins.
  • environment/info – experimentell; stellt eine Verbindung zu einer konfigurierten Ausführungsumgebung her und gibt deren Shell sowie das standardmäßige Arbeitsverzeichnis zurück.
  • permissionProfile/list – listet Beta-Berechtigungsprofile und mit Cursor-Paginierung auf, ob die geltenden Anforderungen sie zulassen.
  • collaborationMode/list – listet Voreinstellungen für den Zusammenarbeitsmodus auf (experimentell, ohne Paginierung).
  • skills/list – listet Skills für einen oder mehrere cwd-Werte auf (unterstützt forceReload und optional perCwdExtraUserRoots).
  • skills/extraRoots/set – ersetzt die zusätzlichen Wurzelverzeichnisse auf Prozessebene, die zur Erkennung eigenständiger Skills verwendet werden, ohne sie zu persistieren.
  • skills/changed (Benachrichtigung) – wird ausgegeben, wenn sich überwachte lokale Skill-Dateien ändern.
  • hooks/list – listet erkannte Lebenszyklus-Hooks für einen oder mehrere cwd-Werte auf.
  • marketplace/add – fügt einen Remote-Plugin-Marktplatz hinzu und persistiert ihn in der Marktplatzkonfiguration des Benutzers.
  • marketplace/remove – entfernt einen konfigurierten Marktplatz und, sofern vorhanden, dessen installiertes Marktplatz-Wurzelverzeichnis.
  • marketplace/upgrade – aktualisiert einen konfigurierten Git-Marktplatz oder alle konfigurierten Git-Marktplätze, wenn Sie den Marktplatznamen weglassen.
  • plugin/list – in Entwicklung; listet erkannte Plugin-Marktplätze und Plugin-Status auf, einschließlich Metadaten zu Installations-/Authentifizierungsrichtlinien, Fehlern beim Laden des Marktplatzes, IDs hervorgehobener Plugins sowie Metadaten zu lokalen, Git-, Paketregistrierungs- oder Remote-Plugin-Quellen. Zusammenfassungen können Remote-version, lokale localVersion, strukturierte Hell-/Dunkel-Symbole und installPolicySource enthalten, das bei aktuellen Remote-Zeilen null, WORKSPACE_SETTING oder IMPLICIT_CANONICAL_APP sein kann. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.
  • plugin/read – in Entwicklung; liest ein einzelnes Plugin anhand des Marktplatzpfads oder des Namens des Remote-Marktplatzes und des Plugin-Namens, einschließlich gebündelter Skills, Apps, MCP-Servernamen und eines Remote-Plugin-shareUrl, sofern der Remote-Katalog eines bereitstellt. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.
  • plugin/install – in Entwicklung; installiert ein Plugin anhand eines Marktplatzpfads oder des Namens eines Remote-Marktplatzes. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.
  • plugin/uninstall – in Entwicklung; deinstalliert ein installiertes Plugin. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.
  • plugin/skill/read – liest Remote-Plugin-Skill-Markdown bei Bedarf anhand des Remote-Marktplatzes, der Plugin-ID und des Skill-Namens.
  • app/installed – liest den Laufzeitstatus installierter Apps, einschließlich des tatsächlich geltenden Aktivierungs- und Aufrufstatus jeder App.
  • app/list – listet verfügbare Apps (Connectors) mit Paginierung sowie Metadaten zu Zugänglichkeit und Aktivierungsstatus auf.
  • app/read – ruft Metadaten und optionale, nur zur Anzeige bestimmte Tool-Zusammenfassungen für bestimmte App-IDs ab.
  • skills/config/write – aktiviert oder deaktiviert Skills anhand ihres Pfads.
  • mcpServer/oauth/login – startet eine OAuth-Anmeldung für einen konfigurierten MCP-Server; gibt eine Autorisierungs-URL zurück und gibt nach Abschluss mcpServer/oauthLogin/completed aus.
  • tool/requestUserInput – stellt dem Benutzer für einen Tool-Aufruf 1–3 kurze Fragen (experimentell); für Fragen kann isOther festgelegt werden, um eine Freitextoption bereitzustellen.
  • mcpServer/elicitation/request (Serveranforderung) – fordert vom Client eine strukturierte Formulareingabe oder die Bestätigung eines von einem MCP-Server angeforderten URL-Ablaufs an.
  • item/permissions/requestApproval (Serveranforderung) – fordert den Client auf, eine Teilmenge der vom integrierten Tool request_permissions angeforderten Netzwerk- oder Dateisystemberechtigungen zu erteilen.
  • config/mcpServer/reload – lädt die MCP-Serverkonfiguration erneut vom Datenträger und reiht eine Aktualisierung für geladene Threads ein.
  • mcpServerStatus/list – listet MCP-Server, Tools, Ressourcen und den Authentifizierungsstatus auf (Paginierung mit Cursor und Limit). Verwenden Sie detail: "full" für vollständige Daten oder detail: "toolsAndAuthOnly", um Ressourcen auszulassen.
  • mcpServer/resource/read – liest eine einzelne MCP-Ressource über einen initialisierten MCP-Server.
  • mcpServer/tool/call – ruft ein Tool auf dem konfigurierten MCP-Server eines Threads auf.
  • mcpServer/startupStatus/updated (Benachrichtigung) – wird ausgegeben, wenn sich der Startstatus eines konfigurierten MCP-Servers für einen geladenen Thread ändert.
  • windowsSandbox/setupStart – startet die Einrichtung der Windows-Sandbox für den Modus elevated oder unelevated; kehrt schnell zurück und gibt später windowsSandbox/setupCompleted aus.
  • feedback/upload – übermittelt einen Feedbackbericht (Klassifizierung sowie optional Begründung/Protokolle und Konversations-ID, zusätzlich optionale extraLogFiles-Anhänge).
  • config/read – ruft nach dem Auflösen der Konfigurationsebenen die tatsächlich geltende Konfiguration vom Datenträger ab.
  • externalAgentConfig/detect – erkennt Artefakte externer Agenten, die mit includeHome und optional cwds migriert werden können; jedes erkannte Element enthält cwd (null für das Home-Verzeichnis).
  • externalAgentConfig/import – wendet ausgewählte Migrationselemente externer Agenten an, indem explizite migrationItems mit cwd (null für das Home-Verzeichnis) übergeben werden. Zu den unterstützten Elementtypen zählen Konfiguration, Skills, AGENTS.md, Plugins, MCP-Serverkonfiguration, Subagenten, Hooks, Befehle und Sitzungen; nicht leere Importe geben während der Ausführung externalAgentConfig/import/progress und externalAgentConfig/import/completed aus. Plugin- und Sitzungsimporte können asynchron abgeschlossen werden.
  • config/value/write – schreibt ein einzelnes Konfigurationsschlüssel-Wert-Paar in die config.toml des Benutzers auf dem Datenträger.
  • config/batchWrite – wendet Konfigurationsänderungen atomar auf die config.toml des Benutzers auf dem Datenträger an.
  • configRequirements/read – ruft Anforderungen aus requirements.toml und/oder MDM ab, einschließlich der exakten verwalteten Konfiguration, Positivlisten, angehefteten featureRequirements und Netzwerkanforderungen (oder null, wenn Sie noch keine eingerichtet haben).
  • fs/readFile, fs/writeFile, fs/createDirectory, fs/getMetadata, fs/readDirectory, fs/remove, fs/copy, fs/watch, fs/unwatch und fs/changed (Benachrichtigung) – führen über die app-server-v2-Dateisystem-API Operationen auf absoluten Dateisystempfaden aus.

Plugin-Zusammenfassungen enthalten eine source-Union. Lokale Plugins geben { "type": "local", "path": ... } zurück, Einträge Git-basierter Marktplätze geben { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... } zurück, Paketregistrierungseinträge geben { "type": "npm", "package": ..., "version": ..., "registry": ... } zurück und Remote-Katalogeinträge geben { "type": "remote" } zurück. Bei ausschließlich im Remote-Katalog vorhandenen Einträgen kann PluginMarketplaceEntry.path den Wert null haben; übergeben Sie beim Lesen oder Installieren dieser Plugins remoteMarketplaceName anstelle von marketplacePath.

Modelle

Modelle auflisten (model/list)

Rufen Sie model/list auf, um verfügbare Modelle und deren Funktionen zu ermitteln, bevor Sie Auswahlfelder für Modelle oder Persönlichkeiten darstellen.

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

Jeder Modelleintrag kann Folgendes enthalten:

  • supportedReasoningEfforts – unterstützte Aufwandsoptionen für das Modell.
  • defaultReasoningEffort – empfohlener Standardaufwand für Clients.
  • upgrade – optionale ID des empfohlenen Upgrade-Modells für Migrationsaufforderungen in Clients.
  • upgradeInfo – optionale Upgrade-Metadaten für Migrationsaufforderungen in Clients.
  • hidden – gibt an, ob das Modell in der standardmäßigen Auswahlliste ausgeblendet ist.
  • inputModalities – unterstützte Eingabetypen des Modells (beispielsweise text, image).
  • supportsPersonality – gibt an, ob das Modell persönlichkeitsspezifische Anweisungen wie /personality unterstützt.
  • isDefault – gibt an, ob das Modell als Standard empfohlen wird.

Standardmäßig gibt model/list nur Modelle zurück, die in der Auswahl sichtbar sind. Setzen Sie includeHidden: true, wenn Sie die vollständige Liste benötigen und clientseitig anhand von hidden filtern möchten.

Wenn inputModalities fehlt (ältere Modellkataloge), behandeln Sie den Wert aus Gründen der Abwärtskompatibilität als ["text", "image"].

Experimentelle Features auflisten (experimentalFeature/list)

Verwenden Sie diesen Endpunkt, um Feature-Flags mit Metadaten und Lebenszyklusphase zu ermitteln:

{ "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 kann beta, underDevelopment, stable, deprecated oder removed sein. Bei Nicht-Beta-Flags können displayName, description und announcement den Wert null haben.

Ausführungsumgebung untersuchen (experimentell)

Verwenden Sie environment/info, um eine konfigurierte Remote-Umgebung zu untersuchen, bevor Sie dort mit der Arbeit beginnen. Die Methode erfordert 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 kann null sein. Sofern vorhanden, handelt es sich um eine kanonische file:-URI, welche die native Pfadsyntax der Umgebung verwendet. Unbekannte Umgebungs-IDs sowie Verbindungs- oder Protokollfehler führen zu Anfragefehlern.

Threads

  • thread/read liest einen gespeicherten Thread, ohne ihn zu abonnieren; setzen Sie includeTurns, um Turns einzuschließen.
  • thread/turns/list ist experimentell und durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen. Verwenden Sie itemsView, um auszuwählen, ob Turn-Elemente weggelassen, zusammengefasst oder vollständig geladen werden.
  • thread/items/list ist experimentell und durchläuft persistierte Thread-Elemente seitenweise, optional auf einen Turn beschränkt.
  • thread/list unterstützt Cursor-Paginierung sowie Filterung nach modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm und den experimentellen Filtern parentThreadId oder ancestorThreadId.
  • thread/loaded/list gibt die IDs der derzeit im Arbeitsspeicher befindlichen Threads zurück.
  • thread/archive verschiebt das persistierte JSONL-Protokoll des Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfolger-Threads zu archivieren, die noch nicht archiviert sind.
  • thread/delete löscht einen persistierten aktiven oder archivierten Thread und seine erzeugten Nachfolger-Threads dauerhaft.
  • thread/metadata/update aktualisiert gespeicherte Thread-Metadaten teilweise, einschließlich persistierter Werte für gitInfo und isPinned.
  • thread/unsubscribe beendet das Abonnement der aktuellen Verbindung für einen geladenen Thread und kann nach einer Inaktivitätskarenzzeit thread/closed auslösen.
  • thread/unarchive stellt einen archivierten Thread-Rollout im Verzeichnis der aktiven Sitzungen wieder her.
  • thread/compact/start löst die Komprimierung aus und gibt sofort {} zurück.
  • thread/rollback ist veraltet. Es entfernt die letzten N Turns aus dem Kontext im Arbeitsspeicher und zeichnet eine Rollback-Markierung im persistierten JSONL-Protokoll des Threads auf.
  • thread/inject_items fügt dem für das Modell sichtbaren Verlauf eines geladenen Threads unbearbeitete Responses API-Elemente hinzu, ohne einen Benutzer-Turn zu starten.

Thread starten oder fortsetzen

Starten Sie einen neuen Thread, wenn Sie ein neues Codex-Gespräch benötigen.

{ "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 ist optional. Legen Sie diesen Wert fest, wenn app-server Metriken auf Thread-Ebene mit dem Dienstnamen Ihrer Integration kennzeichnen soll.

thread/start, thread/resume und thread/fork geben instructionSources zurück, ein Array mit den Pfaden geladener Anweisungsdateien. Jeder Pfad verwendet die native absolute Syntax seiner Quellumgebung, einschließlich Pfaden für Remote- Umgebungen.

Experimentelle Clients können historyMode bei thread/start auf "legacy" (den Standardwert) oder "paginated" setzen. Die paginierte Thread-Erstellung wird noch nicht unterstützt und gibt den JSON-RPC-Fehler -32601 zurück. app-server kann Zusammenfassungen vorhandener paginierter Datensätze auflisten und lesen, doch Lesevorgänge des vollständigen Verlaufs, die Turn-Paginierung und das Fortsetzen werden bis zur Unterstützung paginierter Verläufe sicher abgelehnt.

Beta-Clients, die capabilities.experimentalApi aktivieren, können in permissions anstelle des veralteten Felds sandbox die ID eines benannten Berechtigungsprofils übergeben. Senden Sie permissions und sandbox nicht zusammen. Verwenden Sie permissionProfile/list mit dem Projektwert cwd, um verfügbare Profile zu ermitteln und festzustellen, ob verwaltete Anforderungen die einzelnen Profile zulassen.

thread.sessionId identifiziert die Wurzel des aktuellen Live-Sitzungsbaums. Wurzel-Threads verwenden ihre eigene Thread-ID als Sitzungs-ID; verzweigte Threads behalten die Sitzungs-ID der Wurzel bei, von der sie abstammen. Clients sollten die Sitzungs-ID aus thread.sessionId lesen, anstatt sie aus der Thread-ID abzuleiten.

Um eine gespeicherte Sitzung fortzusetzen, rufen Sie thread/resume mit der zuvor aufgezeichneten thread.id auf. Die Antwortstruktur entspricht thread/start. Sie können auch dieselben Konfigurationsüberschreibungen übergeben, die thread/start unterstützt, beispielsweise 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 } } }

Durch das Fortsetzen eines Threads wird thread.updatedAt (oder der Änderungszeitpunkt der Rollout-Datei) nicht automatisch aktualisiert. Der Zeitstempel wird aktualisiert, sobald Sie einen Turn starten.

Wenn Sie einen aktivierten MCP-Server in der Konfiguration als required markieren und dieser Server nicht initialisiert werden kann, schlagen thread/start und thread/resume fehl, anstatt ohne ihn fortzufahren.

dynamicTools bei thread/start ist ein experimentelles Feld (erfordert capabilities.experimentalApi = true). Codex persistiert diese dynamischen Tools in den Rollout-Metadaten des Threads und stellt sie bei thread/resume wieder her, wenn Sie keine neuen dynamischen Tools angeben.

Wenn Sie einen Thread mit einem anderen Modell fortsetzen als dem im Rollout aufgezeichneten, gibt Codex eine Warnung aus und wendet beim nächsten Turn einmalig eine Anweisung zum Modellwechsel an.

Thread-Ziel verwalten

Verwenden Sie thread/goal/set, thread/goal/get und thread/goal/clear, um denselben persistierten Zielstatus zu verwalten, den /goal in der TUI anzeigt.

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

Zielsetzungen dürfen nicht leer sein und höchstens 4.000 Zeichen umfassen. Wenn Sie eine neue Zielsetzung angeben, wird das Ziel ersetzt und die Nutzungszählung zurückgesetzt. Wenn Sie die aktuelle noch nicht abgeschlossene Zielsetzung angeben oder objective weglassen, werden Status oder Token-Budget aktualisiert, während der Nutzungsverlauf erhalten bleibt.

Um von einer gespeicherten Sitzung abzuzweigen, rufen Sie thread/fork mit der thread.id auf. Dadurch wird eine neue Thread-ID erstellt und eine thread/started-Benachrichtigung dafür ausgegeben. Übergeben Sie lastTurnId, um den Verlauf bis einschließlich dieses Turns zu kopieren und spätere Turns wegzulassen:

{ "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 lehnt einen laufenden lastTurnId ab. Wenn Sie das Feld weglassen, während sich der Quell-Thread mitten in einem Turn befindet, zeichnet die Verzweigung eine Unterbrechungsmarkierung auf, anstatt einen nicht gekennzeichneten unvollständigen Turn beizubehalten.

Übergeben Sie ephemeral: true, um eine Verzweigung im Arbeitsspeicher zu erstellen, ohne sie zu den gespeicherten Thread-Auflistungen hinzuzufügen:

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

Kurzlebige Verzweigungen paginierter Threads erfordern außerdem excludeTurns: true. Dieses Feld ist experimentell und erfordert capabilities.experimentalApi = true.

Wenn ein benutzerfreundlicher Thread-Titel festgelegt wurde, fügt app-server thread.name in den Antworten von thread/list, thread/read, thread/resume, thread/unarchive und thread/rollback ein. thread/start und thread/fork können name weglassen (oder null zurückgeben), bis später ein Titel festgelegt wird.

Gespeicherten Thread lesen (ohne ihn fortzusetzen)

Verwenden Sie thread/read, wenn Sie gespeicherte Thread-Daten benötigen, den Thread jedoch weder fortsetzen noch seine Ereignisse abonnieren möchten.

  • includeTurns – bei true enthält die Antwort die Turns des Threads; bei false oder wenn der Wert weggelassen wird, erhalten Sie nur die Thread-Zusammenfassung.
  • Zurückgegebene thread-Objekte enthalten das Laufzeitfeld status (notLoaded, idle, systemError oder active mit activeFlags).
{ "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": [] } } }

Im Gegensatz zu thread/resume lädt thread/read den Thread weder in den Arbeitsspeicher noch gibt es thread/started aus.

Thread-Turns auflisten

thread/turns/list ist experimentell. Verwenden Sie diese Methode, um den Turn-Verlauf eines gespeicherten Threads seitenweise zu durchlaufen, ohne ihn fortzusetzen. Die Ergebnisse werden standardmäßig vom neuesten zum ältesten sortiert, sodass Clients mit nextCursor ältere Turns abrufen können. Die Antwort enthält außerdem backwardsCursor; übergeben Sie den Wert als cursor zusammen mit sortDirection: "asc", um Turns abzurufen, die neuer als das erste Element der vorherigen Seite sind.

itemsView steuert, wie viele Turn-Elementdaten die Antwort enthält:

  • notLoaded lässt Elemente weg.
  • summary gibt zusammengefasste Elementdaten zurück und ist der Standardwert, wenn das Feld weggelassen wird.
  • full gibt vollständige Elementdaten zurück.
{ "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 ist ebenfalls experimentell. Es durchläuft persistierte Elemente seitenweise, ohne den Thread fortzusetzen. Übergeben Sie turnId, um die Ergebnisse auf einen Turn zu beschränken, oder lassen Sie den Wert weg, um Elemente threadübergreifend seitenweise zu durchlaufen. Der aktive Thread-Speicher muss die Elementpaginierung unterstützen; andernfalls gibt der Server einen Fehler für eine nicht unterstützte Methode zurück.

Threads auflisten (mit Paginierung und Filtern)

Mit thread/list können Sie eine Verlaufsoberfläche darstellen. Die Ergebnisse werden anhand von createdAt standardmäßig vom neuesten zum ältesten sortiert. Filter werden vor der Paginierung angewendet. Übergeben Sie eine beliebige Kombination aus:

  • cursor – nicht transparenter String aus einer vorherigen Antwort; für die erste Seite weglassen.
  • limit – wenn nicht festgelegt, verwendet der Server standardmäßig eine angemessene Seitengröße.
  • sortKeycreated_at (Standard), updated_at oder recency_at.
  • sortDirectiondesc (Standard) oder asc.
  • modelProviders – beschränkt die Ergebnisse auf bestimmte Anbieter; wenn nicht festgelegt, null oder ein leeres Array, werden alle Anbieter einbezogen.
  • sourceKinds – beschränkt die Ergebnisse auf bestimmte Thread-Quellen. Wenn der Wert weggelassen wird oder [] lautet, verwendet der Server standardmäßig nur interaktive Quellen: cli und vscode.
  • archived – bei true werden nur archivierte Threads aufgelistet. Bei false oder wenn der Wert weggelassen wird, werden nicht archivierte Threads aufgelistet (Standard).
  • isPinned – wenn angegeben, werden nur Threads zurückgegeben, deren persistierter Anheftungsstatus übereinstimmt. Lassen Sie den Wert weg, um angeheftete und nicht angeheftete Threads zurückzugeben.
  • cwd – beschränkt die Ergebnisse auf Threads, deren aktuelles Sitzungsarbeitsverzeichnis exakt diesem Pfad oder einem der Pfade in einem Array entspricht. Relative Pfade werden ausgehend vom Arbeitsverzeichnis des app-server-Prozesses aufgelöst.
  • useStateDbOnly – bei true werden Ergebnisse der Statusdatenbank zurückgegeben, ohne JSONL-Thread-Protokolle zu durchsuchen, um Metadaten zu reparieren. Lassen Sie den Wert weg oder übergeben Sie false, um das standardmäßige Such- und Reparaturverhalten zu verwenden.
  • searchTerm – beschränkt die Ergebnisse auf Threads, deren extrahierter Titel dieses Fragment unter Beachtung der Groß-/Kleinschreibung enthält.
  • parentThreadId – beschränkt die Ergebnisse auf direkte untergeordnete Threads des angegebenen übergeordneten Threads. Dieser Filter ist experimentell und erfordert capabilities.experimentalApi = true.
  • ancestorThreadId – beschränkt die Ergebnisse auf erzeugte Nachfolger des angegebenen Threads in beliebiger Tiefe. Dieser Filter ist experimentell und erfordert capabilities.experimentalApi = true; kombinieren Sie ihn nicht mit parentThreadId.

sourceKinds akzeptiert die folgenden Werte:

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

Beispiel:

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

Wenn nextCursor den Wert null hat, haben Sie die letzte Seite erreicht.

Gespeicherte Thread-Metadaten aktualisieren

Verwenden Sie thread/metadata/update, um gespeicherte Thread-Metadaten teilweise zu aktualisieren, ohne den Thread fortzusetzen. Setzen Sie isPinned, um den Thread anzuheften oder die Anheftung aufzuheben, oder aktualisieren Sie gitInfo, um persistierte Git-Metadaten zu ändern. Ausgelassene Felder bleiben unverändert; ein explizites null löscht einen gespeicherten Git-Metadatenwert.

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

Änderungen des Thread-Status verfolgen

thread/status/changed wird ausgegeben, wenn sich der Laufzeitstatus eines geladenen Threads ändert. Die Nutzdaten enthalten threadId und den neuen Wert von status.

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

Geladene Threads auflisten

thread/loaded/list gibt die IDs der derzeit im Arbeitsspeicher geladenen Threads zurück.

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

Abonnement eines geladenen Threads beenden

thread/unsubscribe entfernt das Abonnement der aktuellen Verbindung für einen Thread. Der Antwortstatus lautet:

  • unsubscribed, wenn die Verbindung den Thread abonniert hatte und das Abonnement nun entfernt wurde.
  • notSubscribed, wenn die Verbindung diesen Thread nicht abonniert hatte.
  • notLoaded, wenn der Thread nicht geladen ist.

War dies der letzte Abonnent, hält der Server den Thread geladen, bis er 30 Minuten lang weder Abonnenten noch Thread-Aktivität aufweist. Nach Ablauf der Karenzzeit entlädt app-server den Thread und gibt einen thread/status/changed-Übergang zu notLoaded sowie thread/closed aus.

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

Wenn der Thread später abläuft:

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

Thread archivieren

Verwenden Sie thread/archive, um das persistierte Thread-Protokoll (als JSONL-Datei auf dem Datenträger gespeichert) in das Verzeichnis archivierter Sitzungen zu verschieben. Beim Archivieren eines Threads wird außerdem versucht, erzeugte Nachfolger-Threads zu archivieren, die noch nicht archiviert sind.

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

Archivierte Threads erscheinen bei zukünftigen Aufrufen von thread/list nur, wenn Sie archived: true übergeben. Der Server gibt für jeden tatsächlich archivierten Thread eine thread/archived-Benachrichtigung aus; kann ein erzeugter Nachfolger nicht archiviert werden, kann die Anfrage dennoch erfolgreich sein, ohne dass für diesen Nachfolger eine Archivierungsbenachrichtigung ausgegeben wird.

Thread löschen

Verwenden Sie thread/delete, um einen dauerhaft gespeicherten aktiven oder archivierten Thread und die von ihm erzeugten untergeordneten Threads endgültig zu löschen. Der Server entfernt vorhandene Rollout-Dateien und zugehörige Metadaten, bevor er den Erfolg zurückmeldet; fehlende Rollout-Dateien gelten als bereits gelöscht. Flüchtige Root-Threads können nicht gelöscht werden.

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

Archivierung eines Threads aufheben

Verwenden Sie thread/unarchive, um den Rollout eines archivierten Threads zurück in das Verzeichnis der aktiven Sitzungen zu verschieben.

{ "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-Komprimierung auslösen

Verwenden Sie thread/compact/start, um die manuelle Komprimierung des Verlaufs eines Threads auszulösen. Die Anfrage gibt sofort {} zurück.

App-server gibt den Fortschritt als standardmäßige turn/*- und item/*-Benachrichtigungen über dieselbe threadId aus, einschließlich des Lebenszyklus eines contextCompaction-Elements (item/started, dann item/completed).

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

Shell-Befehl für einen Thread ausführen

Verwenden Sie thread/shellCommand für vom Benutzer initiierte Shell-Befehle, die zu einem Thread gehören. Die Anfrage gibt sofort {} zurück, während der Fortschritt über standardmäßige turn/*- und item/*-Benachrichtigungen gestreamt wird.

Diese API wird außerhalb der Sandbox mit vollständigem Zugriff ausgeführt und übernimmt die Sandbox-Richtlinie des Threads nicht. Clients sollten sie nur für ausdrücklich vom Benutzer initiierte Befehle bereitstellen.

Wenn der Thread bereits einen aktiven Turn hat, wird der Befehl als zusätzliche Aktion dieses Turns ausgeführt und seine formatierte Ausgabe in den Nachrichtenstream des Turns eingefügt. Ist der Thread inaktiv, startet app-server einen eigenständigen Turn für den Shell-Befehl.

Legen Sie timeoutMs fest, um die Ausführungszeit in Millisekunden zu begrenzen. Wenn Sie den Wert weglassen oder null übergeben, gilt der Standardwert von einer Stunde. 0 fordert ein sofortiges Timeout an; negative Werte werden abgelehnt. Das Timeout verzögert die unmittelbare RPC-Bestätigung nicht.

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

Hintergrundterminals bereinigen

Verwenden Sie thread/backgroundTerminals/clean, um alle laufenden Hintergrundterminals zu beenden, die einem Thread zugeordnet sind. Diese Methode ist experimentell und erfordert capabilities.experimentalApi = true.

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

Verwenden Sie thread/backgroundTerminals/list, um die laufenden Hintergrundterminals eines geladenen Threads zu prüfen. Die Anfrage unterstützt die standardmäßige Paginierung mit cursor und limit, und der zurückgegebene Wert processId ist die Prozess-ID von app-server. Diese Methode ist experimentell und erfordert 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 } }

Verwenden Sie thread/backgroundTerminals/terminate mit diesem processId, um ein Hintergrundterminal zu beenden. Diese Methode ist experimentell und erfordert capabilities.experimentalApi = true:

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

Letzte Turns zurücksetzen

thread/rollback ist veraltet und wird entfernt. Es entfernt die letzten numTurns Einträge aus dem In-Memory-Kontext und speichert eine Rollback-Markierung im Rollout-Protokoll. Das zurückgegebene thread enthält turns, das nach dem Rollback ausgefüllt ist.

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

Turns

Das Feld input akzeptiert eine Liste von Elementen:

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

Sie können Konfigurationseinstellungen pro Turn überschreiben (Modell, Aufwand, Persönlichkeit, cwd, Sandbox-Richtlinie, Zusammenfassung). Wenn diese Einstellungen angegeben werden, dienen sie als Standardwerte für spätere Turns desselben Threads. outputSchema gilt nur für den aktuellen Turn. Setzen Sie für sandboxPolicy.type = "externalSandbox" den Wert networkAccess auf restricted oder enabled; für workspaceWrite bleibt networkAccess ein boolescher Wert.

Bei turn/start.collaborationMode bedeutet settings.developer_instructions: null „die integrierten Anweisungen für den ausgewählten Modus verwenden“ und nicht, dass die Modusanweisungen gelöscht werden.

Lesezugriff der Sandbox (ReadOnlyAccess)

sandboxPolicy unterstützt explizite Einstellungen für den Lesezugriff:

  • readOnly: optionales access (standardmäßig { "type": "fullAccess" } oder eingeschränkte Stammverzeichnisse).
  • workspaceWrite: optionales readOnlyAccess (standardmäßig { "type": "fullAccess" } oder eingeschränkte Stammverzeichnisse).

Struktur für eingeschränkten Lesezugriff:

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

Unter macOS fügt includePlatformDefaults: true für Sitzungen mit eingeschränktem Lesezugriff eine kuratierte, plattformspezifische Seatbelt-Standardrichtlinie hinzu. Dies verbessert die Tool-Kompatibilität, ohne pauschal den gesamten Bereich /System freizugeben.

Beispiele:

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

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

Um einen Turn mit der Ausgabe eines von Ihrem Client ausgeführten Tools zu starten, übergeben Sie toolOutput mit einem nicht leeren name, einem optionalen namespace und einem output-String oder einem Array von Inhaltselementen. Legen Sie input auf ein leeres Array fest; Sie können toolOutput nicht mit einer nicht leeren Benutzereingabe kombinieren.

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

Die Ausgabe bleibt in der Konversation eine Tool-Ausgabe und erscheint in Benachrichtigungen und im persistierten Verlauf als functionCallOutput-Item. Wenn bereits ein regulärer Turn aktiv ist, reiht Codex die Ausgabe für diesen Turn ein.

Elemente in einen Thread einfügen

Verwenden Sie thread/inject_items, um vorab erstellte Responses API-Elemente an den Prompt-Verlauf eines geladenen Threads anzuhängen, ohne einen Benutzer-Turn zu starten. Diese Elemente werden im Rollout gespeichert und in nachfolgende Modellanfragen aufgenommen.

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

Aktiven Turn steuern

Verwenden Sie turn/steer, um dem aktiven, laufenden Turn weitere Benutzereingaben hinzuzufügen.

  • Geben Sie expectedTurnId an; der Wert muss mit der ID des aktiven Turns übereinstimmen.
  • Die Anfrage schlägt fehl, wenn der Thread keinen aktiven Turn hat.
  • turn/steer gibt keine neue turn/started-Benachrichtigung aus.
  • turn/steer akzeptiert keine Überschreibungen auf Turn-Ebene (model, cwd, sandboxPolicy oder 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" } }

Turn starten (Skill aufrufen)

Rufen Sie einen Skill explizit auf, indem Sie $<skill-name> in die Texteingabe aufnehmen und daneben ein skill-Eingabeelement hinzufügen.

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

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

Bei Erfolg endet der Turn mit status: "interrupted".

Review

review/start führt den Codex-Reviewer für einen Thread aus und streamt Review-Elemente. Zu den Zielen gehören:

  • uncommittedChanges
  • baseBranch (Diff gegenüber einem Branch)
  • commit (Review eines bestimmten Commits)
  • custom (frei formulierte Anweisungen)

Verwenden Sie delivery: "inline" (Standard), um das Review im vorhandenen Thread auszuführen, oder delivery: "detached", um einen neuen Review-Thread abzuzweigen.

Beispiel für Anfrage und Antwort:

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

Verwenden Sie für ein abgekoppeltes Review "delivery": "detached". Die Antwort hat dieselbe Struktur, aber reviewThreadId enthält die ID des neuen Review-Threads (abweichend vom ursprünglichen threadId). Der Server gibt außerdem eine thread/started-Benachrichtigung für diesen neuen Thread aus, bevor er den Review-Turn streamt.

Codex streamt zunächst die übliche turn/started-Benachrichtigung und anschließend ein item/started mit einem enteredReviewMode-Element:

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

Wenn der Reviewer fertig ist, gibt der Server item/started und item/completed mit einem exitedReviewMode-Element aus, das den endgültigen Review-Text enthält:

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

Verwenden Sie diese Benachrichtigung, um die Ausgabe des Reviewers in Ihrem Client darzustellen.

Prozessausführung

process/* ist eine experimentelle, explizite API zur Prozesssteuerung. Sie erfordert capabilities.experimentalApi = true und wird außerhalb der Sandbox von Codex ausgeführt. Verwenden Sie sie nur, wenn Ihr Client die lokale Prozesssteuerung bewusst ohne Sandbox bereitstellt.

Starten Sie mit process/spawn einen Prozess und geben Sie ein processHandle an. Verwenden Sie dieses Handle anschließend für Anfragen zu stdin, Größenänderungen und zum Beenden. Die Ausgabe wird über process/outputDelta-Benachrichtigungen gestreamt, der Abschluss über 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
} }

Verwenden Sie process/writeStdin mit deltaBase64, closeStdin oder beiden, um Eingaben zu senden. Verwenden Sie process/resizePty für Ereignisse zur Größenänderung des PTY und process/kill, um einen laufenden Prozess zu beenden.

Befehlsausführung

command/exec führt einen einzelnen Befehl (argv-Array) in der Server-Sandbox aus, ohne einen Thread zu erstellen.

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

Verwenden Sie sandboxPolicy.type = "externalSandbox", wenn Sie den Serverprozess bereits in einer Sandbox ausführen und möchten, dass Codex seine eigene Sandbox-Durchsetzung überspringt. Setzen Sie für den externen Sandbox-Modus networkAccess auf restricted (Standard) oder enabled. Verwenden Sie für readOnly und workspaceWrite dieselbe oben gezeigte optionale Struktur mit access / readOnlyAccess.

Hinweise:

  • Der Server lehnt leere command-Arrays ab.
  • sandboxPolicy akzeptiert dieselbe Struktur wie turn/start (beispielsweise dangerFullAccess, readOnly, workspaceWrite, externalSandbox).
  • Wenn timeoutMs nicht angegeben wird, wird der Standardwert des Servers verwendet.
  • Setzen Sie tty: true für PTY-gestützte Sitzungen und verwenden Sie processId, wenn Sie anschließend command/exec/write, command/exec/resize oder command/exec/terminate verwenden möchten.
  • Setzen Sie streamStdoutStderr: true, um während der Befehlsausführung command/exec/outputDelta-Benachrichtigungen zu erhalten.

Administratoranforderungen lesen (configRequirements/read)

Verwenden Sie configRequirements/read, um die wirksamen Administratoranforderungen zu prüfen, die aus requirements.toml und/oder MDM geladen wurden.

{ "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.requirements ist null, wenn keine Anforderungen konfiguriert sind. Einzelheiten zu unterstützten Schlüsseln und Werten finden Sie in der Dokumentation zu requirements.toml.

Einrichtung der Windows-Sandbox (windowsSandbox/setupStart)

Benutzerdefinierte Windows-Clients können die Einrichtung der Sandbox asynchron auslösen, anstatt auf Startprüfungen zu warten.

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

App-server startet die Einrichtung im Hintergrund und gibt später eine Abschlussbenachrichtigung aus:

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

Modi:

  • elevated – führt den Einrichtungspfad der Windows-Sandbox mit erhöhten Berechtigungen aus.
  • unelevated – führt den bisherigen Einrichtungs-/Vorabprüfungspfad aus.

Dateisystem

Die v2-Dateisystem-APIs arbeiten mit absoluten Pfaden. Verwenden Sie fs/watch, wenn ein Client den UI-Status nach einer Änderung an einer Datei oder einem Verzeichnis invalidieren muss.

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

Die Überwachung einer Datei gibt bei Änderungen an diesem Dateipfad fs/changed aus. Dies schließt Aktualisierungen ein, die durch Ersetzungs- oder Umbenennungsvorgänge entstehen.

Ereignisse

Ereignisbenachrichtigungen sind der vom Server initiierte Stream für die Lebenszyklen von Threads und Turns sowie für die darin enthaltenen Elemente. Lesen Sie nach dem Starten oder Fortsetzen eines Threads den aktiven Transportstream weiter, um Benachrichtigungen vom Typ thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* und serverRequest/resolved zu empfangen.

Benachrichtigungen deaktivieren

Clients können bestimmte Benachrichtigungen pro Verbindung unterdrücken, indem sie die exakten Methodennamen in initialize.params.capabilities.optOutNotificationMethods senden.

  • Nur exakte Übereinstimmung: item/agentMessage/delta unterdrückt ausschließlich diese Methode.
  • Unbekannte Methodennamen werden ignoriert.
  • Gilt für die aktuellen Benachrichtigungen thread/*, turn/*, item/* und verwandte v2-Benachrichtigungen.
  • Gilt nicht für Anfragen, Antworten oder Fehler.

Ereignisse der unscharfen Dateisuche (experimentell)

Die Sitzungs-API für die unscharfe Dateisuche gibt pro Abfrage Benachrichtigungen aus:

  • fuzzyFileSearch/sessionUpdated{ sessionId, query, files } mit den aktuellen Treffern für die aktive Abfrage.
  • fuzzyFileSearch/sessionCompleted – einmal { sessionId }, sobald die Indizierung und der Abgleich für diese Abfrage abgeschlossen sind.

Warnereignisse

  • configWarning{ summary, details?, path?, range? } für behebbare Konfigurations- oder Initialisierungsprobleme.
  • warning{ threadId?, message } für nicht schwerwiegende Laufzeitwarnungen.

Ereignisse zur Einrichtung der Windows-Sandbox

  • windowsSandbox/setupCompleted{ mode, success, error }, das nach Abschluss einer windowsSandbox/setupStart-Anfrage ausgegeben wird.

Turn-Ereignisse

  • turn/started{ turn } mit der Turn-ID, einem leeren items und status: "inProgress".
  • turn/completed{ turn }, wobei turn.status den Wert completed, interrupted oder failed hat; bei Fehlern ist { error: { message, codexErrorInfo?, additionalDetails? } } enthalten.
  • turn/diff/updated{ threadId, turnId, diff } mit dem neuesten aggregierten einheitlichen Diff über sämtliche Dateiänderungen des Turns.
  • turn/plan/updated{ turnId, explanation?, plan }, wenn der Agent seinen Plan mitteilt oder ändert; jeder plan-Eintrag ist { step, status }, wobei status den Wert pending, inProgress oder completed hat.
  • hook/started und hook/completed{ threadId, turnId?, run } beim Start eines synchronen Lebenszyklus-Hooks beziehungsweise dann, wenn dessen endgültige Ausführungszusammenfassung verfügbar ist. Diese Benachrichtigungen werden bei asynchronen Hooks nicht ausgegeben.
  • model/safetyBuffering/updated{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }, wenn eine Antwort vorübergehend zur Sicherheitsprüfung gepuffert wird.
  • model/rerouted{ threadId, turnId, fromModel, toModel, reason }, wenn der Dienst eine Anfrage an ein anderes Modell weiterleitet.
  • model/verification{ threadId, turnId, verifications }, wenn der Dienst eine zusätzliche Kontoverifizierung verlangt.
  • thread/tokenUsage/updated – Nutzungsaktualisierungen für den aktiven Thread.

turn/diff/updated und turn/plan/updated enthalten derzeit auch dann leere items-Arrays, wenn Elementereignisse gestreamt werden. Verwenden Sie item/*-Benachrichtigungen als maßgebliche Quelle für Turn-Elemente.

Elemente

ThreadItem ist die mit Tags versehene Union, die in Turn-Antworten und item/*-Benachrichtigungen übertragen wird. Zu den gängigen Elementtypen gehören:

  • userMessage{id, content}, wobei content eine Liste von Benutzereingaben ist (text, image oder localImage).
  • functionCallOutput{id, name, namespace, output} für eine über turn/start.toolOutput bereitgestellte eigenständige Tool-Ausgabe. namespace kann null sein.
  • agentMessage{id, text, phase?} mit der kumulierten Antwort des Agenten. Falls vorhanden, verwendet phase die Übertragungswerte der Responses API (commentary, final_answer).
  • plan{id, text} mit dem vorgeschlagenen Plantext im Planmodus. Behandeln Sie das abschließende plan-Item aus item/completed als maßgeblich.
  • reasoning{id, summary, content}, wobei summary gestreamte Reasoning-Zusammenfassungen und content unbearbeitete Reasoning-Blöcke enthält.
  • commandExecution{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.
  • fileChange{id, changes, status} zur Beschreibung vorgeschlagener Änderungen; changes listet {path, kind, diff} auf.
  • mcpToolCall{id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Bei vertrauenswürdigen MCP-Apps kann appContext die Werte connectorId, linkId, resourceUri, appName, templateId und den stabilen Connector actionName enthalten. Bei älteren persistierten Items können neuere Metadaten fehlen. Verwenden Sie appContext.resourceUri anstelle des veralteten Werts mcpAppResourceUri auf oberster Ebene.
  • dynamicToolCall{id, tool, arguments, status, contentItems?, success?, durationMs?} für vom Client ausgeführte dynamische Tool-Aufrufe.
  • collabToolCall{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.
  • webSearch{id, query, action?} für vom Agenten ausgegebene Websuchanfragen.
  • imageView{id, path}, das ausgegeben wird, wenn der Agent das Tool zur Bildanzeige aufruft.
  • enteredReviewMode{id, review}, das beim Start des Reviewers gesendet wird.
  • exitedReviewMode{id, review}, das nach Abschluss des Reviewers ausgegeben wird.
  • contextCompaction{id}, das ausgegeben wird, wenn Codex den Konversationsverlauf komprimiert.

Für webSearch.action kann die Aktion type den Wert search (query?, queries?), openPage (url?) oder findInPage (url?, pattern?) haben.

App-server stuft die bisherige thread/compacted-Benachrichtigung als veraltet ein; verwenden Sie stattdessen das contextCompaction-Element.

Alle Elemente geben zwei gemeinsame Lebenszyklusereignisse aus:

  • item/started – gibt das vollständige item aus, wenn eine neue Arbeitseinheit beginnt; item.id stimmt mit dem von Deltas verwendeten itemId überein.
  • item/completed – sendet das endgültige item nach Abschluss der Arbeit; betrachten Sie dies als maßgeblichen Status.

Element-Deltas

  • item/agentMessage/delta – hängt gestreamten Text an die Agentennachricht an.
  • item/plan/delta – streamt vorgeschlagenen Plantext. Das endgültige plan-Element entspricht möglicherweise nicht exakt den verketteten Deltas.
  • item/reasoning/summaryTextDelta – streamt lesbare Reasoning-Zusammenfassungen; summaryIndex wird erhöht, wenn ein neuer Zusammenfassungsabschnitt beginnt.
  • item/reasoning/summaryPartAdded – markiert eine Grenze zwischen Abschnitten der Reasoning-Zusammenfassung.
  • item/reasoning/textDelta – streamt rohen Reasoning-Text (sofern vom Modell unterstützt).
  • item/commandExecution/outputDelta – streamt stdout/stderr für einen Befehl; hängen Sie die Deltas der Reihe nach an.
  • item/fileChange/outputDelta – veraltete Kompatibilitätsbenachrichtigung für die bisherige apply_patch-Textausgabe. Aktuelle app-server-Versionen geben sie nicht mehr aus; verwenden Sie stattdessen fileChange-Elemente und turn/diff/updated.

Fehler

Wenn ein Turn fehlschlägt, gibt der Server ein error-Ereignis mit { error: { message, codexErrorInfo?, additionalDetails? } } aus und beendet den Turn anschließend mit status: "failed". Wenn ein vorgelagerter HTTP-Status verfügbar ist, erscheint er in codexErrorInfo.httpStatusCode.

Zu den gängigen codexErrorInfo-Werten gehören:

  • ContextWindowExceeded
  • UsageLimitExceeded
  • HttpConnectionFailed (vorgelagerte 4xx-/5xx-Fehler)
  • ResponseStreamConnectionFailed
  • ResponseStreamDisconnected
  • ResponseTooManyFailedAttempts
  • BadRequest, Unauthorized, SandboxError, InternalServerError, Other

Wenn ein vorgelagerter HTTP-Status verfügbar ist, leitet der Server ihn in httpStatusCode für die entsprechende codexErrorInfo-Variante weiter.

Genehmigungen

Abhängig von den Codex-Einstellungen eines Benutzers können die Ausführung von Befehlen und Dateiänderungen eine Genehmigung erfordern. App-server sendet eine vom Server initiierte JSON-RPC-Anfrage an den Client, und der Client antwortet mit einer Entscheidungsnutzlast.

  • Entscheidungen zur Befehlsausführung: accept, acceptForSession, decline, cancel oder { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.

  • Entscheidungen zu Dateiänderungen: accept, acceptForSession, decline, cancel.

  • Anfragen enthalten threadId und turnId – verwenden Sie diese, um den UI-Status auf die aktive Unterhaltung zu begrenzen.

  • Der Server setzt die Arbeit fort oder lehnt sie ab und beendet das Element mit item/completed.

Genehmigungen zur Befehlsausführung

Reihenfolge der Nachrichten:

  1. item/started zeigt das ausstehende commandExecution-Element mit command, cwd und weiteren Feldern.
  2. item/commandExecution/requestApproval enthält itemId, threadId, turnId, optional reason, optional command, optional cwd, optional commandActions, optional proposedExecpolicyAmendment, optional networkApprovalContext und optional availableDecisions. Bei initialize.params.capabilities.experimentalApi = true kann die Nutzlast außerdem das experimentelle additionalPermissions enthalten, das den angeforderten Sandbox-Zugriff pro Befehl beschreibt. Alle Dateisystempfade innerhalb von additionalPermissions sind in der Übertragung absolut.
  3. Der Client antwortet mit einer der oben genannten Entscheidungen zur Genehmigung der Befehlsausführung.
  4. serverRequest/resolved bestätigt, dass die ausstehende Anfrage beantwortet oder gelöscht wurde.
  5. item/completed gibt das endgültige commandExecution-Element mit status: completed | failed | declined zurück.

Wenn networkApprovalContext vorhanden ist, betrifft die Abfrage den verwalteten Netzwerkzugriff (und keine allgemeine Genehmigung eines Shell-Befehls). Das aktuelle v2-Schema stellt das Ziel host und protocol bereit; Clients sollten eine netzwerkspezifische Abfrage darstellen und sich nicht darauf verlassen, dass command eine für den Benutzer aussagekräftige Vorschau des Shell-Befehls ist.

Codex gruppiert gleichzeitig auftretende Abfragen zur Netzwerkfreigabe nach Ziel (host, Protokoll und Port). App-server kann daher eine einzige Abfrage senden, die mehrere ausstehende Anfragen an dasselbe Ziel freigibt, während unterschiedliche Ports desselben Hosts getrennt behandelt werden.

Genehmigungen für Dateiänderungen

Reihenfolge der Nachrichten:

  1. item/started gibt ein fileChange-Element mit den vorgeschlagenen Werten changes und status: "inProgress" aus.
  2. item/fileChange/requestApproval enthält itemId, threadId, turnId, optional reason und optional grantRoot.
  3. Der Client antwortet mit einer der oben genannten Entscheidungen zur Genehmigung von Dateiänderungen.
  4. serverRequest/resolved bestätigt, dass die ausstehende Anfrage beantwortet oder gelöscht wurde.
  5. item/completed gibt das endgültige fileChange-Element mit status: completed | failed | declined zurück.

tool/requestUserInput

Wenn der Client auf item/tool/requestUserInput antwortet, gibt app-server serverRequest/resolved mit { threadId, requestId } aus. Wird die ausstehende Anfrage durch den Start, den Abschluss oder die Unterbrechung eines Turns gelöscht, bevor der Client antwortet, gibt der Server dieselbe Benachrichtigung für diese Bereinigung aus.

Die Anfrageparameter enthalten autoResolutionMs als ganzzahliges Zeitlimit in Millisekunden oder null. Wenn dieser Wert vorhanden ist, können Host-Clients die Abfrage nach diesem Intervall automatisch auflösen, falls der Benutzer nicht antwortet.

Berechtigungsanfragen

Das integrierte Tool request_permissions sendet item/permissions/requestApproval mit threadId, turnId, itemId, environmentId, cwd, optional reason sowie den angeforderten Netzwerk- oder Dateisystemberechtigungen. Antworten Sie mit permissions, das nur die gewährte Teilmenge enthält. Setzen Sie scope auf "session", um die Gewährung für spätere Turns derselben Sitzung beizubehalten; lassen Sie den Wert weg oder verwenden Sie "turn" für eine auf den Turn beschränkte Gewährung. Nicht angeforderte Berechtigungen werden ignoriert.

Elicitierungsanfragen von MCP-Servern

Ein MCP-Server kann einen Turn mit mcpServer/elicitation/request unterbrechen. Die Anfrage enthält threadId, ein optionales turnId, serverName und eine der folgenden Anfragestrukturen:

  • mode: "form" oder mode: "openai/form", mit message und requestedSchema.
  • mode: "url", mit message, url und elicitationId.

Antworten Sie mit action: "accept" und dem angeforderten content oder mit action: "decline" oder "cancel" und content: null. App-server gibt anschließend serverRequest/resolved aus. Um die Variante openai/form zu empfangen, aktivieren Sie sie mit initialize.params.capabilities.mcpServerOpenaiFormElicitation.

Dynamische Tool-Aufrufe (experimentell)

dynamicTools auf thread/start und der zugehörige Anfrage- oder Antwortablauf von item/tool/call sind experimentelle APIs.

Die Namen dynamischer Tools und Namespaces müssen den Namensvorgaben der Responses API entsprechen. Vermeiden Sie reservierte Namespace-Namen, die von integrierten Codex-Tools verwendet werden.

Wenn während eines Turns ein dynamisches Tool aufgerufen wird, gibt app-server Folgendes aus:

  1. item/started mit item.type = "dynamicToolCall", status = "inProgress" sowie tool und arguments.
  2. item/tool/call als Serveranfrage an den Client.
  3. Die Antwortnutzlast des Clients mit den zurückgegebenen Inhaltselementen.
  4. item/completed mit item.type = "dynamicToolCall", dem endgültigen status sowie allen zurückgegebenen Werten contentItems oder success.

Genehmigungen für MCP-Tool-Aufrufe (Apps)

Tool-Aufrufe von Apps (Connectors) können ebenfalls eine Genehmigung erfordern. Wenn ein App-Tool-Aufruf Nebenwirkungen hat, kann der Server mit tool/requestUserInput und Optionen wie Akzeptieren, Ablehnen und Abbrechen um eine Genehmigung bitten. Destruktive Tool-Annotationen lösen immer eine Genehmigungsabfrage aus, selbst wenn das Tool zugleich Hinweise auf weniger weitreichende Berechtigungen angibt. Wenn der Benutzer ablehnt oder abbricht, wird das zugehörige mcpToolCall-Element mit einem Fehler abgeschlossen, ohne das Tool auszuführen.

Skills

Rufen Sie einen Skill auf, indem Sie $<skill-name> in die Texteingabe aufnehmen. Fügen Sie ein skill-Eingabeelement hinzu (empfohlen), damit der Server die vollständigen Skill-Anweisungen einfügt, anstatt das Modell den Namen auflösen zu lassen.

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

Wenn Sie das skill-Element weglassen, analysiert das Modell dennoch die $<skill-name>-Markierung und versucht, den Skill zu finden, was die Latenz erhöhen kann.

Beispiel:

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

Verwenden Sie skills/list, um verfügbare Skills abzurufen (optional nach cwds eingeschränkt, mit forceReload). Sie können auch perCwdExtraUserRoots angeben, um zusätzliche absolute Pfade als user-Bereich für bestimmte cwd-Werte zu durchsuchen. App-server ignoriert Einträge, deren cwd nicht in cwds enthalten ist. skills/list kann ein zwischengespeichertes Ergebnis pro cwd wiederverwenden; setzen Sie forceReload: true, um die Daten vom Datenträger zu aktualisieren. Wenn vorhanden, liest der Server interface und dependencies aus 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": []
  }]
} }

Der Server gibt außerdem skills/changed-Benachrichtigungen aus, wenn sich überwachte lokale Skill-Dateien ändern. Behandeln Sie dies als Invalidierungssignal und führen Sie skills/list bei Bedarf erneut mit Ihren aktuellen Parametern aus.

So aktivieren oder deaktivieren Sie einen Skill anhand seines Pfads:

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

Apps (Connectors)

Verwenden Sie app/installed, um den neuesten festgeschriebenen Laufzeit-Snapshot der installierten Apps zu lesen. Jedes Ergebnis enthält die App id, runtimeName (oder null), den wirksamen enabled-Status und den callable-Status. Eine App kann nur aufgerufen werden, wenn sie durch die wirksame Konfiguration aktiviert ist und mindestens ein für das Modell sichtbares Tool den App- und Tool-Richtlinien entspricht.

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

Lassen Sie threadId weg, um anstelle der Konfiguration eines geladenen Threads die globale Konfiguration zu verwenden. Setzen Sie forceRefresh: true, um den Laufzeit-Snapshot des Connectors vor dem Lesen zu aktualisieren. Wenn eine globale oder Workspace-Richtlinie den App-Zugriff sperrt, kann eine erkannte App dennoch erscheinen, wobei enabled und callable auf false gesetzt sind.

Verwenden Sie app/list, um verfügbare Apps abzurufen. In CLI/TUI ist /apps die benutzerseitige Auswahloberfläche; rufen Sie in benutzerdefinierten Clients app/list direkt auf. Jeder Eintrag enthält sowohl isAccessible (für den Benutzer verfügbar) als auch isEnabled (in config.toml aktiviert), damit Clients zwischen Installation/Zugriff und lokalem Aktivierungsstatus unterscheiden können. App-Einträge können außerdem die optionalen Felder branding, appMetadata und labels enthalten.

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

Wenn Sie threadId angeben, verwendet das Feature-Gating der App (features.apps) den Konfigurations-Snapshot dieses Threads. Wird der Wert weggelassen, verwendet app-server die neueste globale Konfiguration.

app/list wird zurückgegeben, nachdem sowohl zugängliche Apps als auch Verzeichnis-Apps geladen wurden. Setzen Sie forceRefetch: true, um App-Caches zu umgehen und aktuelle Daten abzurufen. Cache-Einträge werden nur ersetzt, wenn die Aktualisierung erfolgreich ist.

Der Server gibt außerdem app/list/updated-Benachrichtigungen aus, wenn eine der beiden Quellen (zugängliche Apps oder Verzeichnis-Apps) vollständig geladen wurde. Jede Benachrichtigung enthält die aktuelle zusammengeführte App-Liste.

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

Verwenden Sie app/read, wenn Sie die App-IDs bereits kennen und App-Metadaten anstelle des installierten Laufzeitstatus benötigen. Übergeben Sie höchstens 100 appIds. Der Server behält nur das jeweils erste Vorkommen einer wiederholten ID bei und bewahrt diese Reihenfolge sowohl in apps als auch in missingAppIds. Unbekannte oder unzugängliche Apps werden in missingAppIds zurückgegeben, ohne dass die gesamte Anfrage fehlschlägt.

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

Setzen Sie includeTools: true, um ausschließlich zur Anzeige bestimmte öffentliche Tool-Zusammenfassungen anzufordern. Die Metadatenantwort enthält weder den Laufzeitstatus installierter Apps noch autorisiert sie einen Tool-Aufruf; verwenden Sie app/installed, um den wirksamen enabled- und callable-Status zu prüfen.

Rufen Sie eine App auf, indem Sie $<app-slug> in die Texteingabe einfügen und ein mention-Eingabeelement mit dem app://<id>-Pfad hinzufügen (empfohlen).

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

Beispiele für Konfigurations-RPCs für App-Einstellungen

Verwenden Sie config/read, config/value/write und config/batchWrite, um App-Steuerelemente in config.toml zu prüfen oder zu aktualisieren.

Lesen Sie die wirksame Struktur der App-Konfiguration (einschließlich _default und Überschreibungen pro Tool):

{ "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 legt den Reviewer für alle Apps fest, sofern dieser Wert nicht für eine einzelne App überschrieben wird. Wenn beide Angaben fehlen, übernimmt die App den übergeordneten Wert approvals_reviewer. apps._default.default_tools_approval_mode legt den Rückfall-Genehmigungsmodus für Tools ohne Überschreibung pro App oder pro Tool fest. Verwaltete Anforderungen an den Genehmigungsmodus haben Vorrang vor den Genehmigungsmoduseinstellungen der Tools.

Eine einzelne App-Einstellung aktualisieren:

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

Mehrere App-Änderungen atomar anwenden:

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

Konfiguration externer Agenten erkennen und importieren

Verwenden Sie externalAgentConfig/detect, um migrierbare Artefakte externer Agenten zu erkennen, und übergeben Sie die ausgewählten Einträge anschließend an externalAgentConfig/import.

Erkennungsbeispiel:

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

Importbeispiel:

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

Der optionale Importparameter source auf oberster Ebene bezeichnet das Produkt, das die ausgewählten Migrationselemente erzeugt hat.

Der Server gibt externalAgentConfig/import/progress aus, sobald einzelne Elementtypen abgeschlossen sind, und externalAgentConfig/import/completed, nachdem alle synchronen und im Hintergrund ausgeführten Importe abgeschlossen sind. Diese Benachrichtigungen enthalten dasselbe importId wie die Antwort sowie itemTypeResults mit successes und failures pro Typ. Der Abschluss kann unmittelbar nach der Antwort oder erst nach Abschluss entfernter Hintergrundimporte eintreten.

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

Frühere abgeschlossene Importe lesen:

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

Unterstützte itemType-Werte sind AGENTS_MD, CONFIG, SKILLS, PLUGINS, MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS und SESSIONS. Bei PLUGINS-Elementen listet details.plugins jedes marketplaceName und das pluginNames auf, dessen Migration Codex versuchen kann. Die Erkennung gibt nur Elemente zurück, bei denen noch Arbeit aussteht. Codex überspringt beispielsweise die AGENTS-Migration, wenn AGENTS.md bereits vorhanden und nicht leer ist; Skill-Importe überschreiben keine vorhandenen Skill-Verzeichnisse.

Beim Erkennen von Plugins aus .claude/settings.json liest Codex die konfigurierten Marketplace-Quellen aus extraKnownMarketplaces. Wenn enabledPlugins Plugins aus claude-plugins-official enthält, die Marketplace-Quelle jedoch fehlt, leitet Codex anthropics/claude-plugins-official als Quelle ab.

Auth-Endpunkte

Die JSON-RPC-Oberfläche für Authentifizierung und Konten stellt Anfrage-/Antwortmethoden sowie vom Server initiierte Benachrichtigungen bereit (kein id). Verwenden Sie diese, um den Authentifizierungsstatus zu ermitteln, Anmeldungen zu starten oder abzubrechen, sich abzumelden, ChatGPT-Ratenlimits zu prüfen und Workspace-Eigentümer über aufgebrauchte Guthaben oder erreichte Nutzungslimits zu benachrichtigen.

Authentifizierungsmodi

Codex unterstützt die folgenden Authentifizierungsmodi. account/updated.authMode zeigt den aktiven Modus an und enthält, sofern verfügbar, das aktuelle ChatGPT-planType. account/read meldet außerdem Konto- und Tarifdetails.

  • API key (apikey) – der Aufrufer stellt mit type: "apiKey" einen OpenAI API key bereit, den Codex für API-Anfragen speichert.
  • Von ChatGPT verwaltet (chatgpt) – Codex verwaltet den ChatGPT-OAuth-Ablauf, speichert Tokens dauerhaft und aktualisiert sie automatisch. Beginnen Sie mit type: "chatgpt" für den Browserablauf oder mit type: "chatgptDeviceCode" für den Gerätecode-Ablauf.
  • Externe ChatGPT-Tokens (chatgptAuthTokens) – experimentell und für Host-Apps vorgesehen, die den Authentifizierungslebenszyklus des Benutzers für ChatGPT bereits selbst verwalten. Die Host-App stellt accessToken, chatgptAccountId und optional chatgptPlanType direkt bereit und muss das Token auf Anforderung aktualisieren.
  • Amazon Bedrockaccount/read meldet Bedrock-Konten als type: "amazonBedrock" und gibt an, ob die Anmeldedaten von einem durch Codex verwalteten Bedrock API key (credentialSource: "codexManaged") oder aus der externen AWS-Anmeldedatenkette (credentialSource: "awsManaged") stammen. account/updated.authMode verwendet bedrockApiKey für durch Codex verwaltete Bedrock API keys.

API-Übersicht

  • account/read – aktuelle Kontoinformationen abrufen; Tokens optional aktualisieren.
  • account/login/start – Anmeldung beginnen (apiKey, chatgpt, chatgptDeviceCode oder experimentell chatgptAuthTokens).
  • account/login/completed (Benachrichtigung) – wird ausgegeben, wenn ein Anmeldeversuch abgeschlossen ist (erfolgreich oder mit Fehler).
  • account/login/cancel – eine ausstehende, verwaltete ChatGPT-Anmeldung anhand von loginId abbrechen.
  • account/logout – abmelden; löst account/updated aus.
  • account/updated (Benachrichtigung) – wird bei jeder Änderung des Authentifizierungsmodus ausgegeben (authMode: apikey, chatgpt, chatgptAuthTokens, agentIdentity, personalAccessToken, bedrockApiKey oder null) und enthält, sofern verfügbar, planType.
  • account/chatgptAuthTokens/refresh (Serveranfrage) – nach einem Autorisierungsfehler neue extern verwaltete ChatGPT-Tokens anfordern.
  • account/rateLimits/read – ChatGPT-Ratenlimits abrufen.
  • account/rateLimits/updated (Benachrichtigung) – wird bei jeder Änderung der ChatGPT-Ratenlimits eines Benutzers ausgegeben.
  • account/sendAddCreditsNudgeEmail – ChatGPT anweisen, einen Workspace-Eigentümer per E-Mail über aufgebrauchte Guthaben oder ein erreichtes Nutzungslimit zu informieren.
  • account/rateLimitResetCredit/consume – eine verdiente Zurücksetzung des Ratenlimits unter Verwendung eines vom Aufrufer bereitgestellten idempotencyKey-Werts einlösen.
  • account/usage/read – Zusammenfassungen der Token-Aktivität und Tagesintervalle für das ChatGPT-Konto abrufen.
  • account/workspaceMessages/read – aktive Workspace-Nachrichten einschließlich Benachrichtigungsüberschriften abrufen, sofern verfügbar.
  • mcpServer/oauthLogin/completed (Benachrichtigung) – wird nach Abschluss eines mcpServer/oauth/login-Ablaufs ausgegeben; die Nutzlast enthält { name, threadId, success, error? }. threadId kann bei App-bezogenen oder Plugin-OAuth-Abläufen den Wert null haben.
  • mcpServer/startupStatus/updated (Benachrichtigung) – wird ausgegeben, wenn sich der Startstatus eines konfigurierten MCP-Servers ändert; die Nutzlast enthält { threadId, name, status, error, failureReason }. Bei einem App-bezogenen Start ist threadId gleich null. Wenn der Start fehlschlägt, bedeutet failureReason: "reauthenticationRequired", dass gespeicherte OAuth-Anmeldedaten abgelaufen sind und nicht aktualisiert werden konnten. Der Client sollte daher anbieten, die Verbindung zum Server erneut herzustellen.

1) Authentifizierungsstatus prüfen

Anfrage:

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

Antwortbeispiele:

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

Hinweise zu den Feldern:

  • refreshToken (boolescher Wert): Setzen Sie true, um im verwalteten ChatGPT-Modus eine Token-Aktualisierung zu erzwingen. Im Modus für externe Tokens (chatgptAuthTokens) ignoriert app-server dieses Flag.
  • email ist null, wenn das ChatGPT-Konto keine E-Mail-Adresse hat.
  • requiresOpenaiAuth gibt den aktiven Anbieter wieder; bei false kann Codex ohne OpenAI-Anmeldedaten ausgeführt werden.
  • Amazon Bedrock meldet credentialSource: "codexManaged", wenn ein von Codex verwalteter Bedrock API key verwendet wird. Für den externen AWS-Anmeldedatenpfad meldet es credentialSource: "awsManaged". Dies identifiziert die ausgewählte Quelle der Anmeldedaten; es bestätigt nicht, dass die AWS-Anmeldedatenkette Anmeldedaten auflösen kann.

2) Mit einem API key anmelden

  1. Senden Sie:
   {
     "method": "account/login/start",
     "id": 2,
     "params": { "type": "apiKey", "apiKey": "sk-..." }
   }
  1. Erwartete Antwort:
   { "id": 2, "result": { "type": "apiKey" } }
  1. Benachrichtigungen:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "apikey", "planType": null }
   }

3) Mit ChatGPT anmelden (Browserablauf)

  1. Starten Sie den Vorgang:
   {
     "method": "account/login/start",
     "id": 3,
     "params": {
       "type": "chatgpt",
       "useHostedLoginSuccessPage": true,
       "appBrand": "chatgpt"
     }
   }

Standardmäßig leitet ein erfolgreicher Browser-Callback zu einer lokalen Erfolgsseite weiter. Setzen Sie useHostedLoginSuccessPage: true, um die gehostete Erfolgsseite zu verwenden, wenn keine Organisationseinrichtung erforderlich ist. Bei aktivierter gehosteter Erfolgsseite kann appBrand den Wert "codex" oder "chatgpt" haben; fehlende Werte oder null verwenden standardmäßig "codex".

   {
     "id": 3,
     "result": {
       "type": "chatgpt",
       "loginId": "<uuid>",
       "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
     }
   }
  1. Öffnen Sie authUrl in einem Browser; app-server stellt den lokalen Callback bereit.
  2. Warten Sie auf Benachrichtigungen:
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3b) Mit ChatGPT anmelden (Gerätecode-Ablauf)

Verwenden Sie diesen Ablauf, wenn Ihr Client den Anmeldevorgang steuert oder ein Browser-Callback unzuverlässig ist.

  1. Starten Sie den Vorgang:
   {
     "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. Zeigen Sie dem Benutzer verificationUrl und userCode an; das Frontend steuert die UX.
  2. Warten Sie auf Benachrichtigungen:
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3c) Mit extern verwalteten ChatGPT-Tokens anmelden (chatgptAuthTokens)

Verwenden Sie diesen experimentellen Modus nur, wenn eine Host-Anwendung den Authentifizierungslebenszyklus des Benutzers für ChatGPT verwaltet und Tokens direkt bereitstellt. Clients müssen während initialize den Wert capabilities.experimentalApi = true setzen, bevor sie diesen Anmeldetyp verwenden.

  1. Senden Sie:
   {
     "method": "account/login/start",
     "id": 7,
     "params": {
       "type": "chatgptAuthTokens",
       "accessToken": "<jwt>",
       "chatgptAccountId": "org-123",
       "chatgptPlanType": "business"
     }
   }
  1. Erwartete Antwort:
   { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  1. Benachrichtigungen:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
   }

Wenn der Server ein 401 Unauthorized empfängt, kann er aktualisierte Tokens von der Host-App anfordern:

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

Nach einer erfolgreichen Aktualisierungsantwort wiederholt der Server die ursprüngliche Anfrage. Anfragen laufen nach etwa 10 Sekunden ab.

4) ChatGPT-Anmeldung abbrechen

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

5) Abmelden

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

6) Ratenlimits (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 }
  }
} }

Hinweise zu den Feldern:

  • rateLimits ist die abwärtskompatible Ansicht eines einzelnen Kontingents.
  • rateLimitsByLimitId (sofern vorhanden) ist die Ansicht mehrerer Kontingente, die nach dem abgerechneten limit_id (beispielsweise codex) indiziert ist.
  • limitId ist die Kennung des abgerechneten Kontingents.
  • limitName ist eine optionale, benutzerseitig sichtbare Bezeichnung des Kontingents.
  • usedPercent ist die aktuelle Nutzung innerhalb des Kontingentzeitraums.
  • windowDurationMins ist die Länge des Kontingentzeitraums.
  • resetsAt ist ein Unix-Zeitstempel (Sekunden) für die nächste Zurücksetzung.
  • planType ist enthalten, wenn der Server den einem Kontingent zugeordneten ChatGPT-Tarif zurückgibt.
  • credits ist enthalten, wenn der Server Details zum verbleibenden Workspace-Guthaben zurückgibt.
  • rateLimitReachedType bezeichnet den vom Server klassifizierten Limitstatus, wenn ein Limit erreicht wurde.
  • rateLimitResetCredits enthält die Anzahl der verfügbaren verdienten Zurücksetzungen, wenn der Dienst sie bereitstellt; andernfalls ist der Wert null.
  • rateLimitResetCredits.credits ist null, wenn nur die Anzahl bekannt ist. Ein leeres Array bedeutet, dass der Dienst Details abgerufen und keine verfügbaren Guthaben zurückgegeben hat. Der Dienst kann die Anzahl der Detailzeilen begrenzen; daher ist availableCount maßgeblich.
  • Jede Detailzeile enthält ein undurchsichtiges id, resetType, status, grantedAt, expiresAt (kann null sein), title (kann null sein) und description (kann null sein).
  • Rufen Sie account/rateLimits/read ab, nachdem Sie eine Zurücksetzung eingelöst haben.

7) Token-Nutzung (ChatGPT)

Verwenden Sie account/usage/read, um Zusammenfassungsfelder zur ChatGPT-Token-Aktivität und optionale Tagesintervalle abzurufen.

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

Hinweise zu den Feldern:

  • summary-Werte können null sein, wenn der Dienst diese Kennzahl nicht zurückgegeben hat.
  • dailyUsageBuckets kann null sein; sofern vorhanden, enthält jedes Intervall startDate und tokens.
  • Der Endpunkt erfordert eine Authentifizierung, die durch Codex-Dienste gestützt wird. ChatGPT, externe ChatGPT-Tokens, Agentenidentität und die Authentifizierung mit einem persönlichen Zugriffstoken funktionieren; eine reine API-key- oder Bedrock-Authentifizierung nicht.

8) Verdiente Zurücksetzungen des Ratenlimits (ChatGPT)

Verwenden Sie account/rateLimitResetCredit/consume, um eine verdiente Zurücksetzung einzulösen.

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

Hinweise zu den Feldern:

  • idempotencyKey darf nicht leer sein. Verwenden Sie für jeden logischen Einlösungsversuch eine UUID und bei Wiederholungen desselben Versuchs erneut denselben Wert.
  • creditId ist optional. Wenn angegeben, muss der Wert eine nicht leere, undurchsichtige ID aus account/rateLimits/read sein. Wird er weggelassen, wählt der Dienst das nächste verfügbare Guthaben aus.
  • reset bedeutet, dass ein Guthaben eingelöst wurde.
  • alreadyRedeemed bedeutet, dass dieselbe Einlösung bereits zuvor abgeschlossen wurde. Behandeln Sie dies als idempotenten Erfolg und aktualisieren Sie die Kontolimits.
  • nothingToReset bedeutet, dass kein geeignetes Ratenlimit-Zeitfenster für eine Zurücksetzung vorhanden ist.
  • noCredit bedeutet, dass für das Konto keine verdienten Zurücksetzungsguthaben verfügbar sind.
  • Rufen Sie nach dem Einlösen einer Zurücksetzung account/rateLimits/read ab, anstatt aktualisierte Zeitfenster aus dieser Antwort abzuleiten.

9) Workspace-Eigentümer über ein Limit benachrichtigen

Verwenden Sie account/sendAddCreditsNudgeEmail, um ChatGPT anzuweisen, einen Workspace-Eigentümer per E-Mail zu benachrichtigen, wenn Guthaben aufgebraucht sind oder ein Nutzungslimit erreicht wurde.

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

Verwenden Sie creditType: "credits", wenn das Workspace-Guthaben aufgebraucht ist, oder creditType: "usage_limit", wenn das Nutzungslimit des Workspace erreicht wurde. Wenn der Eigentümer vor Kurzem bereits benachrichtigt wurde, lautet der Antwortstatus cooldown_active.

10) Workspace-Nachrichten (ChatGPT)

Verwenden Sie account/workspaceMessages/read, um aktive Nachrichten für den aktuellen Workspace einschließlich Benachrichtigungsüberschriften abzurufen, sofern verfügbar.

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