Deutsch

Codex App Server

Den vollständigen Dokumentationsindex finden Sie unter llms.txt. Markdown-Versionen der Dokumentationsseiten sind verfügbar, indem Sie .md an die Seiten-URL anhängen.

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

CLI-Terminaloberfläche verbinden

Im Remote-Modus der Terminaloberfläche können Sie app-server auf einem Computer 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 die Befehlszeile einzutragen:

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 ausschließlich für localhost oder eine über einen SSH-Port weitergeleitete 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:// ausschließlich für localhost oder eine über 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 die bidirektionale Kommunikation mithilfe von JSON-RPC-2.0-Nachrichten (wobei der "jsonrpc":"2.0"-Header bei der Übertragung weggelassen wird).

Unterstützte Transportarten:

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

Bei der Ausführung mit --listen ws://IP:PORT stellt derselbe Listener außerdem einfache 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 lassen während der Einführung derzeit standardmäßig nicht authentifizierte Verbindungen zu. Konfigurieren Sie daher die WebSocket-Authentifizierung, bevor Sie einen solchen 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-Tokens 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.

Ziehen Sie --ws-token-file der Übergabe unformatierter Bearer-Tokens über die Befehlszeile vor. Verwenden Sie --ws-token-sha256 nur, wenn der Client das unformatierte 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 die Warteschlange für eingehende Anfragen voll ist, lehnt der Server neue Anfragen mit dem JSON-RPC-Fehlercode -32001 und der Meldung "Server overloaded; retry later." ab. Clients sollten den Versuch mit einer exponentiell ansteigenden Verzögerung und zufälliger Streuung wiederholen.

Nachrichtenschema

Anfragen enthalten method, params und id:

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

Antworten geben den Wert 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-Paket generieren. Jede Ausgabe gilt spezifisch für die 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" } });

Grundlegende Bausteine

  • Thread: Ein Gespräch zwischen einem Benutzer und dem Codex-Agent. Threads enthalten Turns.
  • Turn: Eine einzelne Benutzeranfrage und die darauf folgende Arbeit des Agenten. Turns enthalten Elemente und streamen schrittweise Aktualisierungen.
  • Element: Eine Eingabe- oder Ausgabeeinheit (Benutzernachricht, Agent-Nachricht, 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 jede Anfrage ü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 abzuzweigen.
  • Turn beginnen: Rufen Sie turn/start mit dem Ziel-threadId und der Benutzereingabe auf. Optionale Felder überschreiben unter anderem Modell, Persönlichkeit, cwd und Sandbox-Richtlinie.
  • Aktiven Turn steuern: Rufen Sie turn/steer auf, um Benutzereingaben an den aktuell laufenden Turn anzuhängen, 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: Der Server gibt turn/completed mit dem endgültigen Status aus, wenn das Modell fertig ist oder nachdem eine Abbruchanforderung turn/interrupt erfolgt ist.

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 die folgenden Client-Funktionen:

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

Wichtig: Verwenden Sie clientInfo.name, um Ihren Client gegenüber der 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"]
    }
  }
}

Aktivierung der experimentellen API

Einige app-server-Methoden und -Felder sind absichtlich durch die Funktion experimentalApi geschützt.

  • Lassen Sie capabilities weg (oder setzen Sie experimentalApi auf false), um 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 ohne vorherige Aktivierung eine experimentelle Methode oder ein experimentelles Feld sendet, lehnt app-server dies mit folgender Meldung ab:

<descriptor> requires experimentalApi capability

API-Übersicht

  • thread/start – erstellt einen neuen Thread, gibt thread/started aus und abonniert automatisch Turn-/Elementereignisse für diesen Thread.
  • thread/resume – öffnet einen vorhandenen Thread anhand seiner ID erneut, sodass spätere turn/start-Aufrufe daran angehängt werden.
  • thread/fork – zweigt einen Thread durch Kopieren des gespeicherten Verlaufs in eine neue Thread-ID ab. Übergeben Sie lastTurnId, um den Verlauf bis einschließlich dieses Turns zu kopieren und spätere Turns wegzulassen, 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; setzen Sie includeTurns, um den vollständigen Turn-Verlauf zurückzugeben. Zurückgegebene thread-Objekte enthalten den Laufzeitwert 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 den Laufzeitwert status.
  • thread/turns/list – experimentell; durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen. itemsView steuert, ob Turn-Elemente weggelassen, zusammengefasst oder vollständig geladen werden.
  • thread/items/list – experimentell; durchläuft gespeicherte Thread-Elemente seitenweise und kann optional auf einen turnId beschränkt werden. Der aktive Thread-Speicher muss die Elementpaginierung unterstützen.
  • thread/loaded/list – listet die derzeit im Arbeitsspeicher geladenen Thread-IDs auf.
  • thread/name/set – legt den benutzerseitig sichtbaren Namen eines Threads für einen geladenen Thread oder einen gespeicherten Rollout fest oder aktualisiert ihn; gibt thread/name/updated aus.
  • thread/goal/set – legt das Ziel für einen Thread 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 Metadaten eines SQLite-basierten gespeicherten Threads, einschließlich der gespeicherten Werte gitInfo und isPinned.
  • thread/archive – verschiebt die Protokolldatei eines Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfolger-Threads zu archivieren, sofern sie noch nicht archiviert sind; gibt bei Erfolg {} zurück und für jeden archivierten Thread thread/archived aus.
  • thread/delete – löscht einen gespeicherten aktiven oder archivierten Thread und alle erzeugten Nachfolger-Threads dauerhaft; gibt bei Erfolg {} zurück und für jeden gelöschten Thread thread/deleted aus.
  • thread/unsubscribe – beendet das Abonnement dieser Verbindung für Turn-/Elementereignisse des Threads. Wenn dies der letzte Abonnent war, entlädt der Server den Thread nach einer Inaktivitätsfrist ohne Abonnenten und gibt thread/closed aus.
  • thread/unarchive – stellt einen archivierten Thread-Rollout im Verzeichnis der aktiven Sitzungen wieder her; gibt den wiederhergestellten thread zurück und thread/unarchived aus.
  • thread/status/changed – Benachrichtigung, die ausgegeben wird, wenn sich der Laufzeitwert status eines geladenen Threads ändert.
  • thread/compact/start – löst die Komprimierung des Gesprächsverlaufs 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 die Sandbox-Richtlinie des Threads nicht.
  • 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 des app-server-Werts processId (experimentell; erfordert capabilities.experimentalApi).
  • thread/rollback – veraltet; entfernt die letzten N Turns aus dem In-Memory-Kontext und speichert eine Rollback-Markierung; gibt den aktualisierten thread zurück.
  • turn/start – fügt einem Thread Benutzereingaben hinzu und startet die Codex-Generierung; antwortet mit dem anfänglichen turn und streamt Ereignisse. Für collaborationMode bedeutet settings.developer_instructions: null „integrierte Anweisungen für den ausgewählten Modus verwenden“.
  • thread/inject_items – hängt unformatierte Responses API-Elemente an den für das Modell sichtbaren Verlauf eines geladenen Threads an, ohne einen Benutzer-Turn zu starten.
  • turn/steer – hängt Benutzereingaben an den aktiven, laufenden Turn eines Threads an; gibt den akzeptierten turnId zurück.
  • turn/interrupt – fordert den Abbruch eines laufenden 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 Elemente enteredReviewMode und exitedReviewMode aus.
  • command/exec – führt einen einzelnen Befehl in der Server-Sandbox aus, ohne einen Thread oder Turn zu starten.
  • command/exec/write – schreibt stdin-Bytes in eine laufende command/exec-Sitzung oder schließt stdin.
  • command/exec/resize – passt die Größe einer laufenden PTY-basierten command/exec-Sitzung an.
  • 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 – passt die Größe einer laufenden PTY-basierten Prozesssitzung an (experimentell).
  • process/kill – beendet eine laufende Prozesssitzung (experimentell).
  • process/outputDelta und process/exited (Benachrichtigungen) – werden für die gestreamte Prozessausgabe und den Prozessbeendigungsstatus ausgegeben (experimentell).
  • model/list – listet verfügbare Modelle auf (setzen Sie includeHidden: true, um Einträge mit hidden: true einzubeziehen), einschließlich Aufwandoptionen, 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 Funktionsschlü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 die Information auf, ob die wirksamen Anforderungen sie zulassen, einschließlich Cursor-Paginierung.
  • collaborationMode/list – listet Voreinstellungen für den Kollaborationsmodus 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 speichern.
  • 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 speichert 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-Zustände auf, einschließlich Metadaten zu Installations-/Authentifizierungsrichtlinien, Fehlern beim Laden von Marktplätzen, IDs hervorgehobener Plugins sowie Metadaten lokaler, Git-, Paketregistrierungs- oder Remote-Plugin-Quellen. Zusammenfassungen können Remote-version, lokale localVersion, strukturierte Symbole für helle/dunkle Designs und installPolicySource enthalten, das für aktuelle 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 Plugin anhand seines Marktplatzpfads oder anhand des Namens des Remote-Marktplatzes und des Plugin-Namens, einschließlich gebündelter Skills, Apps, MCP-Servernamen und eines Remote-Plugin-Werts shareUrl, wenn der Remote-Katalog einen bereitstellt. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.
  • plugin/install – in Entwicklung; installiert ein Plugin aus einem Marktplatzpfad oder einem Remote-Marktplatznamen. 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 von Remote-Marktplatz, Plugin-ID und Skill-Name.
  • app/installed – liest den Laufzeitstatus installierter Apps, einschließlich des effektiven Aktivierungs- und Aufrufstatus jeder App.
  • app/list – listet verfügbare Apps (Connectors) einschließlich Paginierung sowie Metadaten zu Zugänglichkeit und Aktivierung 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 nach Abschluss mcpServer/oauthLogin/completed aus.
  • tool/requestUserInput – stellt dem Benutzer für einen Tool-Aufruf ein bis drei kurze Fragen (experimentell); Fragen können isOther für eine Freitextoption festlegen.
  • mcpServer/elicitation/request (Serveranfrage) – fordert den Client zu strukturierten Formulareingaben oder zur Bestätigung eines von einem MCP-Server angeforderten URL-Ablaufs auf.
  • item/permissions/requestApproval (Serveranfrage) – fordert den Client auf, eine Teilmenge der vom integrierten Tool request_permissions angeforderten Netzwerk- oder Dateisystemberechtigungen zu gewähren.
  • 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 Authentifizierungsstatus auf (Paginierung mit Cursor und Limit). Verwenden Sie detail: "full" für vollständige Daten oder detail: "toolsAndAuthOnly", um Ressourcen wegzulassen.
  • 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; gibt schnell eine Antwort zurück und später windowsSandbox/setupCompleted aus.
  • feedback/upload – übermittelt einen Feedbackbericht (Klassifizierung und optional Grund/Protokolle und Gesprächs-ID sowie optionale extraLogFiles-Anhänge).
  • config/read – ruft die wirksame Konfiguration auf dem Datenträger ab, nachdem die Konfigurationsebenen aufgelöst wurden.
  • 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 Basisverzeichnis).
  • externalAgentConfig/import – wendet ausgewählte Migrationselemente externer Agenten an, indem explizite migrationItems mit cwd (null für das Basisverzeichnis) übergeben werden. Unterstützte Elementtypen umfassen Konfiguration, Skills, AGENTS.md, Plugins, MCP-Serverkonfiguration, Subagenten, Hooks, Befehle und Sitzungen; bei nicht leeren Importen werden während der Verarbeitung externalAgentConfig/import/progress und externalAgentConfig/import/completed ausgegeben. Plugin- und Sitzungsimporte können asynchron abgeschlossen werden.
  • config/value/write – schreibt einen einzelnen Konfigurationsschlüssel/-wert in die config.toml-Datei des Benutzers auf dem Datenträger.
  • config/batchWrite – wendet Konfigurationsänderungen atomar auf die config.toml-Datei des Benutzers auf dem Datenträger an.
  • configRequirements/read – ruft Anforderungen aus requirements.toml und/oder MDM ab, einschließlich der exakten verwalteten Konfiguration, Zulassungslisten, angehefteten featureRequirements und Anforderungen an Datenresidenz/Netzwerk (oder null, wenn Sie 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 Vorgänge für absolute Dateisystempfade aus.

Plugin-Zusammenfassungen enthalten eine source-Union. Lokale Plugins geben { "type": "local", "path": ... } zurück, Git-basierte Marktplatzeinträge { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }, Paketregistrierungseinträge { "type": "npm", "package": ..., "version": ..., "registry": ... } und Remote-Katalogeinträge { "type": "remote" }. Bei Einträgen, die nur im Remote-Katalog vorhanden sind, 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 Modell oder Persönlichkeit 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 Aufwandoptionen für das Modell.
  • defaultReasoningEffort – empfohlener Standardaufwand für Clients.
  • upgrade – optionale ID des empfohlenen Upgrade-Modells für Migrationshinweise in Clients.
  • upgradeInfo – optionale Upgrade-Metadaten für Migrationshinweise in Clients.
  • hidden – gibt an, ob das Modell in der standardmäßigen Auswahlliste ausgeblendet ist.
  • inputModalities – unterstützte Eingabetypen für das Modell (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 sie auf Clientseite anhand von hidden filtern möchten.

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

Experimentelle Funktionen 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. Falls vorhanden, handelt es sich um einen kanonischen file:-URI, der 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 einzubeziehen.
  • thread/turns/list ist experimentell und durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen. Verwenden Sie itemsView, um festzulegen, ob Turn-Elemente weggelassen, zusammengefasst oder vollständig geladen werden.
  • thread/items/list ist experimentell und durchläuft gespeicherte Thread-Elemente seitenweise, optional auf einen Turn beschränkt.
  • thread/list unterstützt Cursor-Paginierung sowie die Filter modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm und die experimentellen Filter parentThreadId oder ancestorThreadId.
  • thread/loaded/list gibt die derzeit im Arbeitsspeicher befindlichen Thread-IDs zurück.
  • thread/archive verschiebt das gespeicherte JSONL-Protokoll des Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfolger-Threads zu archivieren, sofern sie noch nicht archiviert sind.
  • thread/delete löscht einen gespeicherten aktiven oder archivierten Thread und seine erzeugten Nachfolger-Threads dauerhaft.
  • thread/metadata/update aktualisiert gespeicherte Thread-Metadaten, einschließlich der gespeicherten Werte gitInfo und isPinned.
  • thread/unsubscribe beendet das Abonnement der aktuellen Verbindung für einen geladenen Thread und kann nach einer Inaktivitätsfrist 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 In-Memory-Kontext und zeichnet eine Rollback-Markierung im gespeicherten JSONL-Protokoll des Threads auf.
  • thread/inject_items hängt unformatierte Responses API-Elemente an den für das Modell sichtbaren Verlauf eines geladenen Threads an, 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, auch bei Remote- Umgebungen.

Experimentelle Clients können historyMode für thread/start auf "legacy" (Standard) 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, Turn-Paginierung und Fortsetzung schlagen kontrolliert fehl, bis der paginierte Verlauf unterstützt wird.

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

thread.sessionId identifiziert das Wurzelelement der aktuellen Live-Sitzungsstruktur. Root-Threads verwenden ihre eigene Thread-ID als Sitzungs-ID; abgezweigte Threads behalten die Sitzungs-ID des Root-Threads, aus dem sie hervorgegangen sind. Clients sollten die Sitzungs-ID aus thread.sessionId lesen, statt sie aus der Thread-ID abzuleiten.

Um eine gespeicherte Sitzung fortzusetzen, rufen Sie thread/resume mit dem zuvor aufgezeichneten thread.id auf. Die Antwortstruktur entspricht thread/start. Sie können außerdem dieselben Konfigurationsüberschreibungen übergeben, die von thread/start unterstützt werden, 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, wenn 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 in thread/start ist ein experimentelles Feld (erfordert capabilities.experimentalApi = true). Codex speichert 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 als dem im Rollout aufgezeichneten fortsetzen, 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 gespeicherten 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 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 dem thread.id auf. Dadurch wird eine neue Thread-ID erstellt und dafür eine thread/started-Benachrichtigung 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 der Fork eine Unterbrechungsmarkierung auf, anstatt einen nicht markierten unvollständigen Turn beizubehalten.

Übergeben Sie ephemeral: true, um einen In-Memory-Fork zu erstellen, ohne ihn den Listen gespeicherter Threads 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 Forks paginierter Threads erfordern außerdem excludeTurns: true. Dieses Feld ist experimentell und erfordert capabilities.experimentalApi = true.

Wenn ein benutzerseitig sichtbarer Thread-Titel festgelegt wurde, fügt app-server thread.name in die 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 den Laufzeitwert 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 es, 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 diesen 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 Standard, wenn der Wert 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 gespeicherte 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 zu durchlaufen. Der aktive Thread-Speicher muss die Elementpaginierung unterstützen; andernfalls gibt der Server einen Fehler wegen einer nicht unterstützten Methode zurück.

Threads auflisten (mit Paginierung und Filtern)

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

  • cursor – undurchsichtige Zeichenfolge 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; nicht festgelegt, null oder ein leeres Array schließt alle Anbieter ein.
  • 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 mit dem entsprechenden gespeicherten Anheftungsstatus zurückgegeben. 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 Textfragment 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 zu aktualisieren, ohne den Thread fortzusetzen. Setzen Sie isPinned, um den Thread anzuheften oder zu lösen, oder aktualisieren Sie gitInfo, um gespeicherte Git-Metadaten zu ändern. Weggelassene 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, sobald sich der Laufzeitstatus eines geladenen Threads ändert. Die Nutzlast enthält threadId und den neuen status.

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

Geladene Threads auflisten

thread/loaded/list gibt die derzeit im Arbeitsspeicher geladenen Thread-IDs 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 ist einer der folgenden:

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

Wenn dies der letzte Abonnent war, lässt der Server den Thread geladen, bis er 30 Minuten lang weder Abonnenten noch Thread-Aktivität aufweist. Nach Ablauf der Frist 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 gespeicherte Thread-Protokoll (als JSONL-Datei auf dem Datenträger gespeichert) in das Verzeichnis der archivierten Sitzungen zu verschieben. Beim Archivieren eines Threads wird außerdem versucht, erzeugte Nachfolger-Threads zu archivieren, sofern sie 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 in zukünftigen Aufrufen von thread/list nur, wenn Sie archived: true übergeben. Der Server sendet für jeden tatsächlich archivierten Thread genau eine thread/archived-Benachrichtigung. Wenn ein erzeugter Nachfolger nicht archiviert werden kann, kann die Anfrage dennoch erfolgreich sein, ohne dass für diesen Nachfolger eine Archivierungsbenachrichtigung gesendet wird.

Thread löschen

Verwenden Sie thread/delete, um einen gespeicherten aktiven oder archivierten Thread und die daraus erzeugten Nachfolger-Threads dauerhaft zu löschen. Der Server entfernt vorhandene Rollout-Dateien und zugehörige Metadaten, bevor er den Erfolg zurückgibt. Fehlende Rollout-Dateien werden als bereits gelöscht behandelt. 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" } }

Thread dearchivieren

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 meldet den Fortschritt als standardmäßige turn/*- und item/*-Benachrichtigungen auf demselben threadId, 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 in einem 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 vollem Zugriff ausgeführt und übernimmt nicht die Sandbox-Richtlinie des Threads. 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 für diesen Turn ausgeführt und seine formatierte Ausgabe in den Nachrichtenstream des Turns eingefügt. Wenn der Thread inaktiv ist, startet app-server einen eigenständigen Turn für den Shell-Befehl.

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

Hintergrundterminals bereinigen

Verwenden Sie thread/backgroundTerminals/clean, um alle ausgeführten 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 ausgeführte Hintergrundterminals eines geladenen Threads zu prüfen. Die Anfrage unterstützt die standardmäßige Paginierung mit cursor und limit, und das zurückgegebene 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 speicherinternen Kontext und speichert eine Rollback-Markierung im Rollout-Protokoll. Das zurückgegebene thread enthält nach dem Rollback das ausgefüllte turns.

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

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 angegeben, werden diese Einstellungen zu den Standardwerten 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; bei 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“, statt die Modusanweisungen zu löschen.

Sandbox-Lesezugriff (ReadOnlyAccess)

sandboxPolicy unterstützt explizite Steuerelemente 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 ergänzt includePlatformDefaults: true für Sitzungen mit eingeschränktem Lesezugriff eine kuratierte, plattformübliche Seatbelt-Richtlinie. Dies verbessert die Werkzeugkompatibilität, ohne pauschal den Zugriff auf das gesamte /System zu erlauben.

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

Elemente in einen Thread einfügen

Verwenden Sie thread/inject_items, um vorgefertigte 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 einbezogen.

{ "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; es muss mit der ID des aktiven Turns übereinstimmen.
  • Die Anfrage schlägt fehl, wenn im Thread kein Turn aktiv ist.
  • turn/steer sendet keine neue turn/started-Benachrichtigung.
  • 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 (einen bestimmten Commit prüfen)
  • 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 abzuspalten.

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 abgetrenntes Review "delivery": "detached". Die Antwort hat dieselbe Struktur, aber reviewThreadId ist die ID des neuen Review-Threads (und unterscheidet sich vom ursprünglichen threadId). Der Server sendet außerdem eine thread/started-Benachrichtigung für diesen neuen Thread, bevor der Review-Turn gestreamt wird.

Codex streamt zunächst die übliche turn/started-Benachrichtigung und danach 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, sendet der Server item/started und item/completed mit einem exitedReviewMode-Element, 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 Codex-Sandbox ausgeführt. Verwenden Sie sie nur, wenn Ihr Client bewusst eine lokale Prozesssteuerung ohne Sandbox bereitstellt.

Starten Sie einen Prozess mit process/spawn und geben Sie ein processHandle an. Verwenden Sie diesen Handle anschließend für Anfragen zu stdin, Größenänderungen und Beendigung. 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 PTY-Größenänderungsereignisse und process/kill, um einen laufenden Prozess zu beenden.

Befehlsausführung

command/exec führt einen einzelnen Befehl (argv-Array) innerhalb 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 aus 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 ist, 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 aufrufen möchten.
  • Setzen Sie streamStdoutStderr: true, um während der Ausführung des Befehls command/exec/outputDelta-Benachrichtigungen zu erhalten.

Administratoranforderungen lesen (configRequirements/read)

Verwenden Sie configRequirements/read, um die effektiven 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 den unterstützten Schlüsseln und Werten finden Sie in der Dokumentation zu requirements.toml.

Windows-Sandbox einrichten (windowsSandbox/setupStart)

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

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

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

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

Modi:

  • elevated – den Windows-Sandbox-Einrichtungspfad mit erhöhten Rechten ausführen.
  • unelevated – den älteren Einrichtungs-/Vorprüfungspfad ausführen.

Dateisystem

Die v2-Dateisystem-APIs arbeiten mit absoluten Pfaden. Verwenden Sie fs/watch, wenn ein Client den UI-Zustand ungültig machen muss, nachdem sich eine Datei oder ein Verzeichnis geändert hat.

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

Das Überwachen einer Datei sendet fs/changed für diesen Dateipfad, einschließlich Aktualisierungen, die durch Ersetzungs- oder Umbenennungsvorgänge ausgelöst werden.

Ereignisse

Ereignisbenachrichtigungen sind der vom Server initiierte Stream für Thread-Lebenszyklen, Turn-Lebenszyklen und die darin enthaltenen Elemente. Nachdem Sie einen Thread gestartet oder fortgesetzt haben, lesen Sie 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 thread/*-, turn/*-, item/*- und zugehörigen v2-Benachrichtigungen.
  • Gilt nicht für Anfragen, Antworten oder Fehler.

Ereignisse der unscharfen Dateisuche (experimentell)

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

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

Warnereignisse

  • configWarning{ summary, details?, path?, range? } bei behebbaren Konfigurations- oder Initialisierungsproblemen.
  • warning{ threadId?, message } bei nicht schwerwiegenden Laufzeitwarnungen.

Ereignisse der Windows-Sandbox-Einrichtung

  • windowsSandbox/setupCompleted{ mode, success, error }, das nach Abschluss einer windowsSandbox/setupStart-Anfrage gesendet 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; Fehler enthalten { error: { message, codexErrorInfo?, additionalDetails? } }.
  • turn/diff/updated{ threadId, turnId, diff } mit dem neuesten aggregierten Unified Diff über alle Dateiänderungen des Turns hinweg.
  • turn/plan/updated{ turnId, explanation?, plan }, sobald der Agent seinen Plan mitteilt oder ändert; jeder plan-Eintrag ist { step, status } mit status in pending, inProgress oder completed.
  • hook/started und hook/completed{ threadId, turnId?, run }, wenn ein Lebenszyklus-Hook startet und wenn die Zusammenfassung seiner endgültigen Ausführung verfügbar ist.
  • model/safetyBuffering/updated{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }, wenn eine Antwort in eine vorübergehende Sicherheitspufferung übergeht.
  • 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 selbst 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).
  • agentMessage{id, text, phase?} mit der kumulierten Antwort des Agents. Falls vorhanden, verwendet phase die Wire-Werte der Responses API (commentary, final_answer).
  • plan{id, text} mit dem vorgeschlagenen Plantext im Planmodus. Behandeln Sie das endgültige plan-Element aus item/completed als maßgeblich.
  • reasoning{id, summary, content}, wobei summary gestreamte Reasoning-Zusammenfassungen und content rohe 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 Felder connectorId, linkId, resourceUri, appName, templateId und das stabile Connector-Feld actionName enthalten. In älteren gespeicherten Elementen können neuere Metadaten fehlen. Verwenden Sie appContext.resourceUri anstelle des veralteten mcpAppResourceUri auf oberster Ebene.
  • dynamicToolCall{id, tool, arguments, status, contentItems?, success?, durationMs?} für vom Client ausgeführte dynamische Werkzeugaufrufe.
  • collabToolCall{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.
  • webSearch{id, query, action?} für Websuchanfragen des Agents.
  • imageView{id, path}, das gesendet wird, wenn der Agent das Bildanzeigewerkzeug aufruft.
  • enteredReviewMode{id, review}, das beim Start des Reviewers gesendet wird.
  • exitedReviewMode{id, review}, das nach Abschluss des Reviewers gesendet wird.
  • contextCompaction{id}, das gesendet wird, wenn Codex den Gesprächsverlauf komprimiert.

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

Der App-Server stuft die ältere thread/compacted-Benachrichtigung als veraltet ein; verwenden Sie stattdessen das contextCompaction-Element.

Alle Elemente senden zwei gemeinsame Lebenszyklusereignisse:

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

Element-Deltas

  • item/agentMessage/delta – hängt gestreamten Text an die Agent-Nachricht 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 Textausgabe des älteren apply_patch. Aktuelle app-server-Versionen senden sie nicht mehr; verwenden Sie fileChange-Elemente und turn/diff/updated.

Fehler

Wenn ein Turn fehlschlägt, sendet der Server ein error-Ereignis mit { error: { message, codexErrorInfo?, additionalDetails? } } 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 auf der betreffenden codexErrorInfo-Variante weiter.

Genehmigungen

Je nach Codex-Einstellungen eines Benutzers können die Ausführung von Befehlen und Dateiänderungen eine Genehmigung erfordern. Der 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-Zustand 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. Wenn initialize.params.capabilities.experimentalApi = true gilt, kann die Nutzlast außerdem das experimentelle additionalPermissions enthalten, das den angeforderten Sandbox-Zugriff pro Befehl beschreibt. Alle Dateisystempfade innerhalb von additionalPermissions sind bei 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 aufgehoben wurde.
  5. item/completed gibt das endgültige commandExecution-Element mit status: completed | failed | declined zurück.

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

Codex gruppiert gleichzeitige Aufforderungen zur Netzwerkgenehmigung nach Ziel (host, Protokoll und Port). Der App-Server kann daher eine einzige Aufforderung senden, die mehrere in der Warteschlange befindliche 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 sendet ein fileChange-Element mit den vorgeschlagenen changes und status: "inProgress".
  2. item/fileChange/requestApproval enthält itemId, threadId, turnId, optional reason und optional grantRoot.
  3. Der Client antwortet mit einer der oben genannten Entscheidungen zu Dateiänderungen.
  4. serverRequest/resolved bestätigt, dass die ausstehende Anfrage beantwortet oder aufgehoben 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, sendet app-server serverRequest/resolved mit { threadId, requestId }. Wenn die ausstehende Anfrage durch den Start, den Abschluss oder die Unterbrechung des Turns aufgehoben wird, bevor der Client antwortet, sendet der Server dieselbe Benachrichtigung für diese Bereinigung.

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

Berechtigungsanfragen

Das integrierte request_permissions-Werkzeug 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 es weg oder verwenden Sie "turn" für eine auf den Turn begrenzte 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" beziehungsweise "cancel" und content: null. App-server sendet anschließend serverRequest/resolved. Um die openai/form-Variante zu empfangen, aktivieren Sie sie mit initialize.params.capabilities.mcpServerOpenaiFormElicitation.

Dynamische Werkzeugaufrufe (experimentell)

dynamicTools auf thread/start und der entsprechende Ablauf aus item/tool/call-Anfrage und -Antwort sind experimentelle APIs.

Namen dynamischer Werkzeuge und Namespaces müssen den Benennungsbeschränkungen der Responses API entsprechen. Vermeiden Sie reservierte Namespace-Namen, die von integrierten Codex-Werkzeugen verwendet werden.

Wenn während eines Turns ein dynamisches Werkzeug aufgerufen wird, sendet app-server:

  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 und allen zurückgegebenen Werten für contentItems oder success.

Genehmigungen für MCP-Werkzeugaufrufe (Apps)

Werkzeugaufrufe von Apps (Connectors) können ebenfalls eine Genehmigung erfordern. Wenn ein App-Werkzeugaufruf Nebenwirkungen hat, kann der Server mit tool/requestUserInput und Optionen wie Akzeptieren, Ablehnen und Abbrechen um eine Entscheidung bitten. Annotationen für destruktive Werkzeuge lösen immer eine Genehmigung aus, selbst wenn das Werkzeug auch Hinweise auf weniger weitreichende Berechtigungen angibt. Wenn der Benutzer ablehnt oder abbricht, wird das zugehörige mcpToolCall-Element mit einem Fehler abgeschlossen, ohne das Werkzeug 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 zusätzliche Latenz verursachen 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 durch cwds mit forceReload begrenzt). Sie können außerdem perCwdExtraUserRoots angeben, um zusätzliche absolute Pfade als user-Geltungsbereich für bestimmte cwd-Werte zu durchsuchen. App-server ignoriert Einträge, deren cwd nicht in cwds enthalten ist. skills/list kann pro cwd ein zwischengespeichertes Ergebnis wiederverwenden; setzen Sie forceReload: true, um 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 sendet außerdem skills/changed-Benachrichtigungen, wenn sich überwachte lokale Skill-Dateien ändern. Behandeln Sie dies als Invalidierungssignal und führen Sie bei Bedarf skills/list mit Ihren aktuellen Parametern erneut 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 zuletzt festgeschriebenen Laufzeit-Snapshot der installierten Apps zu lesen. Jedes Ergebnis enthält id, runtimeName (oder null), den effektiven enabled-Zustand und den callable-Zustand der App. Eine App kann nur aufgerufen werden, wenn die effektive Konfiguration sie aktiviert und mindestens ein für das Modell sichtbares Werkzeug die App- und Werkzeugrichtlinien erfüllt.

{
  "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 blockiert, kann eine erkannte App dennoch mit auf false gesetzten Feldern enabled und callable erscheinen.

Verwenden Sie app/list, um verfügbare Apps abzurufen. In CLI/TUI ist /apps die dem Benutzer angezeigte Auswahl; rufen Sie in benutzerdefinierten Clients direkt app/list auf. Jeder Eintrag enthält sowohl isAccessible (für den Benutzer verfügbar) als auch isEnabled (in config.toml aktiviert), sodass Clients zwischen Installation/Zugriff und lokalem Aktivierungszustand 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 die App-Funktionsfreigabe (features.apps) den Konfigurations-Snapshot dieses Threads. Wenn es weggelassen wird, verwendet app-server die neueste globale Konfiguration.

app/list kehrt zurück, 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 Aktualisierungen erfolgreich sind.

Der Server sendet außerdem app/list/updated-Benachrichtigungen, sobald eine der beiden Quellen (zugängliche Apps oder Verzeichnis-Apps) vollständig geladen ist. Jede Benachrichtigung enthält die neueste 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 statt des installierten Laufzeitzustands benötigen. Übergeben Sie höchstens 100 appIds. Der Server behält nur das erste Vorkommen jeder wiederholten ID bei und bewahrt diese Reihenfolge sowohl in apps als auch in missingAppIds. Unbekannte oder nicht zugä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 Werkzeugzusammenfassungen anzufordern. Die Metadatenantwort enthält weder den Laufzeitzustand installierter Apps noch autorisiert sie einen Werkzeugaufruf; verwenden Sie app/installed, um den effektiven Zustand von enabled und callable 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 Config RPC bei 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 effektive App-Konfigurationsstruktur (einschließlich _default und Überschreibungen pro Werkzeug):

{ "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 kein App-spezifischer Wert ihn überschreibt. Wenn beide weggelassen werden, übernimmt die App den übergeordneten approvals_reviewer-Wert. apps._default.default_tools_approval_mode legt den standardmäßigen Genehmigungsmodus für Werkzeuge ohne App- oder Werkzeug-spezifische Überschreibung fest. Verwaltete Anforderungen an den Genehmigungsmodus haben Vorrang vor den Genehmigungsmoduseinstellungen der Werkzeuge.

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

Externe Agent-Konfiguration erkennen und importieren

Verwenden Sie externalAgentConfig/detect, um migrierbare Artefakte externer Agents zu ermitteln, und übergeben Sie anschließend die ausgewählten Einträge 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 kennzeichnet das Produkt, das die ausgewählten Migrationselemente erzeugt hat.

Der Server sendet externalAgentConfig/import/progress, wenn Elementtypen abgeschlossen werden, und externalAgentConfig/import/completed, nachdem alle synchronen und im Hintergrund ausgeführten Importe beendet sind. Diese Benachrichtigungen enthalten dasselbe importId aus der Antwort sowie itemTypeResults mit successes und failures pro Typ. Der Abschluss kann unmittelbar nach der Antwort oder nach Abschluss der im Hintergrund ausgeführten Remote- Importe 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": []
    }
  ]
} }

Zuvor 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 erforderlich ist. 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 konfigurierte 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 Nutzungslimits zu benachrichtigen.

Authentifizierungsmodi

Codex unterstützt die folgenden Authentifizierungsmodi. account/updated.authMode zeigt den aktiven Modus 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, und Codex speichert ihn für API-Anfragen.
  • Von ChatGPT verwaltet (chatgpt) – Codex verwaltet den ChatGPT-OAuth-Ablauf, speichert Tokens dauerhaft und aktualisiert sie automatisch. Starten Sie für den Browserablauf mit type: "chatgpt" oder für den Gerätecodeablauf mit type: "chatgptDeviceCode".
  • Externe ChatGPT-Tokens (chatgptAuthTokens) – experimentell und für Host-Apps vorgesehen, die bereits den ChatGPT-Authentifizierungslebenszyklus des Benutzers verwalten. Die Host-App stellt direkt ein accessToken, chatgptAccountId und optionales chatgptPlanType bereit und muss das Token auf Anforderung aktualisieren.
  • Amazon Bedrockaccount/read meldet Bedrock-Konten als type: "amazonBedrock" und gibt an, ob die Anmeldedaten aus einem von Codex verwalteten Bedrock API key (credentialSource: "codexManaged") oder aus der externen AWS-Anmeldedatenkette (credentialSource: "awsManaged") stammen. account/updated.authMode verwendet bedrockApiKey für von Codex verwaltete Bedrock API keys.

API-Übersicht

  • account/read – aktuelle Kontoinformationen abrufen; optional Tokens aktualisieren.
  • account/login/start – Anmeldung beginnen (apiKey, chatgpt, chatgptDeviceCode oder experimentell chatgptAuthTokens).
  • account/login/completed (Benachrichtigung) – wird gesendet, wenn ein Anmeldeversuch abgeschlossen ist (Erfolg oder 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 gesendet, wenn sich der Authentifizierungsmodus ändert (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 gesendet, wenn sich die ChatGPT-Ratenlimits eines Benutzers ändern.
  • account/sendAddCreditsNudgeEmail – ChatGPT anweisen, einem Workspace-Eigentümer eine E-Mail über aufgebrauchtes Guthaben oder ein erreichtes Nutzungslimit zu senden.
  • account/rateLimitResetCredit/consume – eine verdiente Ratenlimit-Zurücksetzung mit einem vom Aufrufer bereitgestellten idempotencyKey-Wert verbrauchen.
  • account/usage/read – Zusammenfassungen der Token-Aktivität und Tagesintervalle für ein 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 gesendet; die Nutzlast enthält { name, threadId, success, error? }. threadId kann bei App-spezifischen oder Plugin-OAuth-Abläufen null sein.
  • mcpServer/startupStatus/updated (Benachrichtigung) – wird gesendet, wenn sich der Startstatus eines konfigurierten MCP-Servers ändert; die Nutzlast enthält { threadId, name, status, error, failureReason }. Bei einem App-spezifischen 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, den Server erneut zu verbinden.

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 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 an; 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 bezeichnet die ausgewählte Quelle der Anmeldedaten; es wird nicht geprüft, ob 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:
   {
     "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; ausgelassene 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ätecodeablauf)

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

  1. Starten Sie:
   {
     "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 verwaltet 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 ChatGPT-Authentifizierungslebenszyklus des Benutzers 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 überschreiten nach etwa 10 Sekunden das Zeitlimit.

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 Feldern:

  • rateLimits ist die abwärtskompatible Ansicht eines einzelnen Intervalls.
  • rateLimitsByLimitId (sofern vorhanden) ist die Ansicht mehrerer Intervalle, die nach dem gemessenen limit_id indiziert ist (beispielsweise codex).
  • limitId ist die Kennung des gemessenen Intervalls.
  • limitName ist eine optionale, benutzerfreundliche Bezeichnung des Intervalls.
  • 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 Intervall zugeordneten ChatGPT-Tarif zurückgibt.
  • credits ist enthalten, wenn der Server Details zum verbleibenden Workspace-Guthaben zurückgibt.
  • rateLimitReachedType bezeichnet den vom Server klassifizierten Limitzustand, 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 kein verfügbares Guthaben zurückgegeben hat. Der Dienst kann die Anzahl der Detailzeilen begrenzen, daher ist availableCount maßgeblich.
  • Jede Detailzeile enthält ein nicht transparentes id, resetType, status, grantedAt, expiresAt (kann null sein), title (kann null sein) und description (kann null sein).
  • Rufen Sie nach dem Verbrauch einer Zurücksetzung account/rateLimits/read ab.

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 Feldern:

  • summary-Werte können null sein, wenn der Dienst diese Kennzahl noch nicht zurückgegeben hat.
  • dailyUsageBuckets kann null sein; falls vorhanden, enthält jedes Intervall startDate und tokens.
  • Der Endpunkt erfordert eine durch Codex-Dienste gestützte Authentifizierung. ChatGPT, externe ChatGPT-Tokens, Agent-Identität und Authentifizierung mit persönlichem Zugriffstoken funktionieren; reine API-key- und Bedrock-Authentifizierung nicht.

8) Verdiente Ratenlimit-Zurücksetzungen (ChatGPT)

Verwenden Sie account/rateLimitResetCredit/consume, um eine verdiente Zurücksetzung zu verbrauchen.

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

Hinweise zu Feldern:

  • idempotencyKey darf nicht leer sein. Verwenden Sie für jeden logischen Einlösungsversuch eine UUID und verwenden Sie denselben Wert erneut, wenn Sie diesen Versuch wiederholen.
  • creditId ist optional. Wenn angegeben, muss es eine nicht leere, nicht transparente ID aus account/rateLimits/read sein. Wenn es weggelassen wird, wählt der Dienst das nächste verfügbare Guthaben aus.
  • reset bedeutet, dass ein Guthaben verbraucht 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 es kein geeignetes Ratenlimit-Zeitfenster zum Zurücksetzen gibt.
  • noCredit bedeutet, dass für das Konto keine verdienten Zurücksetzungsguthaben verfügbar sind.
  • Rufen Sie nach dem Verbrauch 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, einem Workspace-Eigentümer eine E-Mail zu senden, wenn das Guthaben aufgebraucht oder ein Nutzungslimit erreicht ist.

{ "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 Workspace-Nutzungslimit erreicht wurde. Wenn der Eigentümer bereits kürzlich 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 }
] } }