Codex App Server
Codex App Server
Codex app-server ist die Schnittstelle, über die Codex funktionsreiche Clients unterstützt (beispielsweise die Codex-Erweiterung für VS Code). Verwenden Sie ihn, wenn Sie eine tiefgreifende Integration in Ihr eigenes Produkt benötigen: Authentifizierung, Gesprächsverlauf, Genehmigungen und gestreamte Agentenereignisse. Die Implementierung von app-server ist im Codex-GitHub-Repository als Open Source verfügbar (openai/codex/codex-rs/app-server). Eine vollständige Liste der Open-Source-Komponenten von Codex finden Sie auf der Seite Open Source.
Terminaloberfläche der CLI verbinden
Im Remote-Modus der Terminaloberfläche können Sie app-server auf einem Rechner ausführen und die Terminaloberfläche der Codex CLI von einem anderen aus verbinden. Starten Sie einen WebSocket-Listener:
codex app-server --listen ws://127.0.0.1:4500Verbinden Sie anschließend die Terminaloberfläche:
codex --remote ws://127.0.0.1:4500Konfigurieren Sie für eine nicht lokale Verbindung die WebSocket-Authentifizierung und sichern Sie die Verbindung mit TLS ab. Speichern Sie das Bearer-Token in einer Umgebungsvariable und übergeben Sie deren Namen, anstatt das Token in der Befehlszeile anzugeben:
export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
--remote-auth-token-env CODEX_REMOTE_TOKENDie Option --remote akzeptiert die Endpunkte ws://, wss://, unix:// und
unix://PATH. Verwenden Sie unverschlüsselte WebSockets nur für localhost oder eine per SSH
portweitergeleitete Verbindung.
Remote-Host für Code Mode verbinden
Standardmäßig startet app-server einen lokalen Host für Code Mode. Um stattdessen einen Remote-Host zu verwenden, übergeben Sie dessen sichere WebSocket-URL:
codex app-server --code-mode-host wss://code-mode.example.com/host--code-mode-host steuert die ausgehende Verbindung von app-server zu seinem Host für Code
Mode. Dies ändert --listen nicht; diese Einstellung steuert, wie Clients eine Verbindung zu
app-server herstellen. Alle Threads im selben app-server-Prozess verwenden gemeinsam die ausgewählte
Verbindung zum Host für Code Mode.
Verwenden Sie wss:// für einen Remote-Host. Verwenden Sie ws:// nur für localhost oder
eine per SSH weitergeleitete Verbindung. Der app-server-Befehl und der WebSocket-Transport sind
experimentell und werden für Produktionsworkloads nicht unterstützt.
Protokoll
Wie MCP unterstützt codex app-server bidirektionale Kommunikation über JSON-RPC-2.0-Nachrichten (wobei der "jsonrpc":"2.0"-Header bei der Übertragung weggelassen wird).
Unterstützte Transporte:
stdio(--listen stdio://, Standard): durch Zeilenumbrüche getrenntes JSON (JSONL).websocket(--listen ws://IP:PORT, experimentell und nicht unterstützt): eine JSON-RPC-Nachricht pro WebSocket-Textframe.- Unix-Socket (
--listen unix://oder--listen unix://PATH): WebSocket- Verbindungen über den standardmäßigen app-server-Steuerungssocket von Codex oder einen benutzerdefinierten Unix- Socket-Pfad unter Verwendung des standardmäßigen HTTP-Upgrade-Handshakes. off(--listen off): keinen lokalen Transport bereitstellen.
Wenn Sie app-server mit --listen ws://IP:PORT ausführen, stellt derselbe Listener auch grundlegende
HTTP-Integritätsprüfungen bereit:
GET /readyzgibt200 OKzurück, sobald der Listener neue Verbindungen akzeptiert.GET /healthzgibt200 OKzurück, wenn die Anfrage keinenOrigin- Header enthält.- Anfragen mit einem
Origin-Header werden mit403 Forbiddenabgelehnt.
Der WebSocket-Transport ist experimentell und wird nicht unterstützt. Lokale Listener wie
ws://127.0.0.1:PORT eignen sich für localhost und Workflows mit SSH-Portweiterleitung.
WebSocket-Listener außerhalb der Loopback-Schnittstelle erlauben während der Einführung derzeit standardmäßig nicht authentifizierte
Verbindungen. Konfigurieren Sie daher die WebSocket-Authentifizierung, bevor Sie einen Listener remote
bereitstellen.
Unterstützte Flags für die WebSocket-Authentifizierung:
--ws-auth capability-token --ws-token-file /absolute/path--ws-auth capability-token --ws-token-sha256 HEX--ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path
Für signierte Bearer-Token können Sie außerdem --ws-issuer, --ws-audience und
--ws-max-clock-skew-seconds festlegen. Clients übermitteln die Anmeldedaten während des
WebSocket-Handshakes als Authorization: Bearer <token>, und app-server
erzwingt die Authentifizierung vor JSON-RPC initialize.
Bevorzugen Sie --ws-token-file, anstatt unbearbeitete Bearer-Token in der Befehlszeile zu übergeben. Verwenden Sie
--ws-token-sha256 nur, wenn der Client das unbearbeitete Token mit hoher Entropie in einem
separaten lokalen Geheimnisspeicher aufbewahrt; der Hash dient lediglich zur Verifizierung, und Clients benötigen weiterhin
das ursprüngliche Token.
Im WebSocket-Modus verwendet app-server begrenzte Warteschlangen. Wenn der Eingang für Anfragen voll ist,
lehnt der Server neue Anfragen mit dem JSON-RPC-Fehlercode -32001 und der Meldung
"Server overloaded; retry later." ab. Clients sollten es nach einer exponentiell
ansteigenden Verzögerung mit Jitter erneut versuchen.
Nachrichtenschema
Anfragen enthalten method, params und id:
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.6-terra" } }Antworten geben den Wert von id zusammen mit entweder result oder error zurück:
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }Benachrichtigungen lassen id weg und verwenden nur method und params:
{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }Sie können über die CLI ein TypeScript-Schema oder ein JSON-Schema-Bundle generieren. Jede Ausgabe gilt für die jeweils ausgeführte Codex-Version, sodass die generierten Artefakte exakt dieser Version entsprechen:
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemasErste Schritte
- Starten Sie den Server mit
codex app-server(standardmäßiger stdio-Transport),codex app-server --listen ws://127.0.0.1:4500(TCP-WebSocket) odercodex app-server --listen unix://(standardmäßiger Unix-Socket). - Verbinden Sie einen Client über den ausgewählten Transport und senden Sie anschließend
initialize, gefolgt von der Benachrichtigunginitialized. - Starten Sie einen Thread und einen Turn und lesen Sie anschließend fortlaufend Benachrichtigungen aus dem aktiven Transportstream.
Beispiel (Node.js/TypeScript):
const proc = spawn("codex", ["app-server"], {
stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
const msg = JSON.parse(line) as any;
console.log("server:", msg);
if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
threadId = msg.result.thread.id;
send({
method: "turn/start",
id: 2,
params: {
threadId,
input: [{ type: "text", text: "Summarize this repo." }],
},
});
}
});
send({
method: "initialize",
id: 0,
params: {
clientInfo: {
name: "my_product",
title: "My Product",
version: "0.1.0",
},
},
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.6-terra" } });Zentrale Grundelemente
- Thread: Ein Gespräch zwischen einem Benutzer und dem Codex-Agenten. Threads enthalten Turns.
- Turn: Eine einzelne Benutzeranfrage und die darauffolgende Arbeit des Agenten. Turns enthalten Elemente und streamen inkrementelle Aktualisierungen.
- Element: Eine Ein- oder Ausgabeeinheit (Benutzernachricht, Agentennachricht, Befehlsausführungen, Dateiänderung, Tool-Aufruf und mehr).
Verwenden Sie die Thread-APIs, um Gespräche zu erstellen, aufzulisten oder zu archivieren. Steuern Sie ein Gespräch mit den Turn-APIs und streamen Sie den Fortschritt über Turn-Benachrichtigungen.
Überblick über den Lebenszyklus
- Einmal pro Verbindung initialisieren: Senden Sie unmittelbar nach dem Öffnen einer Transportverbindung eine
initialize-Anfrage mit den Metadaten Ihres Clients und geben Sie anschließendinitializedaus. Der Server lehnt vor diesem Handshake alle Anfragen über diese Verbindung ab. - Thread starten (oder fortsetzen): Rufen Sie
thread/startfür ein neues Gespräch,thread/resumezum Fortsetzen eines vorhandenen Gesprächs oderthread/forkauf, um den Verlauf in eine neue Thread-ID zu verzweigen. - Turn beginnen: Rufen Sie
turn/startmit der gewünschtenthreadIdund der Benutzereingabe auf. Optionale Felder überschreiben Modell, Persönlichkeit,cwd, Sandbox-Richtlinie und weitere Einstellungen. - Aktiven Turn steuern: Rufen Sie
turn/steerauf, um dem derzeit laufenden Turn eine Benutzereingabe hinzuzufügen, ohne einen neuen Turn zu erstellen. - Ereignisse streamen: Lesen Sie nach
turn/startfortlaufend Benachrichtigungen auf stdout:thread/archived,thread/unarchived,item/started,item/completed,item/agentMessage/delta, Tool-Fortschritt und weitere Aktualisierungen. - Turn abschließen: Wenn das Modell fertig ist oder nach einer Abbruchanforderung über
turn/interrupt, gibt der Serverturn/completedmit dem endgültigen Status aus.
Initialisierung
Clients müssen pro Transportverbindung eine einzelne initialize-Anfrage senden, bevor sie eine andere Methode über diese Verbindung aufrufen, und dies anschließend mit einer initialized-Benachrichtigung bestätigen. Vor der Initialisierung gesendete Anfragen erhalten einen Not initialized-Fehler, und wiederholte initialize-Aufrufe über dieselbe Verbindung geben Already initialized zurück.
Der Server gibt die User-Agent-Zeichenfolge zurück, die er gegenüber vorgelagerten Diensten verwendet, sowie die Werte platformFamily und platformOs, die das Laufzeitziel beschreiben. Legen Sie clientInfo fest, um Ihre Integration zu identifizieren.
initialize.params.capabilities unterstützt außerdem diese Client-Funktionen:
optOutNotificationMethods– exakte Methodennamen von Benachrichtigungen, die für diese Verbindung unterdrückt werden sollen. Der Abgleich erfolgt exakt (keine Platzhalter oder Präfixe); unbekannte Namen werden akzeptiert und ignoriert.requestAttestation– aktiviert die vom Server initiierte Anfrageattestation/generate. Desktop-Hosts, die eine vorgelagerte Attestierung bereitstellen, antworten mit einem undurchsichtigen{ "token": "..." }-Wert.mcpServerOpenaiFormElicitation– erlaubt nachgelagerten MCP-Servern, die erweiterte OpenAI-Variante vonmcpServer/elicitation/requestzu senden.
Wichtig: Verwenden Sie clientInfo.name, um Ihren Client für die OpenAI Compliance Logs Platform zu identifizieren. Wenn Sie eine neue Codex-Integration für den Einsatz in Unternehmen entwickeln, wenden Sie sich bitte an OpenAI, damit sie der Liste bekannter Clients hinzugefügt wird. Weitere Informationen finden Sie in der Referenz zu Codex-Protokollen.
Beispiel (aus der Codex-Erweiterung für VS Code):
{
"method": "initialize",
"id": 0,
"params": {
"clientInfo": {
"name": "codex_vscode",
"title": "Codex VS Code Extension",
"version": "0.1.0"
}
}
}Beispiel mit deaktivierten Benachrichtigungen:
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true,
"optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
}
}
}Experimentelle API aktivieren
Einige Methoden und Felder von app-server sind bewusst durch die Fähigkeit experimentalApi geschützt.
- Lassen Sie
capabilitiesweg (oder setzen SieexperimentalApiauffalse), um ausschließlich die stabile API-Oberfläche zu verwenden; der Server lehnt dann experimentelle Methoden und Felder ab. - Setzen Sie
capabilities.experimentalApiauftrue, um experimentelle Methoden und Felder zu aktivieren.
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true
}
}
}Wenn ein Client eine experimentelle Methode oder ein experimentelles Feld sendet, ohne diese Funktion aktiviert zu haben, lehnt app-server dies mit Folgendem ab:
<descriptor> requires experimentalApi capability
API-Überblick
thread/start– erstellt einen neuen Thread; gibtthread/startedaus und abonniert Sie automatisch für Turn-/Item-Ereignisse dieses Threads.thread/resume– öffnet einen vorhandenen Thread anhand seiner ID erneut, sodass spätereturn/start-Aufrufe daran angehängt werden.thread/fork– verzweigt einen Thread unter einer neuen Thread-ID, indem der gespeicherte Verlauf kopiert wird. Übergeben SielastTurnId, um den Verlauf bis einschließlich dieses Turns zu kopieren und spätere Turns auszulassen, oderephemeral: true, um einen In-Memory-Fork zu erstellen. Gibt für den neuen Threadthread/startedaus; zurückgegebene Threads enthaltenforkedFromId, sofern verfügbar.thread/read– liest einen gespeicherten Thread anhand seiner ID, ohne ihn fortzusetzen; legen SieincludeTurnsfest, um den vollständigen Turn-Verlauf zurückzugeben. Zurückgegebenethread-Objekte enthalten die Laufzeitangabestatus.thread/list– durchläuft gespeicherte Thread-Protokolle seitenweise; unterstützt Cursor-basierte Paginierung sowiemodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermund die experimentellen FilterparentThreadIdoderancestorThreadId. Zurückgegebenethread-Objekte enthalten die Laufzeitangabestatus.thread/turns/list– experimentell; durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen.itemsViewsteuert, ob Turn-Items ausgelassen, zusammengefasst oder vollständig geladen werden.thread/items/list– experimentell; durchläuft persistierte Thread-Items seitenweise, optional auf einen einzelnenturnIdbeschränkt. Der aktive Thread-Speicher muss die Item-Paginierung unterstützen.thread/loaded/list– listet die IDs der derzeit im Arbeitsspeicher geladenen Threads auf.thread/name/set– legt den für Benutzer sichtbaren Namen eines geladenen Threads oder eines persistierten Rollouts fest oder aktualisiert ihn; gibtthread/name/updatedaus.thread/goal/set– legt das Ziel eines Threads fest; gibtthread/goal/updatedaus.thread/goal/get– liest das aktuelle Ziel eines Threads.thread/goal/clear– löscht das Ziel eines Threads; gibtthread/goal/clearedaus.thread/metadata/update– aktualisiert die Metadaten SQLite-gestützter gespeicherter Threads, einschließlich der persistierten WertegitInfoundisPinned.thread/archive– verschiebt die Protokolldatei eines Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfahren-Threads zu archivieren, die noch nicht archiviert sind; gibt bei Erfolg{}zurück und gibt für jeden archivierten Threadthread/archivedaus.thread/delete– löscht einen persistierten aktiven oder archivierten Thread und alle erzeugten Nachfahren-Threads dauerhaft; gibt bei Erfolg{}zurück und gibt für jeden gelöschten Threadthread/deletedaus.thread/unsubscribe– beendet das Abonnement dieser Verbindung für Turn-/Item-Ereignisse des Threads. War dies der letzte Abonnent, entlädt der Server den Thread nach einer Karenzzeit ohne Abonnenten und gibtthread/closedaus.thread/unarchive– stellt den Rollout eines archivierten Threads im Verzeichnis der aktiven Sitzungen wieder her; gibt den wiederhergestelltenthreadzurück und gibtthread/unarchivedaus.thread/status/changed– Benachrichtigung, die ausgegeben wird, wenn sich die Laufzeitangabestatuseines geladenen Threads ändert.thread/compact/start– löst die Komprimierung des Konversationsverlaufs eines Threads aus; gibt sofort{}zurück, während der Fortschritt über die Benachrichtigungenturn/*unditem/*gestreamt wird.thread/shellCommand– führt einen vom Benutzer initiierten Shell-Befehl für einen Thread aus. Dieser wird außerhalb der Sandbox mit vollständigem Zugriff ausgeführt und übernimmt nicht die Sandbox-Richtlinie des Threads.thread/backgroundTerminals/clean– beendet alle laufenden Hintergrundterminals eines Threads (experimentell; erfordertcapabilities.experimentalApi).thread/backgroundTerminals/list– listet laufende Hintergrundterminals eines geladenen Threads auf (experimentell; erfordertcapabilities.experimentalApi).thread/backgroundTerminals/terminate– beendet ein laufendes Hintergrundterminal anhand der app-server-processId(experimentell; erfordertcapabilities.experimentalApi).thread/rollback– veraltet; entfernt die letzten N Turns aus dem In-Memory-Kontext und persistiert eine Rollback-Markierung; gibt den aktualisiertenthreadzurück.turn/start– fügt einem Thread eine Benutzereingabe oder eine eigenständige Tool-Ausgabe hinzu und startet die Codex-Generierung; antwortet mit dem anfänglichenturnund streamt Ereignisse. BeicollaborationModebedeutetsettings.developer_instructions: null„integrierte Anweisungen für den ausgewählten Modus verwenden“.thread/inject_items– hängt unbearbeitete Responses API-Items an den für das Modell sichtbaren Verlauf eines geladenen Threads an, ohne einen Benutzer-Turn zu starten.turn/steer– hängt eine Benutzereingabe an den aktiven, derzeit ausgeführten Turn eines Threads an; gibt den akzeptiertenturnIdzurück.turn/interrupt– fordert den Abbruch eines derzeit ausgeführten Turns an; bei Erfolg wird{}zurückgegeben und der Turn endet mitstatus: "interrupted".review/start– startet den Codex-Reviewer für einen Thread; gibt die ItemsenteredReviewModeundexitedReviewModeaus.command/exec– führt einen einzelnen Befehl in der Server-Sandbox aus, ohne einen Thread/Turn zu starten.command/exec/write– schreibtstdin-Bytes in eine laufendecommand/exec-Sitzung oder schließtstdin.command/exec/resize– ändert die Größe einer laufenden PTY-gestütztencommand/exec-Sitzung.command/exec/terminate– beendet eine laufendecommand/exec-Sitzung.command/exec/outputDelta(Benachrichtigung) – wird für Base64-codierte stdout-/stderr-Blöcke einer streamendencommand/exec-Sitzung ausgegeben.process/spawn– startet eine explizite Prozesssitzung außerhalb der Codex-Sandbox (experimentell; erfordertcapabilities.experimentalApi).process/writeStdin– schreibt stdin-Bytes in eine laufendeprocess/spawn-Sitzung oder schließt stdin (experimentell).process/resizePty– ändert die Größe einer laufenden PTY-gestützten Prozesssitzung (experimentell).process/kill– beendet eine laufende Prozesssitzung (experimentell).process/outputDeltaundprocess/exited(Benachrichtigung) – werden für die gestreamte Prozessausgabe und den Prozessbeendigungsstatus ausgegeben (experimentell).model/list– listet verfügbare Modelle auf (legen SieincludeHidden: truefest, um Einträge mithidden: trueeinzuschließen), einschließlich Optionen für den Reasoning-Aufwand, optionalemupgradeundinputModalities.modelProvider/capabilities/read– liest die Grenzen der Anbieterfunktionen für Modell-/Anbieterkombinationen.experimentalFeature/list– listet Feature-Flags mit Metadaten zur Lebenszyklusphase und Cursor-Paginierung auf.experimentalFeature/enablement/set– aktualisiert In-Memory-Laufzeiteinstellungen für unterstützte Feature-Schlüssel wieappsundplugins.environment/info– experimentell; stellt eine Verbindung zu einer konfigurierten Ausführungsumgebung her und gibt deren Shell sowie das standardmäßige Arbeitsverzeichnis zurück.permissionProfile/list– listet Beta-Berechtigungsprofile und mit Cursor-Paginierung auf, ob die geltenden Anforderungen sie zulassen.collaborationMode/list– listet Voreinstellungen für den Zusammenarbeitsmodus auf (experimentell, ohne Paginierung).skills/list– listet Skills für einen oder mehrerecwd-Werte auf (unterstütztforceReloadund optionalperCwdExtraUserRoots).skills/extraRoots/set– ersetzt die zusätzlichen Wurzelverzeichnisse auf Prozessebene, die zur Erkennung eigenständiger Skills verwendet werden, ohne sie zu persistieren.skills/changed(Benachrichtigung) – wird ausgegeben, wenn sich überwachte lokale Skill-Dateien ändern.hooks/list– listet erkannte Lebenszyklus-Hooks für einen oder mehrerecwd-Werte auf.marketplace/add– fügt einen Remote-Plugin-Marktplatz hinzu und persistiert ihn in der Marktplatzkonfiguration des Benutzers.marketplace/remove– entfernt einen konfigurierten Marktplatz und, sofern vorhanden, dessen installiertes Marktplatz-Wurzelverzeichnis.marketplace/upgrade– aktualisiert einen konfigurierten Git-Marktplatz oder alle konfigurierten Git-Marktplätze, wenn Sie den Marktplatznamen weglassen.plugin/list– in Entwicklung; listet erkannte Plugin-Marktplätze und Plugin-Status auf, einschließlich Metadaten zu Installations-/Authentifizierungsrichtlinien, Fehlern beim Laden des Marktplatzes, IDs hervorgehobener Plugins sowie Metadaten zu lokalen, Git-, Paketregistrierungs- oder Remote-Plugin-Quellen. Zusammenfassungen können Remote-version, lokalelocalVersion, strukturierte Hell-/Dunkel-Symbole undinstallPolicySourceenthalten, das bei aktuellen Remote-Zeilennull,WORKSPACE_SETTINGoderIMPLICIT_CANONICAL_APPsein kann. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.plugin/read– in Entwicklung; liest ein einzelnes Plugin anhand des Marktplatzpfads oder des Namens des Remote-Marktplatzes und des Plugin-Namens, einschließlich gebündelter Skills, Apps, MCP-Servernamen und eines Remote-Plugin-shareUrl, sofern der Remote-Katalog eines bereitstellt. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.plugin/install– in Entwicklung; installiert ein Plugin anhand eines Marktplatzpfads oder des Namens eines Remote-Marktplatzes. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.plugin/uninstall– in Entwicklung; deinstalliert ein installiertes Plugin. Rufen Sie diese Methode noch nicht aus Produktionsclients auf.plugin/skill/read– liest Remote-Plugin-Skill-Markdown bei Bedarf anhand des Remote-Marktplatzes, der Plugin-ID und des Skill-Namens.app/installed– liest den Laufzeitstatus installierter Apps, einschließlich des tatsächlich geltenden Aktivierungs- und Aufrufstatus jeder App.app/list– listet verfügbare Apps (Connectors) mit Paginierung sowie Metadaten zu Zugänglichkeit und Aktivierungsstatus auf.app/read– ruft Metadaten und optionale, nur zur Anzeige bestimmte Tool-Zusammenfassungen für bestimmte App-IDs ab.skills/config/write– aktiviert oder deaktiviert Skills anhand ihres Pfads.mcpServer/oauth/login– startet eine OAuth-Anmeldung für einen konfigurierten MCP-Server; gibt eine Autorisierungs-URL zurück und gibt nach AbschlussmcpServer/oauthLogin/completedaus.tool/requestUserInput– stellt dem Benutzer für einen Tool-Aufruf 1–3 kurze Fragen (experimentell); für Fragen kannisOtherfestgelegt werden, um eine Freitextoption bereitzustellen.mcpServer/elicitation/request(Serveranforderung) – fordert vom Client eine strukturierte Formulareingabe oder die Bestätigung eines von einem MCP-Server angeforderten URL-Ablaufs an.item/permissions/requestApproval(Serveranforderung) – fordert den Client auf, eine Teilmenge der vom integrierten Toolrequest_permissionsangeforderten Netzwerk- oder Dateisystemberechtigungen zu erteilen.config/mcpServer/reload– lädt die MCP-Serverkonfiguration erneut vom Datenträger und reiht eine Aktualisierung für geladene Threads ein.mcpServerStatus/list– listet MCP-Server, Tools, Ressourcen und den Authentifizierungsstatus auf (Paginierung mit Cursor und Limit). Verwenden Siedetail: "full"für vollständige Daten oderdetail: "toolsAndAuthOnly", um Ressourcen auszulassen.mcpServer/resource/read– liest eine einzelne MCP-Ressource über einen initialisierten MCP-Server.mcpServer/tool/call– ruft ein Tool auf dem konfigurierten MCP-Server eines Threads auf.mcpServer/startupStatus/updated(Benachrichtigung) – wird ausgegeben, wenn sich der Startstatus eines konfigurierten MCP-Servers für einen geladenen Thread ändert.windowsSandbox/setupStart– startet die Einrichtung der Windows-Sandbox für den Moduselevatedoderunelevated; kehrt schnell zurück und gibt späterwindowsSandbox/setupCompletedaus.feedback/upload– übermittelt einen Feedbackbericht (Klassifizierung sowie optional Begründung/Protokolle und Konversations-ID, zusätzlich optionaleextraLogFiles-Anhänge).config/read– ruft nach dem Auflösen der Konfigurationsebenen die tatsächlich geltende Konfiguration vom Datenträger ab.externalAgentConfig/detect– erkennt Artefakte externer Agenten, die mitincludeHomeund optionalcwdsmigriert werden können; jedes erkannte Element enthältcwd(nullfür das Home-Verzeichnis).externalAgentConfig/import– wendet ausgewählte Migrationselemente externer Agenten an, indem explizitemigrationItemsmitcwd(nullfür das Home-Verzeichnis) übergeben werden. Zu den unterstützten Elementtypen zählen Konfiguration, Skills,AGENTS.md, Plugins, MCP-Serverkonfiguration, Subagenten, Hooks, Befehle und Sitzungen; nicht leere Importe geben während der AusführungexternalAgentConfig/import/progressundexternalAgentConfig/import/completedaus. Plugin- und Sitzungsimporte können asynchron abgeschlossen werden.config/value/write– schreibt ein einzelnes Konfigurationsschlüssel-Wert-Paar in dieconfig.tomldes Benutzers auf dem Datenträger.config/batchWrite– wendet Konfigurationsänderungen atomar auf dieconfig.tomldes Benutzers auf dem Datenträger an.configRequirements/read– ruft Anforderungen ausrequirements.tomlund/oder MDM ab, einschließlich der exakten verwalteten Konfiguration, Positivlisten, angeheftetenfeatureRequirementsund Netzwerkanforderungen (odernull, wenn Sie noch keine eingerichtet haben).fs/readFile,fs/writeFile,fs/createDirectory,fs/getMetadata,fs/readDirectory,fs/remove,fs/copy,fs/watch,fs/unwatchundfs/changed(Benachrichtigung) – führen über die app-server-v2-Dateisystem-API Operationen auf absoluten Dateisystempfaden aus.
Plugin-Zusammenfassungen enthalten eine source-Union. Lokale Plugins geben
{ "type": "local", "path": ... } zurück, Einträge Git-basierter Marktplätze geben
{ "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... } zurück,
Paketregistrierungseinträge geben
{ "type": "npm", "package": ..., "version": ..., "registry": ... } zurück und
Remote-Katalogeinträge geben { "type": "remote" } zurück. Bei ausschließlich im Remote-Katalog vorhandenen
Einträgen kann PluginMarketplaceEntry.path den Wert null haben; übergeben Sie
beim Lesen oder Installieren dieser Plugins remoteMarketplaceName anstelle von marketplacePath.
Modelle
Modelle auflisten (model/list)
Rufen Sie model/list auf, um verfügbare Modelle und deren Funktionen zu ermitteln, bevor Sie Auswahlfelder für Modelle oder Persönlichkeiten darstellen.
{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
"data": [{
"id": "gpt-5.6-sol",
"model": "gpt-5.6-sol",
"displayName": "GPT-5.6-Sol",
"hidden": false,
"defaultReasoningEffort": "low",
"supportedReasoningEfforts": [{
"reasoningEffort": "low",
"description": "Fast responses with lighter reasoning"
}],
"inputModalities": ["text", "image"],
"supportsPersonality": true,
"isDefault": true
}],
"nextCursor": null
} }Jeder Modelleintrag kann Folgendes enthalten:
supportedReasoningEfforts– unterstützte Aufwandsoptionen für das Modell.defaultReasoningEffort– empfohlener Standardaufwand für Clients.upgrade– optionale ID des empfohlenen Upgrade-Modells für Migrationsaufforderungen in Clients.upgradeInfo– optionale Upgrade-Metadaten für Migrationsaufforderungen in Clients.hidden– gibt an, ob das Modell in der standardmäßigen Auswahlliste ausgeblendet ist.inputModalities– unterstützte Eingabetypen des Modells (beispielsweisetext,image).supportsPersonality– gibt an, ob das Modell persönlichkeitsspezifische Anweisungen wie/personalityunterstützt.isDefault– gibt an, ob das Modell als Standard empfohlen wird.
Standardmäßig gibt model/list nur Modelle zurück, die in der Auswahl sichtbar sind. Setzen Sie includeHidden: true, wenn Sie die vollständige Liste benötigen und clientseitig anhand von hidden filtern möchten.
Wenn inputModalities fehlt (ältere Modellkataloge), behandeln Sie den Wert aus Gründen der Abwärtskompatibilität als ["text", "image"].
Experimentelle Features auflisten (experimentalFeature/list)
Verwenden Sie diesen Endpunkt, um Feature-Flags mit Metadaten und Lebenszyklusphase zu ermitteln:
{ "method": "experimentalFeature/list", "id": 7, "params": { "limit": 20 } }
{ "id": 7, "result": {
"data": [{
"name": "unified_exec",
"stage": "beta",
"displayName": "Unified exec",
"description": "Use the unified PTY-backed execution tool.",
"announcement": "Beta rollout for improved command execution reliability.",
"enabled": false,
"defaultEnabled": false
}],
"nextCursor": null
} }stage kann beta, underDevelopment, stable, deprecated oder removed sein. Bei Nicht-Beta-Flags können displayName, description und announcement den Wert null haben.
Ausführungsumgebung untersuchen (experimentell)
Verwenden Sie environment/info, um eine konfigurierte Remote-Umgebung zu untersuchen, bevor
Sie dort mit der Arbeit beginnen. Die Methode erfordert capabilities.experimentalApi = true.
{ "method": "environment/info", "id": 8, "params": { "environmentId": "devbox" } }
{ "id": 8, "result": {
"shell": { "name": "zsh", "path": "/bin/zsh" },
"cwd": "file:///workspace/project"
} }cwd kann null sein. Sofern vorhanden, handelt es sich um eine kanonische file:-URI, welche die
native Pfadsyntax der Umgebung verwendet. Unbekannte Umgebungs-IDs sowie Verbindungs- oder
Protokollfehler führen zu Anfragefehlern.
Threads
thread/readliest einen gespeicherten Thread, ohne ihn zu abonnieren; setzen SieincludeTurns, um Turns einzuschließen.thread/turns/listist experimentell und durchläuft den Turn-Verlauf eines gespeicherten Threads seitenweise, ohne ihn fortzusetzen. Verwenden SieitemsView, um auszuwählen, ob Turn-Elemente weggelassen, zusammengefasst oder vollständig geladen werden.thread/items/listist experimentell und durchläuft persistierte Thread-Elemente seitenweise, optional auf einen Turn beschränkt.thread/listunterstützt Cursor-Paginierung sowie Filterung nachmodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermund den experimentellen FilternparentThreadIdoderancestorThreadId.thread/loaded/listgibt die IDs der derzeit im Arbeitsspeicher befindlichen Threads zurück.thread/archiveverschiebt das persistierte JSONL-Protokoll des Threads in das Archivverzeichnis und versucht, die Protokolle erzeugter Nachfolger-Threads zu archivieren, die noch nicht archiviert sind.thread/deletelöscht einen persistierten aktiven oder archivierten Thread und seine erzeugten Nachfolger-Threads dauerhaft.thread/metadata/updateaktualisiert gespeicherte Thread-Metadaten teilweise, einschließlich persistierter Werte fürgitInfoundisPinned.thread/unsubscribebeendet das Abonnement der aktuellen Verbindung für einen geladenen Thread und kann nach einer Inaktivitätskarenzzeitthread/closedauslösen.thread/unarchivestellt einen archivierten Thread-Rollout im Verzeichnis der aktiven Sitzungen wieder her.thread/compact/startlöst die Komprimierung aus und gibt sofort{}zurück.thread/rollbackist veraltet. Es entfernt die letzten N Turns aus dem Kontext im Arbeitsspeicher und zeichnet eine Rollback-Markierung im persistierten JSONL-Protokoll des Threads auf.thread/inject_itemsfügt dem für das Modell sichtbaren Verlauf eines geladenen Threads unbearbeitete Responses API-Elemente hinzu, ohne einen Benutzer-Turn zu starten.
Thread starten oder fortsetzen
Starten Sie einen neuen Thread, wenn Sie ein neues Codex-Gespräch benötigen.
{ "method": "thread/start", "id": 10, "params": {
"model": "gpt-5.6-terra",
"cwd": "/Users/me/project",
"approvalPolicy": "never",
"sandbox": "workspaceWrite",
"personality": "friendly",
"serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
"thread": {
"id": "thr_123",
"sessionId": "thr_123",
"preview": "",
"ephemeral": false,
"modelProvider": "openai",
"createdAt": 1730910000
}
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }serviceName ist optional. Legen Sie diesen Wert fest, wenn app-server Metriken auf Thread-Ebene mit dem Dienstnamen Ihrer Integration kennzeichnen soll.
thread/start, thread/resume und thread/fork geben
instructionSources zurück, ein Array mit den Pfaden geladener Anweisungsdateien. Jeder Pfad verwendet
die native absolute Syntax seiner Quellumgebung, einschließlich Pfaden für Remote-
Umgebungen.
Experimentelle Clients können historyMode bei thread/start auf "legacy"
(den Standardwert) oder "paginated" setzen. Die paginierte Thread-Erstellung wird noch nicht unterstützt
und gibt den JSON-RPC-Fehler -32601 zurück. app-server kann Zusammenfassungen vorhandener
paginierter Datensätze auflisten und lesen, doch Lesevorgänge des vollständigen Verlaufs, die Turn-Paginierung und das Fortsetzen
werden bis zur Unterstützung paginierter Verläufe sicher abgelehnt.
Beta-Clients, die capabilities.experimentalApi aktivieren, können in
permissions anstelle des veralteten Felds sandbox die ID eines benannten Berechtigungsprofils übergeben.
Senden Sie permissions und sandbox nicht zusammen. Verwenden Sie
permissionProfile/list mit dem Projektwert cwd, um verfügbare Profile zu ermitteln
und festzustellen, ob verwaltete Anforderungen die einzelnen Profile zulassen.
thread.sessionId identifiziert die Wurzel des aktuellen Live-Sitzungsbaums. Wurzel-Threads
verwenden ihre eigene Thread-ID als Sitzungs-ID; verzweigte Threads behalten die Sitzungs-ID
der Wurzel bei, von der sie abstammen. Clients sollten die Sitzungs-ID aus
thread.sessionId lesen, anstatt sie aus der Thread-ID abzuleiten.
Um eine gespeicherte Sitzung fortzusetzen, rufen Sie thread/resume mit der zuvor aufgezeichneten thread.id auf. Die Antwortstruktur entspricht thread/start. Sie können auch dieselben Konfigurationsüberschreibungen übergeben, die thread/start unterstützt, beispielsweise personality:
{ "method": "thread/resume", "id": 11, "params": {
"threadId": "thr_123",
"personality": "friendly"
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }Durch das Fortsetzen eines Threads wird thread.updatedAt (oder der Änderungszeitpunkt der Rollout-Datei) nicht automatisch aktualisiert. Der Zeitstempel wird aktualisiert, sobald Sie einen Turn starten.
Wenn Sie einen aktivierten MCP-Server in der Konfiguration als required markieren und dieser Server nicht initialisiert werden kann, schlagen thread/start und thread/resume fehl, anstatt ohne ihn fortzufahren.
dynamicTools bei thread/start ist ein experimentelles Feld (erfordert capabilities.experimentalApi = true). Codex persistiert diese dynamischen Tools in den Rollout-Metadaten des Threads und stellt sie bei thread/resume wieder her, wenn Sie keine neuen dynamischen Tools angeben.
Wenn Sie einen Thread mit einem anderen Modell fortsetzen als dem im Rollout aufgezeichneten, gibt Codex eine Warnung aus und wendet beim nächsten Turn einmalig eine Anweisung zum Modellwechsel an.
Thread-Ziel verwalten
Verwenden Sie thread/goal/set, thread/goal/get und thread/goal/clear, um denselben
persistierten Zielstatus zu verwalten, den /goal in der TUI anzeigt.
{ "method": "thread/goal/set", "id": 13, "params": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
"threadId": "thr_123",
"goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
}
} }Zielsetzungen dürfen nicht leer sein und höchstens 4.000 Zeichen umfassen. Wenn Sie eine neue
Zielsetzung angeben, wird das Ziel ersetzt und die Nutzungszählung zurückgesetzt. Wenn Sie die aktuelle
noch nicht abgeschlossene Zielsetzung angeben oder objective weglassen, werden Status oder Token-Budget
aktualisiert, während der Nutzungsverlauf erhalten bleibt.
Um von einer gespeicherten Sitzung abzuzweigen, rufen Sie thread/fork mit der thread.id auf. Dadurch wird eine neue Thread-ID erstellt und eine thread/started-Benachrichtigung dafür ausgegeben. Übergeben Sie
lastTurnId, um den Verlauf bis einschließlich dieses Turns zu kopieren und spätere
Turns wegzulassen:
{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456" } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }app-server lehnt einen laufenden lastTurnId ab. Wenn Sie das Feld weglassen, während sich der
Quell-Thread mitten in einem Turn befindet, zeichnet die Verzweigung eine Unterbrechungsmarkierung auf, anstatt
einen nicht gekennzeichneten unvollständigen Turn beizubehalten.
Übergeben Sie ephemeral: true, um eine Verzweigung im Arbeitsspeicher zu erstellen, ohne sie zu den gespeicherten
Thread-Auflistungen hinzuzufügen:
{
"method": "thread/fork",
"id": 13,
"params": {
"threadId": "thr_123",
"ephemeral": true
}
}
{
"id": 13,
"result": {
"thread": {
"id": "thr_789",
"sessionId": "thr_789",
"forkedFromId": "thr_123",
"ephemeral": true
}
}
}Kurzlebige Verzweigungen paginierter Threads erfordern außerdem excludeTurns: true. Dieses
Feld ist experimentell und erfordert capabilities.experimentalApi = true.
Wenn ein benutzerfreundlicher Thread-Titel festgelegt wurde, fügt app-server thread.name in den Antworten von thread/list, thread/read, thread/resume, thread/unarchive und thread/rollback ein. thread/start und thread/fork können name weglassen (oder null zurückgeben), bis später ein Titel festgelegt wird.
Gespeicherten Thread lesen (ohne ihn fortzusetzen)
Verwenden Sie thread/read, wenn Sie gespeicherte Thread-Daten benötigen, den Thread jedoch weder fortsetzen noch seine Ereignisse abonnieren möchten.
includeTurns– beitrueenthält die Antwort die Turns des Threads; beifalseoder wenn der Wert weggelassen wird, erhalten Sie nur die Thread-Zusammenfassung.- Zurückgegebene
thread-Objekte enthalten das Laufzeitfeldstatus(notLoaded,idle,systemErroroderactivemitactiveFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }Im Gegensatz zu thread/resume lädt thread/read den Thread weder in den Arbeitsspeicher noch gibt es thread/started aus.
Thread-Turns auflisten
thread/turns/list ist experimentell. Verwenden Sie diese Methode, um den Turn-Verlauf eines gespeicherten Threads seitenweise zu durchlaufen, ohne ihn fortzusetzen. Die Ergebnisse werden standardmäßig vom neuesten zum ältesten sortiert, sodass Clients mit nextCursor ältere Turns abrufen können. Die Antwort enthält außerdem backwardsCursor; übergeben Sie den Wert als cursor zusammen mit sortDirection: "asc", um Turns abzurufen, die neuer als das erste Element der vorherigen Seite sind.
itemsView steuert, wie viele Turn-Elementdaten die Antwort enthält:
notLoadedlässt Elemente weg.summarygibt zusammengefasste Elementdaten zurück und ist der Standardwert, wenn das Feld weggelassen wird.fullgibt vollständige Elementdaten zurück.
{ "method": "thread/turns/list", "id": 20, "params": {
"threadId": "thr_123",
"limit": 50,
"sortDirection": "desc",
"itemsView": "summary"
} }
{ "id": 20, "result": {
"data": [],
"nextCursor": "older-turns-cursor-or-null",
"backwardsCursor": "newer-turns-cursor-or-null"
} }thread/items/list ist ebenfalls experimentell. Es durchläuft persistierte Elemente seitenweise, ohne
den Thread fortzusetzen. Übergeben Sie turnId, um die Ergebnisse auf einen Turn zu beschränken, oder lassen Sie den Wert weg,
um Elemente threadübergreifend seitenweise zu durchlaufen. Der aktive Thread-Speicher muss die Elementpaginierung
unterstützen; andernfalls gibt der Server einen Fehler für eine nicht unterstützte Methode zurück.
Threads auflisten (mit Paginierung und Filtern)
Mit thread/list können Sie eine Verlaufsoberfläche darstellen. Die Ergebnisse werden anhand von createdAt standardmäßig vom neuesten zum ältesten sortiert. Filter werden vor der Paginierung angewendet. Übergeben Sie eine beliebige Kombination aus:
cursor– nicht transparenter String aus einer vorherigen Antwort; für die erste Seite weglassen.limit– wenn nicht festgelegt, verwendet der Server standardmäßig eine angemessene Seitengröße.sortKey–created_at(Standard),updated_atoderrecency_at.sortDirection–desc(Standard) oderasc.modelProviders– beschränkt die Ergebnisse auf bestimmte Anbieter; wenn nicht festgelegt, null oder ein leeres Array, werden alle Anbieter einbezogen.sourceKinds– beschränkt die Ergebnisse auf bestimmte Thread-Quellen. Wenn der Wert weggelassen wird oder[]lautet, verwendet der Server standardmäßig nur interaktive Quellen:cliundvscode.archived– beitruewerden nur archivierte Threads aufgelistet. Beifalseoder wenn der Wert weggelassen wird, werden nicht archivierte Threads aufgelistet (Standard).isPinned– wenn angegeben, werden nur Threads zurückgegeben, deren persistierter Anheftungsstatus übereinstimmt. Lassen Sie den Wert weg, um angeheftete und nicht angeheftete Threads zurückzugeben.cwd– beschränkt die Ergebnisse auf Threads, deren aktuelles Sitzungsarbeitsverzeichnis exakt diesem Pfad oder einem der Pfade in einem Array entspricht. Relative Pfade werden ausgehend vom Arbeitsverzeichnis des app-server-Prozesses aufgelöst.useStateDbOnly– beitruewerden Ergebnisse der Statusdatenbank zurückgegeben, ohne JSONL-Thread-Protokolle zu durchsuchen, um Metadaten zu reparieren. Lassen Sie den Wert weg oder übergeben Siefalse, um das standardmäßige Such- und Reparaturverhalten zu verwenden.searchTerm– beschränkt die Ergebnisse auf Threads, deren extrahierter Titel dieses Fragment unter Beachtung der Groß-/Kleinschreibung enthält.parentThreadId– beschränkt die Ergebnisse auf direkte untergeordnete Threads des angegebenen übergeordneten Threads. Dieser Filter ist experimentell und erfordertcapabilities.experimentalApi = true.ancestorThreadId– beschränkt die Ergebnisse auf erzeugte Nachfolger des angegebenen Threads in beliebiger Tiefe. Dieser Filter ist experimentell und erfordertcapabilities.experimentalApi = true; kombinieren Sie ihn nicht mitparentThreadId.
sourceKinds akzeptiert die folgenden Werte:
clivscodeexecappServersubAgentsubAgentReviewsubAgentCompactsubAgentThreadSpawnsubAgentOtherunknown
Beispiel:
{ "method": "thread/list", "id": 20, "params": {
"cursor": null,
"limit": 25,
"sortKey": "created_at"
} }
{ "id": 20, "result": {
"data": [
{ "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
{ "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
],
"nextCursor": "opaque-token-or-null"
} }Wenn nextCursor den Wert null hat, haben Sie die letzte Seite erreicht.
Gespeicherte Thread-Metadaten aktualisieren
Verwenden Sie thread/metadata/update, um gespeicherte Thread-Metadaten teilweise zu aktualisieren, ohne den
Thread fortzusetzen. Setzen Sie isPinned, um den Thread anzuheften oder die Anheftung aufzuheben, oder aktualisieren Sie gitInfo, um
persistierte Git-Metadaten zu ändern. Ausgelassene Felder bleiben unverändert; ein explizites null löscht einen
gespeicherten Git-Metadatenwert.
{ "method": "thread/metadata/update", "id": 21, "params": {
"threadId": "thr_123",
"isPinned": true,
"gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
"thread": {
"id": "thr_123",
"isPinned": true,
"gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
}
} }Änderungen des Thread-Status verfolgen
thread/status/changed wird ausgegeben, wenn sich der Laufzeitstatus eines geladenen Threads ändert. Die Nutzdaten enthalten threadId und den neuen Wert von status.
{
"method": "thread/status/changed",
"params": {
"threadId": "thr_123",
"status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
}
}Geladene Threads auflisten
thread/loaded/list gibt die IDs der derzeit im Arbeitsspeicher geladenen Threads zurück.
{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }Abonnement eines geladenen Threads beenden
thread/unsubscribe entfernt das Abonnement der aktuellen Verbindung für einen Thread. Der Antwortstatus lautet:
unsubscribed, wenn die Verbindung den Thread abonniert hatte und das Abonnement nun entfernt wurde.notSubscribed, wenn die Verbindung diesen Thread nicht abonniert hatte.notLoaded, wenn der Thread nicht geladen ist.
War dies der letzte Abonnent, hält der Server den Thread geladen, bis er 30 Minuten lang weder Abonnenten noch Thread-Aktivität aufweist. Nach Ablauf der Karenzzeit entlädt app-server den Thread und gibt einen thread/status/changed-Übergang zu notLoaded sowie thread/closed aus.
{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }Wenn der Thread später abläuft:
{ "method": "thread/status/changed", "params": {
"threadId": "thr_123",
"status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }Thread archivieren
Verwenden Sie thread/archive, um das persistierte Thread-Protokoll (als JSONL-Datei auf dem Datenträger gespeichert) in das Verzeichnis archivierter Sitzungen zu verschieben. Beim Archivieren eines Threads wird außerdem versucht, erzeugte Nachfolger-Threads zu archivieren, die noch nicht archiviert sind.
{ "method": "thread/archive", "id": 22, "params": { "threadId": "thr_b" } }
{ "id": 22, "result": {} }
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
{ "method": "thread/archived", "params": { "threadId": "thr_child" } }Archivierte Threads erscheinen bei zukünftigen Aufrufen von thread/list nur, wenn Sie archived: true übergeben. Der Server gibt für jeden tatsächlich archivierten Thread eine thread/archived-Benachrichtigung aus; kann ein erzeugter Nachfolger nicht archiviert werden, kann die Anfrage dennoch erfolgreich sein, ohne dass für diesen Nachfolger eine Archivierungsbenachrichtigung ausgegeben wird.
Thread löschen
Verwenden Sie thread/delete, um einen dauerhaft gespeicherten aktiven oder archivierten Thread
und die von ihm erzeugten untergeordneten Threads endgültig zu löschen. Der Server entfernt vorhandene Rollout-Dateien und
zugehörige Metadaten, bevor er den Erfolg zurückmeldet; fehlende Rollout-Dateien gelten
als bereits gelöscht. Flüchtige Root-Threads können nicht gelöscht werden.
{ "method": "thread/delete", "id": 23, "params": { "threadId": "thr_b" } }
{ "id": 23, "result": {} }
{ "method": "thread/deleted", "params": { "threadId": "thr_b" } }
{ "method": "thread/deleted", "params": { "threadId": "thr_child" } }Archivierung eines Threads aufheben
Verwenden Sie thread/unarchive, um den Rollout eines archivierten Threads zurück in das Verzeichnis der aktiven Sitzungen zu verschieben.
{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
{ "id": 24, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes" } } }
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }Thread-Komprimierung auslösen
Verwenden Sie thread/compact/start, um die manuelle Komprimierung des Verlaufs eines Threads auszulösen. Die Anfrage gibt sofort {} zurück.
App-server gibt den Fortschritt als standardmäßige turn/*- und item/*-Benachrichtigungen über dieselbe threadId aus, einschließlich des Lebenszyklus eines contextCompaction-Elements (item/started, dann item/completed).
{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }Shell-Befehl für einen Thread ausführen
Verwenden Sie thread/shellCommand für vom Benutzer initiierte Shell-Befehle, die zu einem Thread gehören. Die Anfrage gibt sofort {} zurück, während der Fortschritt über standardmäßige turn/*- und item/*-Benachrichtigungen gestreamt wird.
Diese API wird außerhalb der Sandbox mit vollständigem Zugriff ausgeführt und übernimmt die Sandbox-Richtlinie des Threads nicht. Clients sollten sie nur für ausdrücklich vom Benutzer initiierte Befehle bereitstellen.
Wenn der Thread bereits einen aktiven Turn hat, wird der Befehl als zusätzliche Aktion dieses Turns ausgeführt und seine formatierte Ausgabe in den Nachrichtenstream des Turns eingefügt. Ist der Thread inaktiv, startet app-server einen eigenständigen Turn für den Shell-Befehl.
Legen Sie timeoutMs fest, um die Ausführungszeit in Millisekunden zu begrenzen. Wenn Sie den Wert weglassen oder
null übergeben, gilt der Standardwert von einer Stunde. 0 fordert ein sofortiges Timeout an; negative
Werte werden abgelehnt. Das Timeout verzögert die unmittelbare RPC-Bestätigung nicht.
{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }Hintergrundterminals bereinigen
Verwenden Sie thread/backgroundTerminals/clean, um alle laufenden Hintergrundterminals zu beenden, die einem Thread zugeordnet sind. Diese Methode ist experimentell und erfordert capabilities.experimentalApi = true.
{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }Verwenden Sie thread/backgroundTerminals/list, um die laufenden Hintergrundterminals
eines geladenen Threads zu prüfen. Die Anfrage unterstützt die standardmäßige
Paginierung mit cursor und limit, und der zurückgegebene Wert processId ist die Prozess-ID von app-server. Diese
Methode ist experimentell und erfordert capabilities.experimentalApi = true:
{ "method": "thread/backgroundTerminals/list", "id": 28, "params": { "threadId": "thr_b" } }
{ "id": 28, "result": { "data": [
{
"itemId": "item_456",
"processId": "42",
"command": "python3 -m http.server",
"cwd": "/workspace",
"osPid": null,
"cpuPercent": null,
"rssKb": null
}
], "nextCursor": null } }Verwenden Sie thread/backgroundTerminals/terminate mit diesem processId, um ein
Hintergrundterminal zu beenden. Diese Methode ist experimentell und erfordert
capabilities.experimentalApi = true:
{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }Letzte Turns zurücksetzen
thread/rollback ist veraltet und wird entfernt. Es entfernt die letzten
numTurns Einträge aus dem In-Memory-Kontext und speichert eine Rollback-Markierung im
Rollout-Protokoll. Das zurückgegebene thread enthält turns, das nach dem
Rollback ausgefüllt ist.
{ "method": "thread/rollback", "id": 30, "params": { "threadId": "thr_b", "numTurns": 1 } }
{ "id": 30, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes", "ephemeral": false } } }Turns
Das Feld input akzeptiert eine Liste von Elementen:
{ "type": "text", "text": "Explain this diff" }{ "type": "image", "url": "https://.../design.png" }{ "type": "localImage", "path": "/tmp/screenshot.png" }
Sie können Konfigurationseinstellungen pro Turn überschreiben (Modell, Aufwand, Persönlichkeit, cwd, Sandbox-Richtlinie, Zusammenfassung). Wenn diese Einstellungen angegeben werden, dienen sie als Standardwerte für spätere Turns desselben Threads. outputSchema gilt nur für den aktuellen Turn. Setzen Sie für sandboxPolicy.type = "externalSandbox" den Wert networkAccess auf restricted oder enabled; für workspaceWrite bleibt networkAccess ein boolescher Wert.
Bei turn/start.collaborationMode bedeutet settings.developer_instructions: null „die integrierten Anweisungen für den ausgewählten Modus verwenden“ und nicht, dass die Modusanweisungen gelöscht werden.
Lesezugriff der Sandbox (ReadOnlyAccess)
sandboxPolicy unterstützt explizite Einstellungen für den Lesezugriff:
readOnly: optionalesaccess(standardmäßig{ "type": "fullAccess" }oder eingeschränkte Stammverzeichnisse).workspaceWrite: optionalesreadOnlyAccess(standardmäßig{ "type": "fullAccess" }oder eingeschränkte Stammverzeichnisse).
Struktur für eingeschränkten Lesezugriff:
{
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
}Unter macOS fügt includePlatformDefaults: true für Sitzungen mit eingeschränktem Lesezugriff eine kuratierte, plattformspezifische Seatbelt-Standardrichtlinie hinzu. Dies verbessert die Tool-Kompatibilität, ohne pauschal den gesamten Bereich /System freizugeben.
Beispiele:
{ "type": "readOnly", "access": { "type": "fullAccess" } }{
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"readOnlyAccess": {
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
},
"networkAccess": false
}Turn starten
{ "method": "turn/start", "id": 30, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Run tests" } ],
"cwd": "/Users/me/project",
"approvalPolicy": "unlessTrusted",
"sandboxPolicy": {
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"networkAccess": true
},
"model": "gpt-5.6-terra",
"effort": "medium",
"summary": "concise",
"personality": "friendly",
"outputSchema": {
"type": "object",
"properties": { "answer": { "type": "string" } },
"required": ["answer"],
"additionalProperties": false
}
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }Um einen Turn mit der Ausgabe eines von Ihrem Client ausgeführten Tools zu starten, übergeben Sie toolOutput
mit einem nicht leeren name, einem optionalen namespace und einem output-String oder
einem Array von Inhaltselementen. Legen Sie input auf ein leeres Array fest; Sie können
toolOutput nicht mit einer nicht leeren Benutzereingabe kombinieren.
{
"method": "turn/start",
"id": 31,
"params": {
"threadId": "thr_123",
"input": [],
"toolOutput": {
"name": "run_tests",
"namespace": null,
"output": "All 42 tests passed."
}
}
}Die Ausgabe bleibt in der Konversation eine Tool-Ausgabe und erscheint in Benachrichtigungen und im persistierten Verlauf als
functionCallOutput-Item. Wenn bereits ein regulärer
Turn aktiv ist, reiht Codex die Ausgabe für diesen Turn ein.
Elemente in einen Thread einfügen
Verwenden Sie thread/inject_items, um vorab erstellte Responses API-Elemente an den Prompt-Verlauf eines geladenen Threads anzuhängen, ohne einen Benutzer-Turn zu starten. Diese Elemente werden im Rollout gespeichert und in nachfolgende Modellanfragen aufgenommen.
{ "method": "thread/inject_items", "id": 31, "params": {
"threadId": "thr_123",
"items": [
{
"type": "message",
"role": "assistant",
"content": [{ "type": "output_text", "text": "Previously computed context." }]
}
]
} }
{ "id": 31, "result": {} }Aktiven Turn steuern
Verwenden Sie turn/steer, um dem aktiven, laufenden Turn weitere Benutzereingaben hinzuzufügen.
- Geben Sie
expectedTurnIdan; der Wert muss mit der ID des aktiven Turns übereinstimmen. - Die Anfrage schlägt fehl, wenn der Thread keinen aktiven Turn hat.
turn/steergibt keine neueturn/started-Benachrichtigung aus.turn/steerakzeptiert keine Überschreibungen auf Turn-Ebene (model,cwd,sandboxPolicyoderoutputSchema).
{ "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:
uncommittedChangesbaseBranch(Diff gegenüber einem Branch)commit(Review eines bestimmten Commits)custom(frei formulierte Anweisungen)
Verwenden Sie delivery: "inline" (Standard), um das Review im vorhandenen Thread auszuführen, oder delivery: "detached", um einen neuen Review-Thread abzuzweigen.
Beispiel für Anfrage und Antwort:
{ "method": "review/start", "id": 40, "params": {
"threadId": "thr_123",
"delivery": "inline",
"target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
"turn": {
"id": "turn_900",
"status": "inProgress",
"items": [
{ "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
],
"error": null
},
"reviewThreadId": "thr_123"
} }Verwenden Sie für ein abgekoppeltes Review "delivery": "detached". Die Antwort hat dieselbe Struktur, aber reviewThreadId enthält die ID des neuen Review-Threads (abweichend vom ursprünglichen threadId). Der Server gibt außerdem eine thread/started-Benachrichtigung für diesen neuen Thread aus, bevor er den Review-Turn streamt.
Codex streamt zunächst die übliche turn/started-Benachrichtigung und anschließend ein item/started mit einem enteredReviewMode-Element:
{
"method": "item/started",
"params": {
"item": {
"type": "enteredReviewMode",
"id": "turn_900",
"review": "current changes"
}
}
}Wenn der Reviewer fertig ist, gibt der Server item/started und item/completed mit einem exitedReviewMode-Element aus, das den endgültigen Review-Text enthält:
{
"method": "item/completed",
"params": {
"item": {
"type": "exitedReviewMode",
"id": "turn_900",
"review": "Looks solid overall..."
}
}
}Verwenden Sie diese Benachrichtigung, um die Ausgabe des Reviewers in Ihrem Client darzustellen.
Prozessausführung
process/* ist eine experimentelle, explizite API zur Prozesssteuerung. Sie erfordert
capabilities.experimentalApi = true und wird außerhalb der Sandbox von Codex ausgeführt. Verwenden Sie sie
nur, wenn Ihr Client die lokale Prozesssteuerung bewusst ohne
Sandbox bereitstellt.
Starten Sie mit process/spawn einen Prozess und geben Sie ein processHandle an. Verwenden Sie
dieses Handle anschließend für Anfragen zu stdin, Größenänderungen und zum Beenden. Die Ausgabe wird über
process/outputDelta-Benachrichtigungen gestreamt, der Abschluss über
process/exited.
{ "method": "process/spawn", "id": 48, "params": {
"command": ["python3", "-m", "pytest", "-q"],
"processHandle": "pytest-1",
"cwd": "/Users/me/project",
"tty": true
} }
{ "id": 48, "result": {} }
{ "method": "process/outputDelta", "params": {
"processHandle": "pytest-1",
"stream": "stdout",
"deltaBase64": "Li4u"
} }
{ "method": "process/exited", "params": {
"processHandle": "pytest-1",
"exitCode": 0
} }Verwenden Sie process/writeStdin mit deltaBase64, closeStdin oder beiden, um
Eingaben zu senden. Verwenden Sie process/resizePty für Ereignisse zur Größenänderung des PTY und process/kill, um
einen laufenden Prozess zu beenden.
Befehlsausführung
command/exec führt einen einzelnen Befehl (argv-Array) in der Server-Sandbox aus, ohne einen Thread zu erstellen.
{ "method": "command/exec", "id": 50, "params": {
"command": ["ls", "-la"],
"cwd": "/Users/me/project",
"sandboxPolicy": { "type": "workspaceWrite" },
"timeoutMs": 10000
} }
{ "id": 50, "result": { "exitCode": 0, "stdout": "...", "stderr": "" } }Verwenden Sie sandboxPolicy.type = "externalSandbox", wenn Sie den Serverprozess bereits in einer Sandbox ausführen und möchten, dass Codex seine eigene Sandbox-Durchsetzung überspringt. Setzen Sie für den externen Sandbox-Modus networkAccess auf restricted (Standard) oder enabled. Verwenden Sie für readOnly und workspaceWrite dieselbe oben gezeigte optionale Struktur mit access / readOnlyAccess.
Hinweise:
- Der Server lehnt leere
command-Arrays ab. sandboxPolicyakzeptiert dieselbe Struktur wieturn/start(beispielsweisedangerFullAccess,readOnly,workspaceWrite,externalSandbox).- Wenn
timeoutMsnicht angegeben wird, wird der Standardwert des Servers verwendet. - Setzen Sie
tty: truefür PTY-gestützte Sitzungen und verwenden SieprocessId, wenn Sie anschließendcommand/exec/write,command/exec/resizeodercommand/exec/terminateverwenden möchten. - Setzen Sie
streamStdoutStderr: true, um während der Befehlsausführungcommand/exec/outputDelta-Benachrichtigungen zu erhalten.
Administratoranforderungen lesen (configRequirements/read)
Verwenden Sie configRequirements/read, um die wirksamen Administratoranforderungen zu prüfen, die aus requirements.toml und/oder MDM geladen wurden.
{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
"requirements": {
"allowedApprovalPolicies": ["onRequest", "unlessTrusted"],
"allowedSandboxModes": ["readOnly", "workspaceWrite"],
"featureRequirements": {
"personality": true,
"unified_exec": false
},
"network": {
"enabled": true,
"allowedDomains": ["api.openai.com"],
"allowUnixSockets": ["/tmp/example.sock"],
"dangerouslyAllowAllUnixSockets": false
}
}
} }result.requirements ist null, wenn keine Anforderungen konfiguriert sind. Einzelheiten zu unterstützten Schlüsseln und Werten finden Sie in der Dokumentation zu requirements.toml.
Einrichtung der Windows-Sandbox (windowsSandbox/setupStart)
Benutzerdefinierte Windows-Clients können die Einrichtung der Sandbox asynchron auslösen, anstatt auf Startprüfungen zu warten.
{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }App-server startet die Einrichtung im Hintergrund und gibt später eine Abschlussbenachrichtigung aus:
{
"method": "windowsSandbox/setupCompleted",
"params": { "mode": "elevated", "success": true, "error": null }
}Modi:
elevated– führt den Einrichtungspfad der Windows-Sandbox mit erhöhten Berechtigungen aus.unelevated– führt den bisherigen Einrichtungs-/Vorabprüfungspfad aus.
Dateisystem
Die v2-Dateisystem-APIs arbeiten mit absoluten Pfaden. Verwenden Sie fs/watch, wenn ein Client den UI-Status nach einer Änderung an einer Datei oder einem Verzeichnis invalidieren muss.
{ "method": "fs/watch", "id": 54, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"path": "/Users/me/project/.git/HEAD"
} }
{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }
{ "method": "fs/changed", "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"changedPaths": ["/Users/me/project/.git/HEAD"]
} }
{ "method": "fs/unwatch", "id": 55, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"
} }
{ "id": 55, "result": {} }Die Überwachung einer Datei gibt bei Änderungen an diesem Dateipfad fs/changed aus. Dies schließt Aktualisierungen ein, die durch Ersetzungs- oder Umbenennungsvorgänge entstehen.
Ereignisse
Ereignisbenachrichtigungen sind der vom Server initiierte Stream für die Lebenszyklen von Threads und Turns sowie für die darin enthaltenen Elemente. Lesen Sie nach dem Starten oder Fortsetzen eines Threads den aktiven Transportstream weiter, um Benachrichtigungen vom Typ thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* und serverRequest/resolved zu empfangen.
Benachrichtigungen deaktivieren
Clients können bestimmte Benachrichtigungen pro Verbindung unterdrücken, indem sie die exakten Methodennamen in initialize.params.capabilities.optOutNotificationMethods senden.
- Nur exakte Übereinstimmung:
item/agentMessage/deltaunterdrückt ausschließlich diese Methode. - Unbekannte Methodennamen werden ignoriert.
- Gilt für die aktuellen Benachrichtigungen
thread/*,turn/*,item/*und verwandte v2-Benachrichtigungen. - Gilt nicht für Anfragen, Antworten oder Fehler.
Ereignisse der unscharfen Dateisuche (experimentell)
Die Sitzungs-API für die unscharfe Dateisuche gibt pro Abfrage Benachrichtigungen aus:
fuzzyFileSearch/sessionUpdated–{ sessionId, query, files }mit den aktuellen Treffern für die aktive Abfrage.fuzzyFileSearch/sessionCompleted– einmal{ sessionId }, sobald die Indizierung und der Abgleich für diese Abfrage abgeschlossen sind.
Warnereignisse
configWarning–{ summary, details?, path?, range? }für behebbare Konfigurations- oder Initialisierungsprobleme.warning–{ threadId?, message }für nicht schwerwiegende Laufzeitwarnungen.
Ereignisse zur Einrichtung der Windows-Sandbox
windowsSandbox/setupCompleted–{ mode, success, error }, das nach Abschluss einerwindowsSandbox/setupStart-Anfrage ausgegeben wird.
Turn-Ereignisse
turn/started–{ turn }mit der Turn-ID, einem leerenitemsundstatus: "inProgress".turn/completed–{ turn }, wobeiturn.statusden Wertcompleted,interruptedoderfailedhat; bei Fehlern ist{ error: { message, codexErrorInfo?, additionalDetails? } }enthalten.turn/diff/updated–{ threadId, turnId, diff }mit dem neuesten aggregierten einheitlichen Diff über sämtliche Dateiänderungen des Turns.turn/plan/updated–{ turnId, explanation?, plan }, wenn der Agent seinen Plan mitteilt oder ändert; jederplan-Eintrag ist{ step, status }, wobeistatusden Wertpending,inProgressodercompletedhat.hook/startedundhook/completed–{ threadId, turnId?, run }beim Start eines synchronen Lebenszyklus-Hooks beziehungsweise dann, wenn dessen endgültige Ausführungszusammenfassung verfügbar ist. Diese Benachrichtigungen werden bei asynchronen Hooks nicht ausgegeben.model/safetyBuffering/updated–{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }, wenn eine Antwort vorübergehend zur Sicherheitsprüfung gepuffert wird.model/rerouted–{ threadId, turnId, fromModel, toModel, reason }, wenn der Dienst eine Anfrage an ein anderes Modell weiterleitet.model/verification–{ threadId, turnId, verifications }, wenn der Dienst eine zusätzliche Kontoverifizierung verlangt.thread/tokenUsage/updated– Nutzungsaktualisierungen für den aktiven Thread.
turn/diff/updated und turn/plan/updated enthalten derzeit auch dann leere items-Arrays, wenn Elementereignisse gestreamt werden. Verwenden Sie item/*-Benachrichtigungen als maßgebliche Quelle für Turn-Elemente.
Elemente
ThreadItem ist die mit Tags versehene Union, die in Turn-Antworten und item/*-Benachrichtigungen übertragen wird. Zu den gängigen Elementtypen gehören:
userMessage–{id, content}, wobeicontenteine Liste von Benutzereingaben ist (text,imageoderlocalImage).functionCallOutput–{id, name, namespace, output}für eine überturn/start.toolOutputbereitgestellte eigenständige Tool-Ausgabe.namespacekannnullsein.agentMessage–{id, text, phase?}mit der kumulierten Antwort des Agenten. Falls vorhanden, verwendetphasedie Übertragungswerte der Responses API (commentary,final_answer).plan–{id, text}mit dem vorgeschlagenen Plantext im Planmodus. Behandeln Sie das abschließendeplan-Item ausitem/completedals maßgeblich.reasoning–{id, summary, content}, wobeisummarygestreamte Reasoning-Zusammenfassungen undcontentunbearbeitete Reasoning-Blöcke enthält.commandExecution–{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.fileChange–{id, changes, status}zur Beschreibung vorgeschlagener Änderungen;changeslistet{path, kind, diff}auf.mcpToolCall–{id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Bei vertrauenswürdigen MCP-Apps kannappContextdie WerteconnectorId,linkId,resourceUri,appName,templateIdund den stabilen ConnectoractionNameenthalten. Bei älteren persistierten Items können neuere Metadaten fehlen. Verwenden SieappContext.resourceUrianstelle des veralteten WertsmcpAppResourceUriauf oberster Ebene.dynamicToolCall–{id, tool, arguments, status, contentItems?, success?, durationMs?}für vom Client ausgeführte dynamische Tool-Aufrufe.collabToolCall–{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.webSearch–{id, query, action?}für vom Agenten ausgegebene Websuchanfragen.imageView–{id, path}, das ausgegeben wird, wenn der Agent das Tool zur Bildanzeige aufruft.enteredReviewMode–{id, review}, das beim Start des Reviewers gesendet wird.exitedReviewMode–{id, review}, das nach Abschluss des Reviewers ausgegeben wird.contextCompaction–{id}, das ausgegeben wird, wenn Codex den Konversationsverlauf komprimiert.
Für webSearch.action kann die Aktion type den Wert search (query?, queries?), openPage (url?) oder findInPage (url?, pattern?) haben.
App-server stuft die bisherige thread/compacted-Benachrichtigung als veraltet ein; verwenden Sie stattdessen das contextCompaction-Element.
Alle Elemente geben zwei gemeinsame Lebenszyklusereignisse aus:
item/started– gibt das vollständigeitemaus, wenn eine neue Arbeitseinheit beginnt;item.idstimmt mit dem von Deltas verwendetenitemIdüberein.item/completed– sendet das endgültigeitemnach Abschluss der Arbeit; betrachten Sie dies als maßgeblichen Status.
Element-Deltas
item/agentMessage/delta– hängt gestreamten Text an die Agentennachricht an.item/plan/delta– streamt vorgeschlagenen Plantext. Das endgültigeplan-Element entspricht möglicherweise nicht exakt den verketteten Deltas.item/reasoning/summaryTextDelta– streamt lesbare Reasoning-Zusammenfassungen;summaryIndexwird 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 bisherigeapply_patch-Textausgabe. Aktuelle app-server-Versionen geben sie nicht mehr aus; verwenden Sie stattdessenfileChange-Elemente undturn/diff/updated.
Fehler
Wenn ein Turn fehlschlägt, gibt der Server ein error-Ereignis mit { error: { message, codexErrorInfo?, additionalDetails? } } aus und beendet den Turn anschließend mit status: "failed". Wenn ein vorgelagerter HTTP-Status verfügbar ist, erscheint er in codexErrorInfo.httpStatusCode.
Zu den gängigen codexErrorInfo-Werten gehören:
ContextWindowExceededUsageLimitExceededHttpConnectionFailed(vorgelagerte 4xx-/5xx-Fehler)ResponseStreamConnectionFailedResponseStreamDisconnectedResponseTooManyFailedAttemptsBadRequest,Unauthorized,SandboxError,InternalServerError,Other
Wenn ein vorgelagerter HTTP-Status verfügbar ist, leitet der Server ihn in httpStatusCode für die entsprechende codexErrorInfo-Variante weiter.
Genehmigungen
Abhängig von den Codex-Einstellungen eines Benutzers können die Ausführung von Befehlen und Dateiänderungen eine Genehmigung erfordern. App-server sendet eine vom Server initiierte JSON-RPC-Anfrage an den Client, und der Client antwortet mit einer Entscheidungsnutzlast.
Entscheidungen zur Befehlsausführung:
accept,acceptForSession,decline,canceloder{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.Entscheidungen zu Dateiänderungen:
accept,acceptForSession,decline,cancel.Anfragen enthalten
threadIdundturnId– verwenden Sie diese, um den UI-Status auf die aktive Unterhaltung zu begrenzen.Der Server setzt die Arbeit fort oder lehnt sie ab und beendet das Element mit
item/completed.
Genehmigungen zur Befehlsausführung
Reihenfolge der Nachrichten:
item/startedzeigt das ausstehendecommandExecution-Element mitcommand,cwdund weiteren Feldern.item/commandExecution/requestApprovalenthältitemId,threadId,turnId, optionalreason, optionalcommand, optionalcwd, optionalcommandActions, optionalproposedExecpolicyAmendment, optionalnetworkApprovalContextund optionalavailableDecisions. Beiinitialize.params.capabilities.experimentalApi = truekann die Nutzlast außerdem das experimentelleadditionalPermissionsenthalten, das den angeforderten Sandbox-Zugriff pro Befehl beschreibt. Alle Dateisystempfade innerhalb vonadditionalPermissionssind in der Übertragung absolut.- Der Client antwortet mit einer der oben genannten Entscheidungen zur Genehmigung der Befehlsausführung.
serverRequest/resolvedbestätigt, dass die ausstehende Anfrage beantwortet oder gelöscht wurde.item/completedgibt das endgültigecommandExecution-Element mitstatus: completed | failed | declinedzurück.
Wenn networkApprovalContext vorhanden ist, betrifft die Abfrage den verwalteten Netzwerkzugriff (und keine allgemeine Genehmigung eines Shell-Befehls). Das aktuelle v2-Schema stellt das Ziel host und protocol bereit; Clients sollten eine netzwerkspezifische Abfrage darstellen und sich nicht darauf verlassen, dass command eine für den Benutzer aussagekräftige Vorschau des Shell-Befehls ist.
Codex gruppiert gleichzeitig auftretende Abfragen zur Netzwerkfreigabe nach Ziel (host, Protokoll und Port). App-server kann daher eine einzige Abfrage senden, die mehrere ausstehende Anfragen an dasselbe Ziel freigibt, während unterschiedliche Ports desselben Hosts getrennt behandelt werden.
Genehmigungen für Dateiänderungen
Reihenfolge der Nachrichten:
item/startedgibt einfileChange-Element mit den vorgeschlagenen Wertenchangesundstatus: "inProgress"aus.item/fileChange/requestApprovalenthältitemId,threadId,turnId, optionalreasonund optionalgrantRoot.- Der Client antwortet mit einer der oben genannten Entscheidungen zur Genehmigung von Dateiänderungen.
serverRequest/resolvedbestätigt, dass die ausstehende Anfrage beantwortet oder gelöscht wurde.item/completedgibt das endgültigefileChange-Element mitstatus: completed | failed | declinedzurück.
tool/requestUserInput
Wenn der Client auf item/tool/requestUserInput antwortet, gibt app-server serverRequest/resolved mit { threadId, requestId } aus. Wird die ausstehende Anfrage durch den Start, den Abschluss oder die Unterbrechung eines Turns gelöscht, bevor der Client antwortet, gibt der Server dieselbe Benachrichtigung für diese Bereinigung aus.
Die Anfrageparameter enthalten autoResolutionMs als ganzzahliges Zeitlimit in Millisekunden oder
null. Wenn dieser Wert vorhanden ist, können Host-Clients die Abfrage nach diesem
Intervall automatisch auflösen, falls der Benutzer nicht antwortet.
Berechtigungsanfragen
Das integrierte Tool request_permissions sendet
item/permissions/requestApproval mit threadId, turnId, itemId,
environmentId, cwd, optional reason sowie den angeforderten Netzwerk- oder Dateisystemberechtigungen.
Antworten Sie mit permissions, das nur die gewährte Teilmenge enthält.
Setzen Sie scope auf "session", um die Gewährung für spätere Turns derselben
Sitzung beizubehalten; lassen Sie den Wert weg oder verwenden Sie "turn" für eine auf den Turn beschränkte Gewährung. Nicht
angeforderte Berechtigungen werden ignoriert.
Elicitierungsanfragen von MCP-Servern
Ein MCP-Server kann einen Turn mit mcpServer/elicitation/request unterbrechen. Die
Anfrage enthält threadId, ein optionales turnId, serverName und eine der
folgenden Anfragestrukturen:
mode: "form"odermode: "openai/form", mitmessageundrequestedSchema.mode: "url", mitmessage,urlundelicitationId.
Antworten Sie mit action: "accept" und dem angeforderten content oder mit
action: "decline" oder "cancel" und content: null. App-server gibt anschließend
serverRequest/resolved aus. Um die Variante openai/form zu empfangen, aktivieren Sie sie mit
initialize.params.capabilities.mcpServerOpenaiFormElicitation.
Dynamische Tool-Aufrufe (experimentell)
dynamicTools auf thread/start und der zugehörige Anfrage- oder Antwortablauf von item/tool/call sind experimentelle APIs.
Die Namen dynamischer Tools und Namespaces müssen den Namensvorgaben der Responses API entsprechen. Vermeiden Sie reservierte Namespace-Namen, die von integrierten Codex-Tools verwendet werden.
Wenn während eines Turns ein dynamisches Tool aufgerufen wird, gibt app-server Folgendes aus:
item/startedmititem.type = "dynamicToolCall",status = "inProgress"sowietoolundarguments.item/tool/callals Serveranfrage an den Client.- Die Antwortnutzlast des Clients mit den zurückgegebenen Inhaltselementen.
item/completedmititem.type = "dynamicToolCall", dem endgültigenstatussowie allen zurückgegebenen WertencontentItemsodersuccess.
Genehmigungen für MCP-Tool-Aufrufe (Apps)
Tool-Aufrufe von Apps (Connectors) können ebenfalls eine Genehmigung erfordern. Wenn ein App-Tool-Aufruf Nebenwirkungen hat, kann der Server mit tool/requestUserInput und Optionen wie Akzeptieren, Ablehnen und Abbrechen um eine Genehmigung bitten. Destruktive Tool-Annotationen lösen immer eine Genehmigungsabfrage aus, selbst wenn das Tool zugleich Hinweise auf weniger weitreichende Berechtigungen angibt. Wenn der Benutzer ablehnt oder abbricht, wird das zugehörige mcpToolCall-Element mit einem Fehler abgeschlossen, ohne das Tool auszuführen.
Skills
Rufen Sie einen Skill auf, indem Sie $<skill-name> in die Texteingabe aufnehmen. Fügen Sie ein skill-Eingabeelement hinzu (empfohlen), damit der Server die vollständigen Skill-Anweisungen einfügt, anstatt das Modell den Namen auflösen zu lassen.
{
"method": "turn/start",
"id": 101,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$skill-creator Add a new skill for triaging flaky CI."
},
{
"type": "skill",
"name": "skill-creator",
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
}
]
}
}Wenn Sie das skill-Element weglassen, analysiert das Modell dennoch die $<skill-name>-Markierung und versucht, den Skill zu finden, was die Latenz erhöhen kann.
Beispiel:
$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage.Verwenden Sie skills/list, um verfügbare Skills abzurufen (optional nach cwds eingeschränkt, mit forceReload). Sie können auch perCwdExtraUserRoots angeben, um zusätzliche absolute Pfade als user-Bereich für bestimmte cwd-Werte zu durchsuchen. App-server ignoriert Einträge, deren cwd nicht in cwds enthalten ist. skills/list kann ein zwischengespeichertes Ergebnis pro cwd wiederverwenden; setzen Sie forceReload: true, um die Daten vom Datenträger zu aktualisieren. Wenn vorhanden, liest der Server interface und dependencies aus SKILL.json.
{ "method": "skills/list", "id": 25, "params": {
"cwds": ["/Users/me/project", "/Users/me/other-project"],
"forceReload": true,
"perCwdExtraUserRoots": [
{
"cwd": "/Users/me/project",
"extraUserRoots": ["/Users/me/shared-skills"]
}
]
} }
{ "id": 25, "result": {
"data": [{
"cwd": "/Users/me/project",
"skills": [
{
"name": "skill-creator",
"description": "Create or update a Codex skill",
"enabled": true,
"interface": {
"displayName": "Skill Creator",
"shortDescription": "Create or update a Codex skill"
},
"dependencies": {
"tools": [
{
"type": "env_var",
"value": "GITHUB_TOKEN",
"description": "GitHub API token"
},
{
"type": "mcp",
"value": "github",
"transport": "streamable_http",
"url": "https://example.com/mcp"
}
]
}
}
],
"errors": []
}]
} }Der Server gibt außerdem skills/changed-Benachrichtigungen aus, wenn sich überwachte lokale Skill-Dateien ändern. Behandeln Sie dies als Invalidierungssignal und führen Sie skills/list bei Bedarf erneut mit Ihren aktuellen Parametern aus.
So aktivieren oder deaktivieren Sie einen Skill anhand seines Pfads:
{
"method": "skills/config/write",
"id": 26,
"params": {
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
"enabled": false
}
}Apps (Connectors)
Verwenden Sie app/installed, um den neuesten festgeschriebenen Laufzeit-Snapshot der installierten Apps zu lesen.
Jedes Ergebnis enthält die App id, runtimeName (oder null), den wirksamen
enabled-Status und den callable-Status. Eine App kann nur aufgerufen werden, wenn sie durch die wirksame
Konfiguration aktiviert ist und mindestens ein für das Modell sichtbares Tool den
App- und Tool-Richtlinien entspricht.
{
"method": "app/installed",
"id": 49,
"params": {
"threadId": "thread-1",
"forceRefresh": false
}
}
{
"id": 49,
"result": {
"apps": [
{
"id": "demo-app",
"runtimeName": "Demo App",
"enabled": true,
"callable": true
}
]
}
}Lassen Sie threadId weg, um anstelle der Konfiguration eines geladenen Threads die globale Konfiguration zu verwenden.
Setzen Sie forceRefresh: true, um den Laufzeit-Snapshot des Connectors vor dem Lesen
zu aktualisieren. Wenn eine globale oder Workspace-Richtlinie den App-Zugriff sperrt,
kann eine erkannte App dennoch erscheinen, wobei enabled und callable auf false gesetzt sind.
Verwenden Sie app/list, um verfügbare Apps abzurufen. In CLI/TUI ist /apps die benutzerseitige Auswahloberfläche; rufen Sie in benutzerdefinierten Clients app/list direkt auf. Jeder Eintrag enthält sowohl isAccessible (für den Benutzer verfügbar) als auch isEnabled (in config.toml aktiviert), damit Clients zwischen Installation/Zugriff und lokalem Aktivierungsstatus unterscheiden können. App-Einträge können außerdem die optionalen Felder branding, appMetadata und labels enthalten.
{ "method": "app/list", "id": 50, "params": {
"cursor": null,
"limit": 50,
"threadId": "thread-1",
"forceRefetch": false
} }
{ "id": 50, "result": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
],
"nextCursor": null
} }Wenn Sie threadId angeben, verwendet das Feature-Gating der App (features.apps) den Konfigurations-Snapshot dieses Threads. Wird der Wert weggelassen, verwendet app-server die neueste globale Konfiguration.
app/list wird zurückgegeben, nachdem sowohl zugängliche Apps als auch Verzeichnis-Apps geladen wurden. Setzen Sie forceRefetch: true, um App-Caches zu umgehen und aktuelle Daten abzurufen. Cache-Einträge werden nur ersetzt, wenn die Aktualisierung erfolgreich ist.
Der Server gibt außerdem app/list/updated-Benachrichtigungen aus, wenn eine der beiden Quellen (zugängliche Apps oder Verzeichnis-Apps) vollständig geladen wurde. Jede Benachrichtigung enthält die aktuelle zusammengeführte App-Liste.
{
"method": "app/list/updated",
"params": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
]
}
}Verwenden Sie app/read, wenn Sie die App-IDs bereits kennen und App-Metadaten anstelle
des installierten Laufzeitstatus benötigen. Übergeben Sie höchstens 100 appIds. Der Server behält nur
das jeweils erste Vorkommen einer wiederholten ID bei und bewahrt diese Reihenfolge sowohl in
apps als auch in missingAppIds. Unbekannte oder unzugängliche Apps werden in
missingAppIds zurückgegeben, ohne dass die gesamte Anfrage fehlschlägt.
{
"method": "app/read",
"id": 52,
"params": {
"appIds": ["demo-app", "missing-app"],
"includeTools": true
}
}
{
"id": 52,
"result": {
"apps": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"iconUrl": null,
"iconUrlDark": null,
"distributionChannel": null,
"installUrl": null,
"pluginDisplayNames": [],
"toolSummaries": [
{
"name": "search",
"title": "Search",
"description": "Search the app.",
"isEnabled": true,
"disabledReason": null,
"isReadOnly": true
}
]
}
],
"missingAppIds": ["missing-app"]
}
}Setzen Sie includeTools: true, um ausschließlich zur Anzeige bestimmte öffentliche Tool-Zusammenfassungen anzufordern. Die
Metadatenantwort enthält weder den Laufzeitstatus installierter Apps noch autorisiert sie einen
Tool-Aufruf; verwenden Sie app/installed, um den wirksamen enabled- und callable-Status
zu prüfen.
Rufen Sie eine App auf, indem Sie $<app-slug> in die Texteingabe einfügen und ein mention-Eingabeelement mit dem app://<id>-Pfad hinzufügen (empfohlen).
{
"method": "turn/start",
"id": 51,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$demo-app Pull the latest updates from the team."
},
{
"type": "mention",
"name": "Demo App",
"path": "app://demo-app"
}
]
}
}Beispiele für Konfigurations-RPCs für App-Einstellungen
Verwenden Sie config/read, config/value/write und config/batchWrite, um App-Steuerelemente in config.toml zu prüfen oder zu aktualisieren.
Lesen Sie die wirksame Struktur der App-Konfiguration (einschließlich _default und Überschreibungen pro Tool):
{ "method": "config/read", "id": 60, "params": { "includeLayers": false } }
{ "id": 60, "result": {
"config": {
"apps": {
"_default": {
"enabled": true,
"destructive_enabled": true,
"open_world_enabled": true,
"approvals_reviewer": "user",
"default_tools_approval_mode": "auto"
},
"google_drive": {
"enabled": true,
"destructive_enabled": false,
"approvals_reviewer": "auto_review",
"default_tools_approval_mode": "prompt",
"tools": {
"files/delete": { "enabled": false, "approval_mode": "approve" }
}
}
}
}
} }apps._default.approvals_reviewer legt den Reviewer für alle Apps fest, sofern dieser Wert nicht
für eine einzelne App überschrieben wird. Wenn beide Angaben fehlen, übernimmt die App den
übergeordneten Wert approvals_reviewer. apps._default.default_tools_approval_mode
legt den Rückfall-Genehmigungsmodus für Tools ohne Überschreibung pro App oder pro Tool
fest. Verwaltete Anforderungen an den Genehmigungsmodus haben Vorrang vor den
Genehmigungsmoduseinstellungen der Tools.
Eine einzelne App-Einstellung aktualisieren:
{
"method": "config/value/write",
"id": 61,
"params": {
"keyPath": "apps.google_drive.default_tools_approval_mode",
"value": "prompt",
"mergeStrategy": "replace"
}
}Mehrere App-Änderungen atomar anwenden:
{
"method": "config/batchWrite",
"id": 62,
"params": {
"edits": [
{
"keyPath": "apps._default.destructive_enabled",
"value": false,
"mergeStrategy": "upsert"
},
{
"keyPath": "apps.google_drive.tools.files/delete.approval_mode",
"value": "approve",
"mergeStrategy": "upsert"
}
]
}
}Konfiguration externer Agenten erkennen und importieren
Verwenden Sie externalAgentConfig/detect, um migrierbare Artefakte externer Agenten zu erkennen, und übergeben Sie die ausgewählten Einträge anschließend an externalAgentConfig/import.
Erkennungsbeispiel:
{ "method": "externalAgentConfig/detect", "id": 63, "params": {
"includeHome": true,
"cwds": ["/Users/me/project"]
} }
{ "id": 63, "result": {
"items": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
},
{
"itemType": "SKILLS",
"description": "Copy skill folders from /Users/me/.claude/skills to /Users/me/.agents/skills.",
"cwd": null
}
]
} }Importbeispiel:
{ "method": "externalAgentConfig/import", "id": 64, "params": {
"migrationItems": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
}
],
"source": "claude-code"
} }
{ "id": 64, "result": { "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868" } }Der optionale Importparameter source auf oberster Ebene bezeichnet das Produkt, das
die ausgewählten Migrationselemente erzeugt hat.
Der Server gibt externalAgentConfig/import/progress aus, sobald einzelne Elementtypen abgeschlossen sind,
und externalAgentConfig/import/completed, nachdem alle synchronen und im Hintergrund ausgeführten
Importe abgeschlossen sind. Diese Benachrichtigungen enthalten dasselbe importId wie die
Antwort sowie itemTypeResults mit successes und failures pro Typ.
Der Abschluss kann unmittelbar nach der Antwort oder erst nach Abschluss entfernter
Hintergrundimporte eintreten.
{ "method": "externalAgentConfig/import/progress", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }
{ "method": "externalAgentConfig/import/completed", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }Frühere abgeschlossene Importe lesen:
{ "method": "externalAgentConfig/import/readHistories", "id": 65 }
{ "id": 65, "result": { "data": [
{
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"completedAtMs": 1781784000000,
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
] } }Unterstützte itemType-Werte sind AGENTS_MD, CONFIG, SKILLS, PLUGINS,
MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS und SESSIONS. Bei
PLUGINS-Elementen listet details.plugins jedes marketplaceName und das
pluginNames auf, dessen Migration Codex versuchen kann. Die Erkennung gibt nur Elemente zurück, bei denen noch
Arbeit aussteht. Codex überspringt beispielsweise die AGENTS-Migration, wenn AGENTS.md
bereits vorhanden und nicht leer ist; Skill-Importe überschreiben keine vorhandenen
Skill-Verzeichnisse.
Beim Erkennen von Plugins aus .claude/settings.json liest Codex die konfigurierten
Marketplace-Quellen aus extraKnownMarketplaces. Wenn enabledPlugins
Plugins aus claude-plugins-official enthält, die Marketplace-Quelle jedoch fehlt,
leitet Codex anthropics/claude-plugins-official als Quelle ab.
Auth-Endpunkte
Die JSON-RPC-Oberfläche für Authentifizierung und Konten stellt Anfrage-/Antwortmethoden sowie vom Server initiierte Benachrichtigungen bereit (kein id). Verwenden Sie diese, um den Authentifizierungsstatus zu ermitteln, Anmeldungen zu starten oder abzubrechen, sich abzumelden, ChatGPT-Ratenlimits zu prüfen und Workspace-Eigentümer über aufgebrauchte Guthaben oder erreichte Nutzungslimits zu benachrichtigen.
Authentifizierungsmodi
Codex unterstützt die folgenden Authentifizierungsmodi. account/updated.authMode zeigt den aktiven Modus an und enthält, sofern verfügbar, das aktuelle ChatGPT-planType. account/read meldet außerdem Konto- und Tarifdetails.
- API key (
apikey) – der Aufrufer stellt mittype: "apiKey"einen OpenAI API key bereit, den Codex für API-Anfragen speichert. - Von ChatGPT verwaltet (
chatgpt) – Codex verwaltet den ChatGPT-OAuth-Ablauf, speichert Tokens dauerhaft und aktualisiert sie automatisch. Beginnen Sie mittype: "chatgpt"für den Browserablauf oder mittype: "chatgptDeviceCode"für den Gerätecode-Ablauf. - Externe ChatGPT-Tokens (
chatgptAuthTokens) – experimentell und für Host-Apps vorgesehen, die den Authentifizierungslebenszyklus des Benutzers für ChatGPT bereits selbst verwalten. Die Host-App stelltaccessToken,chatgptAccountIdund optionalchatgptPlanTypedirekt bereit und muss das Token auf Anforderung aktualisieren. - Amazon Bedrock –
account/readmeldet Bedrock-Konten alstype: "amazonBedrock"und gibt an, ob die Anmeldedaten von einem durch Codex verwalteten Bedrock API key (credentialSource: "codexManaged") oder aus der externen AWS-Anmeldedatenkette (credentialSource: "awsManaged") stammen.account/updated.authModeverwendetbedrockApiKeyfür durch Codex verwaltete Bedrock API keys.
API-Übersicht
account/read– aktuelle Kontoinformationen abrufen; Tokens optional aktualisieren.account/login/start– Anmeldung beginnen (apiKey,chatgpt,chatgptDeviceCodeoder experimentellchatgptAuthTokens).account/login/completed(Benachrichtigung) – wird ausgegeben, wenn ein Anmeldeversuch abgeschlossen ist (erfolgreich oder mit Fehler).account/login/cancel– eine ausstehende, verwaltete ChatGPT-Anmeldung anhand vonloginIdabbrechen.account/logout– abmelden; löstaccount/updatedaus.account/updated(Benachrichtigung) – wird bei jeder Änderung des Authentifizierungsmodus ausgegeben (authMode:apikey,chatgpt,chatgptAuthTokens,agentIdentity,personalAccessToken,bedrockApiKeyodernull) und enthält, sofern verfügbar,planType.account/chatgptAuthTokens/refresh(Serveranfrage) – nach einem Autorisierungsfehler neue extern verwaltete ChatGPT-Tokens anfordern.account/rateLimits/read– ChatGPT-Ratenlimits abrufen.account/rateLimits/updated(Benachrichtigung) – wird bei jeder Änderung der ChatGPT-Ratenlimits eines Benutzers ausgegeben.account/sendAddCreditsNudgeEmail– ChatGPT anweisen, einen Workspace-Eigentümer per E-Mail über aufgebrauchte Guthaben oder ein erreichtes Nutzungslimit zu informieren.account/rateLimitResetCredit/consume– eine verdiente Zurücksetzung des Ratenlimits unter Verwendung eines vom Aufrufer bereitgestelltenidempotencyKey-Werts einlösen.account/usage/read– Zusammenfassungen der Token-Aktivität und Tagesintervalle für das ChatGPT-Konto abrufen.account/workspaceMessages/read– aktive Workspace-Nachrichten einschließlich Benachrichtigungsüberschriften abrufen, sofern verfügbar.mcpServer/oauthLogin/completed(Benachrichtigung) – wird nach Abschluss einesmcpServer/oauth/login-Ablaufs ausgegeben; die Nutzlast enthält{ name, threadId, success, error? }.threadIdkann bei App-bezogenen oder Plugin-OAuth-Abläufen den Wertnullhaben.mcpServer/startupStatus/updated(Benachrichtigung) – wird ausgegeben, wenn sich der Startstatus eines konfigurierten MCP-Servers ändert; die Nutzlast enthält{ threadId, name, status, error, failureReason }. Bei einem App-bezogenen Start istthreadIdgleichnull. Wenn der Start fehlschlägt, bedeutetfailureReason: "reauthenticationRequired", dass gespeicherte OAuth-Anmeldedaten abgelaufen sind und nicht aktualisiert werden konnten. Der Client sollte daher anbieten, die Verbindung zum Server erneut herzustellen.
1) Authentifizierungsstatus prüfen
Anfrage:
{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }Antwortbeispiele:
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } }{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } }{
"id": 1,
"result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true }
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "codexManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "awsManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "chatgpt",
"email": "user@example.com",
"planType": "pro"
},
"requiresOpenaiAuth": true
}
}Hinweise zu den Feldern:
refreshToken(boolescher Wert): Setzen Sietrue, um im verwalteten ChatGPT-Modus eine Token-Aktualisierung zu erzwingen. Im Modus für externe Tokens (chatgptAuthTokens) ignoriert app-server dieses Flag.emailistnull, wenn das ChatGPT-Konto keine E-Mail-Adresse hat.requiresOpenaiAuthgibt den aktiven Anbieter wieder; beifalsekann 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 escredentialSource: "awsManaged". Dies identifiziert die ausgewählte Quelle der Anmeldedaten; es bestätigt nicht, dass die AWS-Anmeldedatenkette Anmeldedaten auflösen kann.
2) Mit einem API key anmelden
- Senden Sie:
{
"method": "account/login/start",
"id": 2,
"params": { "type": "apiKey", "apiKey": "sk-..." }
}- Erwartete Antwort:
{ "id": 2, "result": { "type": "apiKey" } }- 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)
- Starten Sie den Vorgang:
{
"method": "account/login/start",
"id": 3,
"params": {
"type": "chatgpt",
"useHostedLoginSuccessPage": true,
"appBrand": "chatgpt"
}
} Standardmäßig leitet ein erfolgreicher Browser-Callback zu einer lokalen Erfolgsseite weiter.
Setzen Sie useHostedLoginSuccessPage: true, um die gehostete Erfolgsseite zu verwenden, wenn
keine Organisationseinrichtung erforderlich ist. Bei aktivierter gehosteter Erfolgsseite kann appBrand
den Wert "codex" oder "chatgpt" haben; fehlende Werte oder null verwenden standardmäßig
"codex".
{
"id": 3,
"result": {
"type": "chatgpt",
"loginId": "<uuid>",
"authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
}
}- Öffnen Sie
authUrlin einem Browser; app-server stellt den lokalen Callback bereit. - Warten Sie auf Benachrichtigungen:
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3b) Mit ChatGPT anmelden (Gerätecode-Ablauf)
Verwenden Sie diesen Ablauf, wenn Ihr Client den Anmeldevorgang steuert oder ein Browser-Callback unzuverlässig ist.
- Starten Sie den Vorgang:
{
"method": "account/login/start",
"id": 4,
"params": { "type": "chatgptDeviceCode" }
} {
"id": 4,
"result": {
"type": "chatgptDeviceCode",
"loginId": "<uuid>",
"verificationUrl": "https://auth.openai.com/codex/device",
"userCode": "ABCD-1234"
}
}- Zeigen Sie dem Benutzer
verificationUrlunduserCodean; das Frontend steuert die UX. - Warten Sie auf Benachrichtigungen:
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3c) Mit extern verwalteten ChatGPT-Tokens anmelden (chatgptAuthTokens)
Verwenden Sie diesen experimentellen Modus nur, wenn eine Host-Anwendung den Authentifizierungslebenszyklus des Benutzers für ChatGPT verwaltet und Tokens direkt bereitstellt. Clients müssen während initialize den Wert capabilities.experimentalApi = true setzen, bevor sie diesen Anmeldetyp verwenden.
- Senden Sie:
{
"method": "account/login/start",
"id": 7,
"params": {
"type": "chatgptAuthTokens",
"accessToken": "<jwt>",
"chatgptAccountId": "org-123",
"chatgptPlanType": "business"
}
}- Erwartete Antwort:
{ "id": 7, "result": { "type": "chatgptAuthTokens" } }- Benachrichtigungen:
{
"method": "account/login/completed",
"params": { "loginId": null, "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgptAuthTokens", "planType": "business" }
}Wenn der Server ein 401 Unauthorized empfängt, kann er aktualisierte Tokens von der Host-App anfordern:
{
"method": "account/chatgptAuthTokens/refresh",
"id": 8,
"params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }Nach einer erfolgreichen Aktualisierungsantwort wiederholt der Server die ursprüngliche Anfrage. Anfragen laufen nach etwa 10 Sekunden ab.
4) ChatGPT-Anmeldung abbrechen
{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }5) Abmelden
{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }6) Ratenlimits (ChatGPT)
{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": {
"rateLimits": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"rateLimitsByLimitId": {
"codex": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"codex_other": {
"limitId": "codex_other",
"limitName": "codex_other",
"primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },
"secondary": null,
"rateLimitReachedType": null
}
},
"rateLimitResetCredits": {
"availableCount": 2,
"credits": [{
"id": "RateLimitResetCredit_1",
"resetType": "codexRateLimits",
"status": "available",
"grantedAt": 1781654400,
"expiresAt": 1784246400,
"title": "Rate-limit reset",
"description": "Reset an eligible Codex rate-limit window."
}]
}
} }
{ "method": "account/rateLimits/updated", "params": {
"rateLimits": {
"limitId": "codex",
"primary": { "usedPercent": 31, "windowDurationMins": 15, "resetsAt": 1730948100 }
}
} }Hinweise zu den Feldern:
rateLimitsist die abwärtskompatible Ansicht eines einzelnen Kontingents.rateLimitsByLimitId(sofern vorhanden) ist die Ansicht mehrerer Kontingente, die nach dem abgerechnetenlimit_id(beispielsweisecodex) indiziert ist.limitIdist die Kennung des abgerechneten Kontingents.limitNameist eine optionale, benutzerseitig sichtbare Bezeichnung des Kontingents.usedPercentist die aktuelle Nutzung innerhalb des Kontingentzeitraums.windowDurationMinsist die Länge des Kontingentzeitraums.resetsAtist ein Unix-Zeitstempel (Sekunden) für die nächste Zurücksetzung.planTypeist enthalten, wenn der Server den einem Kontingent zugeordneten ChatGPT-Tarif zurückgibt.creditsist enthalten, wenn der Server Details zum verbleibenden Workspace-Guthaben zurückgibt.rateLimitReachedTypebezeichnet den vom Server klassifizierten Limitstatus, wenn ein Limit erreicht wurde.rateLimitResetCreditsenthält die Anzahl der verfügbaren verdienten Zurücksetzungen, wenn der Dienst sie bereitstellt; andernfalls ist der Wertnull.rateLimitResetCredits.creditsistnull, wenn nur die Anzahl bekannt ist. Ein leeres Array bedeutet, dass der Dienst Details abgerufen und keine verfügbaren Guthaben zurückgegeben hat. Der Dienst kann die Anzahl der Detailzeilen begrenzen; daher istavailableCountmaßgeblich.- Jede Detailzeile enthält ein undurchsichtiges
id,resetType,status,grantedAt,expiresAt(kannnullsein),title(kannnullsein) unddescription(kannnullsein). - Rufen Sie
account/rateLimits/readab, nachdem Sie eine Zurücksetzung eingelöst haben.
7) Token-Nutzung (ChatGPT)
Verwenden Sie account/usage/read, um Zusammenfassungsfelder zur ChatGPT-Token-Aktivität und
optionale Tagesintervalle abzurufen.
{ "method": "account/usage/read", "id": 7 }
{ "id": 7, "result": {
"summary": {
"lifetimeTokens": 1234567,
"peakDailyTokens": 45678,
"longestRunningTurnSec": 540,
"currentStreakDays": 8,
"longestStreakDays": 14
},
"dailyUsageBuckets": [
{ "startDate": "2026-06-18", "tokens": 12345 }
]
} }Hinweise zu den Feldern:
summary-Werte könnennullsein, wenn der Dienst diese Kennzahl nicht zurückgegeben hat.dailyUsageBucketskannnullsein; sofern vorhanden, enthält jedes IntervallstartDateundtokens.- Der Endpunkt erfordert eine Authentifizierung, die durch Codex-Dienste gestützt wird. ChatGPT, externe ChatGPT-Tokens, Agentenidentität und die Authentifizierung mit einem persönlichen Zugriffstoken funktionieren; eine reine API-key- oder Bedrock-Authentifizierung nicht.
8) Verdiente Zurücksetzungen des Ratenlimits (ChatGPT)
Verwenden Sie account/rateLimitResetCredit/consume, um eine verdiente Zurücksetzung einzulösen.
{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }Hinweise zu den Feldern:
idempotencyKeydarf nicht leer sein. Verwenden Sie für jeden logischen Einlösungsversuch eine UUID und bei Wiederholungen desselben Versuchs erneut denselben Wert.creditIdist optional. Wenn angegeben, muss der Wert eine nicht leere, undurchsichtige ID ausaccount/rateLimits/readsein. Wird er weggelassen, wählt der Dienst das nächste verfügbare Guthaben aus.resetbedeutet, dass ein Guthaben eingelöst wurde.alreadyRedeemedbedeutet, dass dieselbe Einlösung bereits zuvor abgeschlossen wurde. Behandeln Sie dies als idempotenten Erfolg und aktualisieren Sie die Kontolimits.nothingToResetbedeutet, dass kein geeignetes Ratenlimit-Zeitfenster für eine Zurücksetzung vorhanden ist.noCreditbedeutet, dass für das Konto keine verdienten Zurücksetzungsguthaben verfügbar sind.- Rufen Sie nach dem Einlösen einer Zurücksetzung
account/rateLimits/readab, anstatt aktualisierte Zeitfenster aus dieser Antwort abzuleiten.
9) Workspace-Eigentümer über ein Limit benachrichtigen
Verwenden Sie account/sendAddCreditsNudgeEmail, um ChatGPT anzuweisen, einen Workspace-Eigentümer per E-Mail zu benachrichtigen, wenn Guthaben aufgebraucht sind oder ein Nutzungslimit erreicht wurde.
{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }Verwenden Sie creditType: "credits", wenn das Workspace-Guthaben aufgebraucht ist, oder creditType: "usage_limit", wenn das Nutzungslimit des Workspace erreicht wurde. Wenn der Eigentümer vor Kurzem bereits benachrichtigt wurde, lautet der Antwortstatus cooldown_active.
10) Workspace-Nachrichten (ChatGPT)
Verwenden Sie account/workspaceMessages/read, um aktive Nachrichten für den aktuellen
Workspace einschließlich Benachrichtigungsüberschriften abzurufen, sofern verfügbar.
{ "method": "account/workspaceMessages/read", "id": 10 }
{ "id": 10, "result": { "featureEnabled": true, "messages": [
{ "messageId": "msg_123", "messageType": "headline", "messageBody": "Workspace maintenance starts at 5pm.", "createdAt": 1781395200, "archivedAt": null }
] } }