Codex app-server es la interfaz que usa Codex para ofrecer funciones avanzadas en clientes como la extensión de Codex para VS Code. Úsala para integrar la autenticación, el historial de conversaciones, las aprobaciones y la transmisión de eventos del agente en tu propio producto. La implementación de app-server es de código abierto y está en el repositorio de Codex en GitHub (openai/codex/codex-rs/app-server). Consulta la página de código abierto para ver la lista completa de componentes de código abierto de Codex.
Si automatizas tareas o ejecutas Codex en CI, usa el SDK de Codex.
Conectar la interfaz de terminal de la CLI
El modo remoto de la interfaz de terminal te permite ejecutar app-server en una máquina y conectar la interfaz de terminal de la CLI de Codex desde otra. Inicia la escucha de conexiones WebSocket:
codex app-server --listen ws://127.0.0.1:4500
Luego conecta la interfaz de terminal:
codex --remote ws://127.0.0.1:4500
Para una conexión que no sea local, configura la autenticación WebSocket y protege la conexión con TLS. Guarda el token de portador en una variable de entorno y pasa el nombre de la variable para evitar escribir el token en la línea de comandos:
export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
--remote-auth-token-env CODEX_REMOTE_TOKEN
La opción --remote acepta puntos de acceso ws://, wss://, unix:// y unix://PATH. Usa WebSockets sin cifrar solo para localhost o para conexiones con reenvío de puertos por SSH.
Conectar un host remoto de Code Mode
De forma predeterminada, app-server inicia un host local de Code Mode. Para compartir un host remoto entre los hilos de un mismo proceso de app-server, pasa el punto de acceso gRPC sobre HTTP/2 del host remoto a --code-mode-host.
codex app-server --code-mode-host https://code-mode.example.com
Usa HTTPS para proteger los argumentos y los resultados de las herramientas cuando te conectes a un host remoto. Usa HTTP solo en la interfaz de loopback o a través de un túnel seguro. La URL admite un nombre de host y un puerto opcional. Omite las credenciales, las rutas, las cadenas de consulta y los fragmentos. Usa --listen para configurar por separado la conexión de los clientes a app-server.
Protocolo
Al igual que MCP, codex app-server admite la comunicación bidireccional mediante mensajes JSON-RPC 2.0 (el encabezado "jsonrpc":"2.0" se omite en la transmisión).
Transportes admitidos:
stdio(--listen stdio://, predeterminado): JSON delimitado por saltos de línea (JSONL).websocket(--listen ws://IP:PORT, experimental y sin soporte): un mensaje JSON-RPC por trama de texto WebSocket.- Socket Unix (
--listen unix://o--listen unix://PATH): conexiones WebSocket a través del socket de control predeterminado de app-server de Codex o de una ruta de socket Unix personalizada, mediante la negociación estándar HTTP Upgrade. off(--listen off): no expone ningún transporte local.
Cuando ejecutas el servidor con --listen ws://IP:PORT, el mismo servicio de escucha también atiende comprobaciones básicas de estado por HTTP:
GET /readyzdevuelve200 OKuna vez que el servicio de escucha acepta conexiones nuevas.GET /healthzdevuelve200 OKcuando la solicitud no incluye un encabezadoOrigin.- Las solicitudes con un encabezado
Originse rechazan con403 Forbidden.
El transporte WebSocket es experimental y no tiene soporte. Los servicios de escucha locales como ws://127.0.0.1:PORT son adecuados para localhost y para flujos de trabajo con reenvío de puertos por SSH. Durante el despliegue, los servicios de escucha WebSocket en interfaces que no son de loopback permiten conexiones sin autenticar de forma predeterminada. Configura la autenticación WebSocket antes de exponer uno de forma remota.
Opciones de autenticación WebSocket admitidas:
--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
Para los tokens de portador firmados, también puedes configurar --ws-issuer, --ws-audience y --ws-max-clock-skew-seconds. Los clientes presentan la credencial como Authorization: Bearer <token> durante la negociación WebSocket, y app-server exige autenticación antes de la solicitud JSON-RPC initialize.
Es preferible usar --ws-token-file a pasar tokens de portador directamente en la línea de comandos. Usa --ws-token-sha256 solo cuando el cliente guarde el token original de alta entropía en un almacén local de secretos independiente. El hash solo sirve para verificar el token y los clientes siguen necesitando el original.
En modo WebSocket, app-server usa colas de capacidad limitada. Cuando se llena la cola de solicitudes entrantes, el servidor rechaza las solicitudes nuevas con el código de error JSON-RPC -32001 y el mensaje "Server overloaded; retry later.". Los clientes deben reintentar con intervalos de espera que aumenten de forma exponencial e incluyan una variación aleatoria.
Esquema de mensajes
Las solicitudes incluyen method, params e id.
Los ejemplos usan GPT-6.1 Sol. La cuenta o el espacio de trabajo donde iniciaste sesión debe tener acceso al modelo. Si es necesario, usa model/list para seleccionar un modelo disponible.
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-6.1-sol" } }Las respuestas devuelven el mismo id junto con result o error:
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }
{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }
Las notificaciones omiten id y solo usan method y params:
{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }
Puedes generar un esquema de TypeScript o un paquete de esquemas JSON Schema desde la CLI. Los artefactos generados corresponden exactamente a la versión de Codex con la que ejecutaste el comando:
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemas
Primeros pasos
- Inicia el servidor con
codex app-server(transporte stdio predeterminado),codex app-server --listen ws://127.0.0.1:4500(WebSocket sobre TCP) ocodex app-server --listen unix://(socket Unix predeterminado). - Conecta un cliente mediante el transporte seleccionado. Luego envía
initializeseguido de la notificacióninitialized. - Inicia un hilo y un turno. Sigue leyendo las notificaciones del flujo de transporte activo.
Ejemplo (Node.js / TypeScript):
import { spawn } from "node:child_process";
import readline from "node:readline";
const proc = spawn("codex", ["app-server"], {
stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
const msg = JSON.parse(line) as any;
console.log("server:", msg);
if (msg.id === 0 && msg.result) {
send({ method: "initialized", params: {} });
send({
method: "thread/start",
id: 1,
params: { model: "gpt-6.1-sol" },
});
}
if (msg.method === "turn/completed") {
if (msg.params?.turn?.status !== "completed") {
console.error(msg.params?.turn?.error ?? "The turn did not complete.");
process.exitCode = 1;
}
proc.stdin.end();
rl.close();
}
if (msg.error) {
console.error(msg.error);
process.exitCode = 1;
proc.stdin.end();
rl.close();
}
if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
threadId = msg.result.thread.id;
send({
method: "turn/start",
id: 2,
params: {
threadId,
input: [{ type: "text", text: "Summarize this repo." }],
},
});
}
});
send({
method: "initialize",
id: 0,
params: {
clientInfo: {
name: "my_product",
title: "My Product",
version: "0.1.0",
},
},
});
proc.on("error", (error) => {
console.error(error);
process.exitCode = 1;
rl.close();
});
proc.on("exit", (code) => {
if (code !== 0) process.exitCode = code ?? 1;
});Conceptos básicos
- Hilo: conversación entre un usuario y el agente de Codex. Los hilos contienen turnos.
- Turno: una solicitud del usuario y el trabajo que realiza el agente a continuación. Los turnos contienen elementos y transmiten actualizaciones incrementales.
- Elemento: unidad de entrada o salida, como un mensaje del usuario o del agente, una ejecución de comando, un cambio en un archivo o una llamada a una herramienta.
Usa las API de hilos para crear, enumerar o archivar conversaciones. Usa las API de turnos para hacer avanzar una conversación y las notificaciones de turno para transmitir el progreso.
Ciclo de vida
- Inicializa una vez por conexión: inmediatamente después de abrir una conexión de transporte, envía una solicitud
initializecon los metadatos del cliente y luego emiteinitialized. El servidor rechaza cualquier solicitud que reciba en esa conexión antes de esta negociación. - Inicia o reanuda un hilo: llama a
thread/startpara iniciar una conversación, athread/resumepara continuar una existente o athread/forkpara crear una rama del historial con un nuevo ID de hilo. - Inicia un turno: llama a
turn/startcon elthreadIdde destino y la entrada del usuario. Los campos opcionales permiten cambiar el modelo, el directorio de trabajo y la política del sandbox. - Redirige un turno activo: llama a
turn/steerpara agregar entrada del usuario al turno en curso sin crear otro. - Recibe eventos en tiempo real: después de
turn/start, sigue leyendo las notificaciones en stdout, incluidasthread/archived,thread/unarchived,item/started,item/completed,item/agentMessage/delta, el progreso de las herramientas y otras actualizaciones. - Finaliza el turno: el servidor emite
turn/completedcon el estado final cuando el modelo termina o después de una cancelación conturn/interrupt.
Inicialización
Los clientes deben enviar una única solicitud initialize por conexión de transporte antes de invocar cualquier otro método en esa conexión y luego confirmar con una notificación initialized. Las solicitudes que se envían antes de la inicialización reciben el error Not initialized. Las llamadas repetidas a initialize en la misma conexión devuelven Already initialized.
El servidor devuelve la cadena de agente de usuario que presentará a los servicios de los que depende, junto con los valores platformFamily y platformOs, que describen la plataforma de ejecución. Configura clientInfo para identificar tu integración.
initialize.params.capabilities también admite estas capacidades del cliente:
optOutNotificationMethods: nombres exactos de los métodos de notificación que se deben omitir en esta conexión. La coincidencia debe ser exacta, sin comodines ni prefijos. Los nombres desconocidos se aceptan y se ignoran.requestAttestation: habilita la solicitudattestation/generateiniciada por el servidor. Los hosts de escritorio que proporcionan una certificación a los servicios de los que dependen responden con un valor opaco{ "token": "..." }.mcpServerOpenaiFormElicitation: permite que los servidores MCP conectados envíen la variante de formulario extendido de OpenAI demcpServer/elicitation/request.
Importante: usa clientInfo.name para identificar tu cliente en la Plataforma de registros de cumplimiento. Si desarrollas una integración nueva de Codex para uso empresarial, ponte en contacto con OpenAI para que la agregue a la lista de clientes conocidos. Para más información, consulta la referencia de registros de Codex.
Ejemplo de la extensión de Codex para VS Code:
{
"method": "initialize",
"id": 0,
"params": {
"clientInfo": {
"name": "codex_vscode",
"title": "Codex VS Code Extension",
"version": "0.1.0"
}
}
}
Ejemplo que omite determinadas notificaciones:
{
"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"]
}
}
}
Habilitar la API experimental
Algunos métodos y campos de app-server solo están disponibles si habilitas la capacidad experimentalApi.
- Omite
capabilities(o estableceexperimentalApienfalse) para usar solo la API estable. El servidor rechazará los métodos y campos experimentales. - Establece
capabilities.experimentalApientruepara habilitar los métodos y campos experimentales.
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true
}
}
}
Si un cliente envía un método o campo experimental sin habilitar la capacidad, app-server lo rechaza con este mensaje:
<descriptor> requires experimentalApi capability
Resumen de la API
thread/start: crea un hilo, emitethread/startedy te suscribe automáticamente a los eventos de turnos y elementos del hilo.thread/resume: vuelve a abrir un hilo existente por ID para que las llamadas posteriores aturn/startagreguen turnos al hilo.thread/fork: crea un fork del hilo con un nuevo ID y una copia del historial almacenado. PasalastTurnIdpara copiar el historial hasta ese turno inclusive y omitir los posteriores, oephemeral: truepara crear un fork en memoria. Emitethread/startedpara el nuevo hilo. Los hilos devueltos incluyenforkedFromIdcuando está disponible.thread/read: lee por ID los metadatos almacenados de un hilo sin reanudarlo. Usathread/turns/listythread/items/listpara cargar el historial. Los objetosthreaddevueltos incluyen el estado de ejecuciónstatus.thread/list: recorre por páginas los hilos almacenados y muestra su estado de ejecución. Consulta paginación y filtros.thread/turns/list: recorre por páginas el historial de turnos de un hilo almacenado sin reanudarlo.itemsViewcontrola si los elementos de los turnos se omiten, se resumen o se cargan por completo.thread/items/list: recorre por páginas los elementos guardados de un hilo. Puedes limitar los resultados a un soloturnId. El almacén de hilos activo debe admitir la paginación de elementos.thread/loaded/list: enumera los ID de los hilos cargados en memoria.thread/name/set: establece o actualiza el nombre visible para el usuario de un hilo cargado o de un registro de sesión guardado. Emitethread/name/updated.thread/goal/set: establece el objetivo de un hilo y emitethread/goal/updated.thread/goal/get: lee el objetivo actual de un hilo.thread/goal/clear: borra el objetivo de un hilo y emitethread/goal/cleared.thread/metadata/update: actualiza los metadatos de Git almacenados para un hilo.thread/archive: mueve el archivo de registro del hilo al directorio de hilos archivados e intenta archivar los registros de los hilos descendientes generados que aún no estén archivados. Si tiene éxito, devuelve{}y emitethread/archivedpor cada hilo archivado.thread/delete: elimina de forma permanente un hilo guardado, activo o archivado, y los hilos descendientes que haya generado. Si tiene éxito, devuelve{}y emitethread/deletedpor cada hilo eliminado.thread/unsubscribe: cancela la suscripción de esta conexión a los eventos de turnos y elementos del hilo. Si era el último suscriptor, el servidor descarga el hilo de la memoria tras un periodo de inactividad sin suscriptores y emitethread/closed.thread/unarchive: devuelve el registro de sesión de un hilo archivado al directorio de sesiones activas. Devuelve elthreadrestaurado y emitethread/unarchived.thread/status/changed: notificación que se emite cuando cambia elstatusde ejecución de un hilo cargado.thread/compact/start: inicia la compactación del historial de conversación de un hilo. Devuelve{}de inmediato y transmite el progreso mediante notificacionesturn/*eitem/*.thread/shellCommand: ejecuta en un hilo un comando de shell iniciado por el usuario. Se ejecuta fuera del sandbox con acceso completo y no hereda la política del sandbox del hilo.thread/backgroundTerminals/clean: detiene todas las terminales en segundo plano en ejecución de un hilo (experimental, requierecapabilities.experimentalApi).thread/backgroundTerminals/list: enumera las terminales en segundo plano en ejecución de un hilo cargado (experimental, requierecapabilities.experimentalApi).thread/backgroundTerminals/terminate: detiene una terminal en segundo plano en ejecución mediante elprocessIdde app-server (experimental, requierecapabilities.experimentalApi).thread/revert: elimina del historial de un hilo persistente paginado el turno especificado y todos los posteriores. Devuelve los metadatos actualizados y los cursores del historial, y luego emitethread/reverted.turn/start: agrega a un hilo entrada del usuario o la salida independiente de una herramienta e inicia la generación de Codex. Responde con elturninicial y transmite eventos. ParacollaborationMode,settings.developer_instructions: nullsignifica “usar las instrucciones integradas del modo seleccionado”.thread/inject_items: agrega elementos sin procesar de la API de Responses al historial de un hilo cargado que ve el modelo, sin iniciar un turno del usuario.turn/steer: agrega entrada del usuario al turno en curso de un hilo y devuelve elturnIdaceptado.turn/interrupt: solicita la cancelación de un turno en curso. Si tiene éxito, devuelve{}y el turno termina constatus: "interrupted".review/start: inicia el revisor de Codex para un hilo y emite elementosenteredReviewModeyexitedReviewMode.command/exec: ejecuta un solo comando en el sandbox del servidor sin iniciar un hilo ni un turno.command/exec/write: escribe bytes destdinen una sesión decommand/execen ejecución o cierrastdin.command/exec/resize: cambia el tamaño de una sesión decommand/execen ejecución que usa una PTY.command/exec/terminate: detiene una sesión decommand/execen ejecución.command/exec/outputDelta(notificación): se emite por cada fragmento de stdout o stderr codificado en base64 que transmite una sesión decommand/exec.process/spawn: inicia explícitamente una sesión de proceso fuera del sandbox de Codex (experimental, requierecapabilities.experimentalApi).process/writeStdin: escribe bytes de stdin en una sesión deprocess/spawnen ejecución o cierra stdin (experimental).process/resizePty: cambia el tamaño de una sesión de proceso en ejecución que usa una PTY (experimental).process/kill: detiene una sesión de proceso en ejecución (experimental).process/outputDeltayprocess/exited(notificaciones): se emiten para transmitir la salida del proceso y comunicar su estado de salida (experimentales).model/list: enumera los modelos disponibles (estableceincludeHidden: truepara incluir entradas conhidden: true), con sus opciones de esfuerzo, el campo opcionalupgradeeinputModalities.modelProvider/capabilities/read: lee los límites de las capacidades del proveedor para combinaciones de modelo y proveedor.experimentalFeature/list: enumera las opciones de activación de funciones con metadatos sobre la etapa de su ciclo de vida y paginación por cursor.experimentalFeature/enablement/set: actualiza parcialmente los ajustes de ejecución en memoria para claves de funciones admitidas, comoappsyplugins.environment/info: método experimental que se conecta a un entorno de ejecución configurado y devuelve su shell y su directorio de trabajo predeterminado.permissionProfile/list: enumera los perfiles de permisos en beta e indica si los requisitos vigentes los permiten, con paginación por cursor.collaborationMode/list: enumera los modos de colaboración predefinidos (experimental, sin paginación).skills/list: enumera las habilidades para uno o más valores decwd(admiteforceReloady, de forma opcional,perCwdExtraUserRoots).skills/extraRoots/set: reemplaza los directorios raíz adicionales que usa el proceso para detectar habilidades independientes, sin guardar los cambios de forma persistente.skills/changed(notificación): se emite cuando cambian los archivos locales de habilidades que se supervisan.hooks/list: enumera los hooks del ciclo de vida detectados para uno o más valores decwd.marketplace/add: agrega un marketplace remoto de complementos y lo guarda en la configuración de marketplaces del usuario.marketplace/remove: elimina un marketplace configurado y su directorio raíz instalado, si existe.marketplace/upgrade: actualiza un marketplace de Git configurado o todos los marketplaces de Git configurados si omites el nombre.plugin/list: en desarrollo. Enumera los marketplaces de complementos detectados y el estado de los complementos, incluidos los metadatos de las políticas de instalación y autenticación, los errores de carga del marketplace, los ID de los complementos destacados y los metadatos del origen de los complementos (local, Git, registro de paquetes o remoto). Los resúmenes pueden incluir la versión remotaversion, la versión locallocalVersion, íconos estructurados para los modos claro y oscuro einstallPolicySource, que puede sernull,WORKSPACE_SETTINGoIMPLICIT_CANONICAL_APPpara las entradas remotas actuales. Aún no llames a este método desde clientes de producción.plugin/read: en desarrollo. Lee un complemento por la ruta del marketplace o el nombre del marketplace remoto y el nombre del complemento. Incluye las habilidades, apps y nombres de servidores MCP que contiene, además de unshareUrldel complemento remoto si el catálogo remoto lo proporciona. Aún no llames a este método desde clientes de producción.plugin/install: en desarrollo. Instala un complemento a partir de la ruta del marketplace o del nombre del marketplace remoto. Aún no llames a este método desde clientes de producción.plugin/uninstall: en desarrollo. Desinstala un complemento instalado. Aún no llames a este método desde clientes de producción.plugin/skill/read: lee bajo demanda el Markdown de la habilidad de un complemento remoto por marketplace remoto, ID de complemento y nombre de habilidad.app/installed: lee el estado de ejecución de las apps instaladas, incluido si cada app está efectivamente habilitada y si se puede invocar.app/list: enumera las apps (conectores) disponibles con paginación y metadatos sobre su disponibilidad y habilitación.app/read: obtiene metadatos para determinados ID de apps y, opcionalmente, resúmenes de herramientas solo para visualización.skills/config/write: habilita o deshabilita habilidades por ruta.mcpServer/oauth/login: inicia un flujo de inicio de sesión OAuth para un servidor MCP configurado. Abre la URL HTTP o HTTPS del campoauthorizationUrlde la respuesta y usaloginIdpara identificar la notificaciónmcpServer/oauthLogin/completedcorrespondiente.tool/requestUserInput: presenta al usuario entre 1 y 3 preguntas breves para una llamada a una herramienta (experimental). Las preguntas pueden usarisOtherpara ofrecer una respuesta libre.mcpServer/elicitation/request(solicitud del servidor): pide al cliente datos de un formulario estructurado o la confirmación de un flujo mediante URL solicitado por un servidor MCP.item/permissions/requestApproval(solicitud del servidor): pide al cliente que conceda un subconjunto de los permisos de red o del sistema de archivos solicitados por la herramienta integradarequest_permissions.config/mcpServer/reload: vuelve a cargar desde el disco la configuración de los servidores MCP y pone en cola una actualización para los hilos cargados.mcpServerStatus/list: enumera servidores MCP, herramientas, recursos y estado de autenticación (paginación por cursor y límite). Usadetail: "full"para obtener todos los datos odetail: "toolsAndAuthOnly"para omitir los recursos. Ambos modos incluyen las capacidades que anuncia el servidor enserverCapabilities, onullsi aún no se ha inicializado correctamente. PasaserverNamepara consultar un solo servidor. ConthreadId, la solicitud reutiliza la conexión MCP de ese hilo.mcpServer/resource/read: lee un solo recurso MCP a través de un servidor MCP inicializado.mcpServer/tool/call: llama a una herramienta del servidor MCP configurado para un hilo.mcpServer/startupStatus/updated(notificación): se emite cuando cambia el estado de inicio de un servidor MCP configurado para un hilo cargado.windowsSandbox/readiness: comprueba si el sandbox de Windows está listo. Si devuelveupdateRequired, llama awindowsSandbox/setupStarty espera la notificaciónwindowsSandbox/setupCompleted.feedback/upload: envía un informe de comentarios con una clasificación, un motivo y registros opcionales, un ID de conversación y archivos adjuntos opcionales enextraLogFiles.config/read: obtiene la configuración efectiva en disco tras resolver las distintas capas de configuración.externalAgentConfig/detect: detecta recursos de agentes externos que se pueden migrar medianteincludeHomey, opcionalmente,cwds. Cada elemento detectado incluyecwd(nullpara el directorio personal).externalAgentConfig/import: aplica los elementos seleccionados para la migración de agentes externos. PasamigrationItemsexplícitos concwd(nullpara el directorio personal). Los tipos admitidos incluyen configuración, habilidades,AGENTS.md, complementos, configuración de servidores MCP, subagentes, hooks, comandos y sesiones. Las importaciones no vacías emitenexternalAgentConfig/import/progressyexternalAgentConfig/import/completeda medida que termina el trabajo. Las importaciones de complementos y sesiones pueden completarse de forma asíncrona.config/value/write: escribe un solo par clave-valor de configuración en el archivoconfig.tomldel usuario en disco.config/batchWrite: aplica de forma atómica cambios de configuración al archivoconfig.tomldel usuario en disco.configRequirements/read: obtiene los requisitos derequirements.toml, de MDM o de ambos, incluidas las listas de elementos permitidos y los valores fijados defeatureRequirements. Los clientes que habilitanexperimentalApitambién pueden leer los requisitos de red administrados.fs/readFile,fs/writeFile,fs/createDirectory,fs/getMetadata,fs/readDirectory,fs/remove,fs/copy,fs/watch,fs/unwatchyfs/changed(notificación): operan sobre rutas absolutas del sistema de archivos mediante la API del sistema de archivos v2 de app-server.
Los resúmenes de complementos incluyen un tipo unión source. Los complementos locales devuelven { "type": "local", "path": ... }, las entradas del marketplace basadas en Git devuelven { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }, las entradas de registros de paquetes devuelven { "type": "npm", "package": ..., "version": ..., "registry": ... } y las entradas del catálogo remoto devuelven { "type": "remote" }. Para las entradas que solo existen en el catálogo remoto, PluginMarketplaceEntry.path puede ser null. Pasa remoteMarketplaceName en lugar de marketplacePath al leer o instalar esos complementos.
Modelos
Enumerar modelos (model/list)
Llama a model/list para mostrar en el selector los modelos disponibles y sus niveles de esfuerzo de razonamiento.
La siguiente respuesta ilustra la estructura. Los modelos disponibles, los niveles de esfuerzo de razonamiento y los valores predeterminados dependen del cliente y de la cuenta. Usa los valores devueltos en lugar de fijar en el código los de este ejemplo.
{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
"data": [{
"id": "gpt-6.1-sol",
"model": "gpt-6.1-sol",
"displayName": "GPT-6.1 Sol",
"hidden": false,
"defaultReasoningEffort": "medium",
"supportedReasoningEfforts": [{
"reasoningEffort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
}],
"inputModalities": ["text", "image"],
"supportsPersonality": false,
"isDefault": true
}],
"nextCursor": null
} }
Cada entrada de modelo puede incluir estos campos:
supportedReasoningEfforts: opciones de esfuerzo admitidas por el modelo.defaultReasoningEffort: esfuerzo predeterminado sugerido para los clientes.upgrade: ID opcional del modelo recomendado para los avisos de migración de los clientes.upgradeInfo: metadatos opcionales de actualización para los avisos de migración de los clientes.hidden: indica si el modelo está oculto en la lista predeterminada del selector.inputModalities: tipos de entrada admitidos por el modelo (por ejemplo,texteimage).supportsPersonality: campo de compatibilidad obsoleto. Siempre esfalse. Los modelos ya no admiten la selección de personalidad.isDefault: indica si el modelo es la opción predeterminada recomendada.
Si el proveedor seleccionado al inicio deja de cumplir los requisitos administrados, model/list devuelve -32600 y pide al cliente que reinicie Codex.
De forma predeterminada, model/list solo devuelve los modelos visibles en el selector. Establece includeHidden: true si necesitas la lista completa y quieres filtrarla en el cliente mediante hidden.
Cuando falte inputModalities (en catálogos de modelos anteriores), interprétalo como ["text", "image"] para mantener la compatibilidad con versiones anteriores.
Enumerar funciones experimentales (experimentalFeature/list)
Usa este punto de acceso para consultar las opciones de activación de funciones, sus metadatos y la etapa de su ciclo de vida:
{ "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 puede ser beta, underDevelopment, stable, deprecated o removed. Para las opciones que no están en beta, displayName, description y announcement pueden ser null.
Inspeccionar un entorno de ejecución (experimental)
Usa environment/info para inspeccionar un entorno remoto configurado antes de empezar a trabajar en él. El método requiere 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 puede ser null. Cuando está presente, es un URI canónico de tipo file: que usa la sintaxis de rutas nativa del entorno. Los ID de entorno desconocidos y los fallos de conexión o de protocolo generan errores en la solicitud.
Hilos
thread/readlee los metadatos almacenados de un hilo sin suscribirse a él.thread/turns/listrecorre por páginas el historial de turnos de un hilo almacenado sin reanudarlo. UsaitemsViewpara elegir si se omiten los elementos del turno, se resumen o se cargan por completo.thread/items/listrecorre por páginas los elementos guardados de un hilo. Puedes limitar los resultados a un turno.thread/listrecorre por páginas los hilos almacenados. UsasectionIdpara enumerar los hilos de una sección oexcludedThreadIdspara omitir los que ya se muestran en pantalla.thread/loaded/listdevuelve los ID de los hilos que están en memoria.thread/archivemueve el registro JSONL guardado del hilo al directorio de hilos archivados e intenta archivar los registros de los hilos descendientes generados que aún no estén archivados.thread/deleteelimina de forma permanente un hilo guardado, activo o archivado, y los hilos descendientes que haya generado.thread/metadata/updateactualiza los datos degitInfoalmacenados para un hilo.thread/unsubscribecancela la suscripción de la conexión actual a un hilo cargado y puede dar lugar athread/closedtras un periodo de inactividad.thread/unarchivedevuelve el registro de sesión de un hilo archivado al directorio de sesiones activas.thread/compact/startinicia la compactación y devuelve{}de inmediato.thread/revertelimina del historial de un hilo persistente paginado el turno especificado y todos los posteriores. No modifica los archivos locales.thread/inject_itemsagrega elementos sin procesar de la API de Responses al historial de un hilo cargado que ve el modelo, sin iniciar un turno del usuario.
Iniciar o reanudar un hilo
Inicia un hilo nuevo cuando necesites una conversación nueva en Codex.
{ "method": "thread/start", "id": 10, "params": {
"model": "gpt-6.1-sol",
"cwd": "/Users/me/project",
"approvalPolicy": "never",
"sandbox": "workspace-write",
"serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
"thread": {
"id": "thr_123",
"sessionId": "thr_123",
"preview": "",
"ephemeral": false,
"modelProvider": "openai",
"createdAt": 1730910000
}
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }serviceName es opcional. Configúralo si quieres que app-server etiquete las métricas del hilo con el nombre del servicio de tu integración.
thread/start, thread/resume y thread/fork devuelven instructionSources, un arreglo con las rutas de los archivos de instrucciones cargados. Cada ruta usa la sintaxis nativa de rutas absolutas de su entorno de origen, incluso si el entorno es remoto.
Los hilos locales persistentes nuevos usan un historial paginado de forma predeterminada. Carga el historial con thread/turns/list y thread/items/list. Establecer explícitamente historyMode en "legacy" o "paginated" en thread/start es experimental y requiere capabilities.experimentalApi = true.
Los clientes beta que habiliten capabilities.experimentalApi pueden pasar el ID de un perfil de permisos con nombre en permissions en lugar de usar el campo anterior sandbox. No envíes permissions y sandbox juntos. Usa permissionProfile/list con el cwd del proyecto para consultar los perfiles disponibles y saber si los requisitos administrados permiten cada uno.
thread.sessionId identifica la raíz del árbol de sesiones activo. Los hilos raíz usan su propio ID de hilo como ID de sesión. Los forks conservan el ID de sesión de la raíz de la que proceden. Los clientes deben leer el ID de sesión de thread.sessionId en lugar de deducirlo del ID de hilo.
Para continuar una sesión almacenada, llama a thread/resume con el thread.id que guardaste. Pasa excludeTurns: true para obtener los metadatos del hilo y el estado de la sesión activa. Luego carga el historial con los métodos de paginación:
{ "method": "thread/resume", "id": 11, "params": {
"threadId": "thr_123",
"excludeTurns": true
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }
En los hilos paginados, las respuestas con el historial completo de thread/resume y thread/fork están obsoletas y generan deprecationNotice. Ambos métodos aceptan excludeTurns: true sin necesidad de habilitar la API experimental. Una respuesta de thread/resume también puede devolver turnsBackwardsCursor e itemsBackwardsCursor. Pasa cada cursor a su método de paginación correspondiente con sortDirection: "desc". La primera página incluye el elemento de referencia del cursor.
Reanudar un hilo no actualiza por sí solo thread.updatedAt ni la fecha de modificación del archivo de registro de sesión. La marca de tiempo se actualiza cuando inicias un turno.
Si marcas un servidor MCP habilitado como required en la configuración y ese servidor no se inicializa, thread/start y thread/resume fallan en lugar de continuar sin él.
dynamicTools en thread/start es un campo experimental (requiere capabilities.experimentalApi = true). Codex guarda estas herramientas dinámicas en los metadatos del registro de sesión del hilo y las restaura al llamar a thread/resume si no proporcionas otras herramientas dinámicas.
Si el proveedor de modelos configurado difiere del que se guardó para el hilo, tanto thread/resume como el envío de nuevas entradas devuelven -32600 con data.type establecido en modelProviderMismatch. Para mostrar el historial del hilo, recorre sus turnos por páginas con thread/turns/list. Vuelve al proveedor guardado para continuar el hilo o llama a thread/fork para iniciar un hilo nuevo a partir de ese historial con el proveedor actual.
Si reanudas el hilo con un modelo distinto del que figura en el registro de sesión, Codex emite una advertencia y aplica una instrucción de cambio de modelo una sola vez en el turno siguiente.
Administrar el objetivo de un hilo
Usa thread/goal/set, thread/goal/get y thread/goal/clear para administrar el mismo estado persistente del objetivo que muestra /goal en la interfaz de terminal.
{ "method": "thread/goal/set", "id": 13, "params": {
"threadId": "thr_123",
"objective": "Termina la migración y asegúrate de que las pruebas sigan pasando",
"status": "active",
"tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
"threadId": "thr_123",
"objective": "Termina la migración y asegúrate de que las pruebas sigan pasando",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
"threadId": "thr_123",
"goal": {
"threadId": "thr_123",
"objective": "Termina la migración y asegúrate de que las pruebas sigan pasando",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
}
} }
El texto del objetivo debe tener entre 1 y 4000 caracteres. Si proporcionas un objetivo nuevo, se reemplaza el anterior y se reinicia el cómputo de uso. Si proporcionas el objetivo actual y este aún no ha llegado a un estado final, u omites objective, se actualiza el estado o el presupuesto de tokens y se conserva el historial de uso.
Para crear un fork de una sesión almacenada, llama a thread/fork con el thread.id. Se crea un nuevo ID de hilo y se emite la notificación thread/started correspondiente. Pasa lastTurnId para copiar el historial hasta ese turno inclusive y omitir los posteriores:
{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456", "excludeTurns": true } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }
App-server rechaza un lastTurnId que corresponde a un turno en curso. Si omites el campo mientras hay un turno en curso en el hilo de origen, el fork registra una marca de interrupción en lugar de conservar un turno parcial sin marcar.
Pasa ephemeral: true para crear un fork en memoria sin agregarlo a las listas de hilos almacenados:
{
"method": "thread/fork",
"id": 13,
"params": {
"threadId": "thr_123",
"ephemeral": true,
"excludeTurns": true
}
}
{
"id": 13,
"result": {
"thread": {
"id": "thr_789",
"sessionId": "thr_789",
"forkedFromId": "thr_123",
"ephemeral": true
}
}
}
Los forks efímeros de hilos paginados requieren excludeTurns: true.
Cuando se establece un título de hilo visible para el usuario, app-server completa thread.name en las respuestas de thread/list, thread/read, thread/resume y thread/unarchive. thread/start y thread/fork pueden omitir name (o devolver null) hasta que se establezca un título.
Leer un hilo almacenado sin reanudarlo
Usa thread/read para obtener los datos almacenados de un hilo sin reanudarlo ni suscribirte a sus eventos.
includeTurns: si esfalseo se omite, solo se devuelve el resumen del hilo. Establecerlo entruecarga el historial completo. Esta opción está obsoleta para los hilos paginados y generadeprecationNotice. Usa los métodos de paginación.- Los objetos
threaddevueltos incluyen el estado de ejecuciónstatus(notLoaded,idle,systemErroroactiveconactiveFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123" } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }
A diferencia de thread/resume, thread/read no carga el hilo en memoria ni emite thread/started.
Enumerar los turnos de un hilo
Usa thread/turns/list para recorrer por páginas el historial de turnos de un hilo almacenado sin reanudarlo. De forma predeterminada, los resultados se ordenan del más reciente al más antiguo para que los clientes puedan obtener turnos anteriores con nextCursor. La respuesta también incluye backwardsCursor. Pásalo como cursor con el valor opuesto de sortDirection para invertir el orden. El turno de referencia vuelve a incluirse, lo que permite detectar sus actualizaciones.
itemsView controla cuántos datos de los elementos del turno incluye la respuesta:
notLoadedomite los elementos.summarydevuelve datos resumidos de los elementos y es el valor predeterminado si se omite el campo.fulldevuelve los datos completos de los elementos.
{ "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"
} }
Enumerar los elementos de un hilo
thread/items/list recorre por páginas los elementos guardados sin reanudar el hilo. Pasa turnId para limitar los resultados a un turno u omítelo para recorrer los elementos de todo el hilo. De forma predeterminada, los resultados se ordenan del más antiguo al más reciente (sortDirection: "asc"). El almacén de hilos activo debe admitir la paginación de elementos. De lo contrario, el servidor devuelve un error de método no admitido.
Pasa el nextCursor opaco de una respuesta anterior para continuar la paginación. Para empezar después de un elemento conocido, pasa un elemento de referencia y un turnId que no esté vacío:
{ "method": "thread/items/list", "id": 21, "params": {
"threadId": "thr_123",
"turnId": "turn_456",
"cursor": { "type": "item", "itemId": "item_123" },
"sortDirection": "asc",
"limit": 50
} }
{ "id": 21, "result": {
"data": [],
"nextCursor": null,
"backwardsCursor": null
} }
El elemento de referencia se excluye de los resultados. El orden ascendente devuelve los elementos posteriores y el descendente, los anteriores. El elemento debe pertenecer al historial visible del turno solicitado. Si falta turnId, el ID del elemento está vacío o el elemento es desconocido o está fuera del ámbito de la solicitud, se devuelve un error de parámetros no válidos (-32602). Continúa con la cadena nextCursor devuelta. Cada entrada del resultado contiene turnId, item y, opcionalmente, las marcas de tiempo registradas de inicio y finalización.
Enumerar hilos con paginación y filtros
thread/list te permite mostrar el historial en una interfaz. De forma predeterminada, los resultados se ordenan del más reciente al más antiguo según createdAt. Los filtros se aplican antes de la paginación. Puedes combinar los siguientes parámetros:
cursor: cadena opaca de una respuesta anterior. Omítela para la primera página.limit: si se omite, el servidor usa un tamaño de página razonable.sortKey:created_at(predeterminado),updated_at,recency_atosection_position. Para usarsection_position, pasa unsectionIdque no sea nulo.sortDirection:ascodesc. Si omitessortDirection, el orden es ascendente parasection_positiony descendente para las claves de tiempo.sectionId: pasa el ID de una sección para enumerar sus hilos onullpara enumerar los hilos sin sección asignada. Omite el campo para incluir los hilos de todas las secciones y los que no tienen sección asignada.excludedThreadIds: permite omitir hasta 100 ID de hilo. Los ID duplicados cuentan para el límite de 100. El servidor excluye los hilos que coinciden antes de aplicar el límite de la página. Envía las mismas exclusiones con cada cursor.modelProviders: limita los resultados a proveedores específicos. Pasa[]para incluir todos los proveedores. Si omites el campo o pasasnull, el servidor usa el proveedor configurado, salvo que filtres por una relación entre hilos, en cuyo caso incluye todos los proveedores.sourceKinds: limita los resultados a orígenes de hilo específicos. Si se omite o es[], el servidor solo incluye los orígenes interactivos de forma predeterminada:cliyvscode.archived: si estrue, solo enumera los hilos archivados. Si esfalseo se omite, enumera los hilos sin archivar (comportamiento predeterminado).cwd: limita los resultados a los hilos cuyo directorio de trabajo actual de la sesión coincide exactamente con esta ruta o con una de las rutas de un arreglo. Las rutas relativas se resuelven a partir del directorio de trabajo del proceso de app-server.useStateDbOnly: si estrue, devuelve los resultados de la base de datos de estado sin examinar los registros JSONL de los hilos para reparar sus metadatos. Omítelo o pasafalsepara usar el comportamiento predeterminado de examen y reparación.searchTerm: limita los resultados a los hilos cuyo título extraído contiene el fragmento de texto indicado. Distingue entre mayúsculas y minúsculas.parentThreadId: limita los resultados a los hilos hijos directos del hilo indicado. Este filtro es experimental y requierecapabilities.experimentalApi = true.ancestorThreadId: limita los resultados a los descendientes generados por el hilo indicado, a cualquier profundidad. Este filtro es experimental y requierecapabilities.experimentalApi = true. No lo combines conparentThreadId.
sourceKinds acepta los siguientes valores:
clivscodeexecappServersubAgentsubAgentReviewsubAgentCompactsubAgentThreadSpawnsubAgentOtherunknown
Ejemplo:
{ "method": "thread/list", "id": 20, "params": {
"cursor": null,
"limit": 25,
"sortKey": "created_at"
} }
{ "id": 20, "result": {
"data": [
{ "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "section": { "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318", "name": "Pinned", "appearance": null }, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
{ "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "section": null, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
],
"nextCursor": "opaque-token-or-null"
} }
Cuando nextCursor es null, llegaste a la última página.
Organizar hilos en secciones
Crea una sección con nombre mediante threadSection/create y usa el section.id devuelto en thread/section/move. Pasa beforeThreadId para insertar el hilo antes de otro hilo de la sección u omítelo para agregarlo al final. Pasa sectionId: null para quitar un hilo de su sección. Usa threadSection/list, threadSection/update y threadSection/delete para recorrer por páginas las secciones personalizadas, cambiarles el nombre y eliminarlas, respectivamente. Para fijar un hilo, muévelo a la sección integrada Pinned que devuelve threadSection/list.
Administrar los recursos adjuntos de un hilo
Usa los adjuntos para asociar recursos, como pull requests, a un hilo almacenado. Puedes administrar estas referencias sin reanudar el hilo.
thread/attachment/addrecibethreadId,attachmentType,identityKeyy unpayloaden formato JSON. Si vuelves a agregar el mismo tipo y la misma clave al mismo hilo, devuelve el adjunto existente.thread/attachment/listrecorre por páginas los adjuntos de un hilo. Para encontrar los hilos que hacen referencia a un recurso, llama athread/attachmentOwner/listcon suattachmentTypey suidentityKey.thread/attachment/removerecibethreadId,attachmentTypeeidentityKey. El recurso asociado sigue disponible.thread/attachment/updatedinforma de una operacióncreatedodeletedcuando cambia la asociación.
Actualizar los metadatos almacenados de un hilo
Usa thread/metadata/update para actualizar parcialmente los metadatos almacenados de un hilo sin reanudarlo. Pasa en gitInfo los campos de Git que quieras actualizar. Omite un campo para conservar su valor o pasa null para borrarlo.
{ "method": "thread/metadata/update", "id": 21, "params": {
"threadId": "thr_123",
"gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
"thread": {
"id": "thr_123",
"gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
}
} }
Seguir los cambios de estado de un hilo
thread/status/changed se emite cada vez que cambia el estado de ejecución de un hilo cargado. La notificación incluye threadId y el nuevo status.
{
"method": "thread/status/changed",
"params": {
"threadId": "thr_123",
"status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
}
}
Enumerar los hilos cargados
thread/loaded/list devuelve los ID de los hilos cargados en memoria.
{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }
Cancelar la suscripción a un hilo cargado
thread/unsubscribe cancela la suscripción de la conexión actual a un hilo. La respuesta indica uno de estos estados:
unsubscribedcuando la conexión estaba suscrita y se canceló la suscripción.notSubscribedcuando la conexión no estaba suscrita a ese hilo.notLoadedcuando el hilo no está cargado.
Después de que se retira el último suscriptor, app-server descarga el hilo de la memoria tras 60 segundos de inactividad de forma predeterminada. Configura thread_unload_delay_secs para cambiar ese intervalo. Al descargar el hilo, app-server emite thread/status/changed con el estado notLoaded y una notificación thread/closed.
{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }
Si después vence el plazo del hilo:
{ "method": "thread/status/changed", "params": {
"threadId": "thr_123",
"status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }
Archivar un hilo
Usa thread/archive para mover el registro guardado de un hilo (un archivo JSONL en disco) al directorio de sesiones archivadas. Al archivar un hilo, el servidor también intenta archivar los hilos descendientes generados que aún no estén archivados.
{ "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" } }
Los hilos archivados no aparecerán en llamadas posteriores a thread/list a menos que pases archived: true. El servidor emite una notificación thread/archived por cada hilo que archiva. Si no puede archivar un descendiente generado, la solicitud puede completarse con éxito sin emitir una notificación de archivado para ese descendiente.
Eliminar un hilo
Usa thread/delete para eliminar de forma permanente un hilo guardado, activo o archivado, y los hilos descendientes que haya generado. El servidor elimina los archivos de registro de sesión existentes y sus metadatos antes de confirmar que la operación tuvo éxito. Los archivos de registro de sesión que faltan se consideran eliminados. No se pueden eliminar los hilos raíz efímeros.
{ "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" } }
Desarchivar un hilo
Usa thread/unarchive para devolver el registro de sesión de un hilo archivado al directorio de sesiones activas.
{ "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" } }
Iniciar la compactación de un hilo
Usa thread/compact/start para iniciar manualmente la compactación del historial de un hilo. La solicitud devuelve {} de inmediato.
App-server comunica el progreso mediante notificaciones estándar turn/* e item/* con el mismo threadId, incluido el ciclo de vida de un elemento contextCompaction (item/started seguido de item/completed).
{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }
Ejecutar un comando de shell en un hilo
Usa thread/shellCommand para comandos de shell que el usuario inicia en un hilo. La solicitud devuelve {} de inmediato y transmite el progreso mediante notificaciones estándar turn/* e item/*.
Esta API se ejecuta fuera del sandbox con acceso completo y no hereda la política del sandbox del hilo. Los clientes solo deben exponerla para comandos iniciados explícitamente por el usuario.
Si el hilo ya tiene un turno activo, el comando se ejecuta como una acción auxiliar de ese turno y su salida formateada se incorpora al flujo de mensajes del turno. Si el hilo está inactivo, app-server inicia un turno independiente para el comando de shell.
Establece timeoutMs para limitar el tiempo de ejecución en milisegundos. Si lo omites o pasas null, se usa el valor predeterminado de una hora. 0 indica que el plazo vence de inmediato. Los valores negativos se rechazan. El tiempo de espera no retrasa la confirmación inmediata de la RPC.
{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }
Detener las terminales en segundo plano
Usa thread/backgroundTerminals/clean para detener todas las terminales en segundo plano en ejecución asociadas a un hilo. Este método es experimental y requiere capabilities.experimentalApi = true.
{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }
Usa thread/backgroundTerminals/list para inspeccionar las terminales en segundo plano en ejecución de un hilo cargado. La solicitud admite la paginación estándar con cursor y limit. El processId devuelto es el ID de proceso que usa app-server. Este método es experimental y requiere 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 } }
Usa thread/backgroundTerminals/terminate con ese processId para detener una terminal en segundo plano. Este método es experimental y requiere capabilities.experimentalApi = true:
{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }
Revertir el historial de un hilo
Usa thread/revert para eliminar el turno indicado en beforeTurnId y todos los posteriores del historial de conversación de un hilo persistente paginado. No revierte los cambios en archivos locales. Si el hilo no está cargado, reanúdalo primero. No se admiten hilos efímeros ni hilos con el formato de historial anterior.
{ "method": "thread/revert", "id": 30, "params": { "threadId": "thr_b", "beforeTurnId": "turn_456" } }
{ "id": 30, "result": {
"thread": { "id": "thr_b", "ephemeral": false, "turns": [] },
"turnsBackwardsCursor": "retained-turn-cursor-or-null",
"itemsBackwardsCursor": "retained-item-cursor-or-null"
} }
{ "method": "thread/reverted", "params": { "threadId": "thr_b" } }
El valor devuelto de thread.turns siempre está vacío. Usa los cursores devueltos con thread/turns/list o thread/items/list y sortDirection: "desc" para cargar el historial conservado, incluido el elemento de referencia del cursor.
thread/rollback se eliminó y devuelve un error de método desconocido. Las marcas de reversión existentes en hilos guardados con versiones anteriores se pueden seguir leyendo.
Turnos
El campo input acepta una lista de elementos:
{ "type": "text", "text": "Explica este diff" }{ "type": "image", "url": "https://.../design.png" }{ "type": "localImage", "path": "/tmp/screenshot.png" }
Puedes cambiar la configuración para cada turno (modelo, esfuerzo, cwd, política del sandbox y resumen). Si especificas estos ajustes, se convierten en los valores predeterminados de los turnos posteriores del mismo hilo. outputSchema solo se aplica al turno actual. Para sandboxPolicy.type = "externalSandbox", establece networkAccess en restricted o enabled. Para workspaceWrite, networkAccess sigue siendo un booleano.
En turn/start.collaborationMode, settings.developer_instructions: null significa “usar las instrucciones integradas del modo seleccionado”. No borra las instrucciones del modo.
Acceso de lectura del sandbox (ReadOnlyAccess)
sandboxPolicy admite controles explícitos de acceso de lectura:
readOnly: campo opcionalaccess({ "type": "fullAccess" }de forma predeterminada, o acceso limitado a directorios raíz específicos).workspaceWrite: campo opcionalreadOnlyAccess({ "type": "fullAccess" }de forma predeterminada, o acceso limitado a directorios raíz específicos).
Estructura del acceso de lectura restringido:
{
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
}
En macOS, includePlatformDefaults: true agrega una política de Seatbelt con reglas predeterminadas seleccionadas para la plataforma en las sesiones con acceso de lectura restringido. Esto mejora la compatibilidad con las herramientas sin conceder acceso general a todo /System.
Ejemplos:
{ "type": "readOnly", "access": { "type": "fullAccess" } }
{
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"readOnlyAccess": {
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
},
"networkAccess": false
}
Iniciar un turno
{ "method": "turn/start", "id": 30, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Run tests" } ],
"cwd": "/Users/me/project",
"approvalPolicy": "on-request",
"sandboxPolicy": {
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"networkAccess": true
},
"model": "gpt-6.1-sol",
"effort": "medium",
"summary": "concise",
"outputSchema": {
"type": "object",
"properties": { "answer": { "type": "string" } },
"required": ["answer"],
"additionalProperties": false
}
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }Configura serviceTierForTurn para cambiar el nivel de servicio de un solo turno nuevo. Usa "default" para la velocidad estándar u omite el campo para heredar el nivel del hilo. Para cambiar el nivel de este turno y de los posteriores, configura serviceTier.
Para iniciar un turno con la salida de una herramienta que ejecutó tu cliente, pasa toolOutput con un name que no esté vacío, un namespace opcional y un output que sea una cadena o un arreglo de elementos de contenido. Establece input en un arreglo vacío. No puedes combinar toolOutput con una entrada del usuario que no esté vacía.
{
"method": "turn/start",
"id": 31,
"params": {
"threadId": "thr_123",
"input": [],
"toolOutput": {
"name": "run_tests",
"namespace": null,
"output": "All 42 tests passed."
}
}
}
La salida conserva su carácter de salida de herramienta en la conversación y aparece como un elemento functionCallOutput en las notificaciones y en el historial guardado. Si ya hay un turno normal activo, Codex pone la salida en cola para ese turno.
Insertar elementos en un hilo
Usa thread/inject_items para agregar elementos ya preparados de la API de Responses al historial de prompts de un hilo cargado sin iniciar un turno del usuario. Estos elementos se guardan en el registro de sesión y se incluyen en las solicitudes posteriores al modelo.
{ "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": {} }
Redirigir un turno activo
Usa turn/steer para agregar más entrada del usuario al turno en curso.
- Incluye
expectedTurnId. Debe coincidir con el ID del turno activo. - La solicitud falla si el hilo no tiene un turno activo.
turn/steerno emite una nueva notificaciónturn/started.turn/steerno acepta cambios de configuración a nivel de turno (model,cwd,sandboxPolicyuoutputSchema).
{ "method": "turn/steer", "id": 32, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Mejor concéntrate primero en las pruebas que fallan." } ],
"expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }
Iniciar un turno e invocar una habilidad
Para invocar una habilidad de forma explícita, incluye $<skill-name> en la entrada de texto y agrega un elemento de entrada skill junto al texto.
{ "method": "turn/start", "id": 33, "params": {
"threadId": "thr_123",
"input": [
{ "type": "text", "text": "$skill-creator Agrega una habilidad para diagnosticar fallas intermitentes en la integración continua e incluye instrucciones de uso paso a paso." },
{ "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 } } }
Interrumpir un turno
{ "method": "turn/interrupt", "id": 31, "params": { "threadId": "thr_123", "turnId": "turn_456" } }
{ "id": 31, "result": {} }
Si la solicitud tiene éxito, el turno termina con status: "interrupted".
Revisión
review/start ejecuta el revisor de Codex en un hilo y transmite los elementos de la revisión. Puedes indicar los siguientes objetivos de revisión:
uncommittedChangesbaseBranch(comparar los cambios con una rama)commit(revisar un commit específico)custom(instrucciones de formato libre)
review/start ejecuta la revisión en el hilo que indiques. Omite delivery o pasa "inline". Para ejecutar una revisión independiente, usa thread/fork si quieres incluir el historial existente o thread/start si quieres empezar con un hilo vacío. Luego llama a review/start con el ID del nuevo hilo.
Ejemplo de solicitud y respuesta:
{ "method": "review/start", "id": 40, "params": {
"threadId": "thr_123",
"delivery": "inline",
"target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
"turn": {
"id": "turn_900",
"status": "inProgress",
"items": [
{ "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
],
"error": null
},
"reviewThreadId": "thr_123"
} }
Codex transmite la notificación habitual turn/started seguida de item/started con un elemento enteredReviewMode:
{
"method": "item/started",
"params": {
"item": {
"type": "enteredReviewMode",
"id": "turn_900",
"review": "current changes"
}
}
}
Cuando el revisor termina, el servidor emite item/started e item/completed con un elemento exitedReviewMode que contiene el texto final de la revisión:
{
"method": "item/completed",
"params": {
"item": {
"type": "exitedReviewMode",
"id": "turn_900",
"review": "Looks solid overall..."
}
}
}
Usa esta notificación para mostrar el resultado de la revisión en tu cliente.
Ejecución de procesos
process/* es una API experimental para controlar procesos explícitamente. Requiere capabilities.experimentalApi = true y se ejecuta fuera del sandbox de Codex. Úsala solo si tu cliente ofrece deliberadamente control de procesos locales sin sandbox.
Inicia un proceso con process/spawn y proporciona un processHandle. Luego usa ese identificador para las solicitudes de escritura en stdin, cambio de tamaño y terminación. La salida se transmite mediante notificaciones process/outputDelta y la finalización se comunica mediante 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
} }
Usa process/writeStdin con deltaBase64, closeStdin o ambos para enviar la entrada. Usa process/resizePty para los eventos de cambio de tamaño de la PTY y process/kill para detener un proceso en ejecución.
Ejecución de comandos
command/exec ejecuta un solo comando (un arreglo argv) en el sandbox del servidor sin crear un hilo.
{ "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": "" } }
Usa sandboxPolicy.type = "externalSandbox" si ya ejecutas el proceso del servidor en un sandbox y quieres que Codex omita la aplicación de su propio sandbox. Para el modo de sandbox externo, establece networkAccess en restricted (predeterminado) o enabled. Para readOnly y workspaceWrite, usa la misma estructura opcional de access o readOnlyAccess que se mostró antes.
Notas:
- El servidor rechaza los arreglos
commandvacíos. sandboxPolicyacepta la misma estructura que usaturn/start(por ejemplo,dangerFullAccess,readOnly,workspaceWriteoexternalSandbox).- Si se omite
timeoutMs, se usa el valor predeterminado del servidor. - Establece
tty: truepara las sesiones que usan una PTY y usaprocessIdcuando vayas a realizar llamadas posteriores acommand/exec/write,command/exec/resizeocommand/exec/terminate. - Establece
streamStdoutStderr: truepara recibir notificacionescommand/exec/outputDeltamientras se ejecuta el comando.
Leer los requisitos de administración (configRequirements/read)
Usa configRequirements/read para inspeccionar los requisitos de administración vigentes que se cargaron desde requirements.toml, desde MDM o desde ambos.
{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
"requirements": {
"allowedApprovalPolicies": ["on-request", "never"],
"allowedSandboxModes": ["read-only", "workspace-write"],
"featureRequirements": {
"unified_exec": false
}
}
} }
result.requirements es null cuando no hay requisitos configurados. Cuando result.supportsIndependentSpeedModes es true, los requisitos de fast_mode y ultrafast_mode se aplican de forma independiente. Los servidores anteriores omiten este campo y usan fast_mode para ambos modos. Para conocer las claves y los valores admitidos, consulta la referencia de requirements.toml.
Configurar el sandbox de Windows (windowsSandbox/setupStart)
Llama a windowsSandbox/readiness antes de pedir al usuario que configure el sandbox. Tanto MXC como un sandbox anterior ya configurado pueden devolver ready. Si el sandbox anterior devuelve updateRequired, llama a windowsSandbox/setupStart para iniciar la configuración de forma asíncrona. La comprobación devuelve notConfigured si el sandbox de Windows está deshabilitado o si el host usa otro sistema operativo.
{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }
App-server inicia la configuración en segundo plano y luego emite una notificación de finalización:
{
"method": "windowsSandbox/setupCompleted",
"params": { "mode": "elevated", "success": true, "error": null }
}
Modos:
elevated: ejecuta el procedimiento de configuración del sandbox de Windows con privilegios elevados.unelevated: ejecuta el procedimiento anterior de configuración y comprobaciones previas.
Sistema de archivos
Las API del sistema de archivos v2 operan sobre rutas absolutas. Usa fs/watch cuando un cliente necesite invalidar el estado de la interfaz después de un cambio en un archivo o directorio.
{ "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": {} }
Al supervisar un archivo, se emite fs/changed para esa ruta, incluso cuando la actualización se produce mediante una operación de reemplazo o cambio de nombre.
Eventos
Las notificaciones de eventos forman el flujo que inicia el servidor para comunicar el ciclo de vida de los hilos, los turnos y sus elementos. Después de iniciar o reanudar un hilo, sigue leyendo el flujo de transporte activo para recibir las notificaciones thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* y serverRequest/resolved.
Omitir notificaciones
Los clientes pueden omitir notificaciones específicas por conexión. Para ello, envían los nombres exactos de los métodos en initialize.params.capabilities.optOutNotificationMethods.
- Solo se admiten coincidencias exactas:
item/agentMessage/deltaomite únicamente ese método. - Los nombres de métodos desconocidos se ignoran.
- Se aplica a las notificaciones actuales
thread/*,turn/*,item/*y a las notificaciones v2 relacionadas. - No se aplica a solicitudes, respuestas ni errores.
Eventos de búsqueda aproximada de archivos (experimental)
La API de sesiones de búsqueda aproximada de archivos emite notificaciones por consulta:
fuzzyFileSearch/sessionUpdated:{ sessionId, query, files }con las coincidencias actuales de la consulta activa.fuzzyFileSearch/sessionCompleted:{ sessionId }una vez que terminan la indexación y la búsqueda de coincidencias para esa consulta.
Eventos de advertencia
configWarning:{ summary, details?, path?, range? }para problemas de configuración o inicialización de los que el sistema puede recuperarse.warning:{ threadId?, message }para advertencias de ejecución que no impiden continuar.
Eventos de configuración del sandbox de Windows
windowsSandbox/setupCompleted:{ mode, success, error }se emite después de que termina una solicitudwindowsSandbox/setupStart.
Eventos de turno
turn/started:{ turn }con el ID del turno,itemsvacío ystatus: "inProgress".turn/completed:{ turn }dondeturn.statusescompleted,interruptedofailed. Los fallos incluyen{ error: { message, codexErrorInfo?, additionalDetails? } }.turn/diff/updated:{ threadId, turnId, diff }con el diff unificado más reciente que reúne todos los cambios en archivos del turno.turn/plan/updated:{ turnId, explanation?, plan }cada vez que el agente comparte o cambia su plan. Cada entrada deplantiene la estructura{ step, status }, dondestatuspuede serpending,inProgressocompleted.hook/startedyhook/completed:{ threadId, turnId?, run }cuando se inicia un hook síncrono del ciclo de vida y cuando está disponible el resumen final de su ejecución. Estas notificaciones no se emiten para los hooks asíncronos.model/safetyBuffering/updated:{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }cuando una respuesta se almacena temporalmente en un búfer por motivos de seguridad.model/rerouted:{ threadId, turnId, fromModel, toModel, reason }cuando el servicio redirige una solicitud a otro modelo.model/verification:{ threadId, turnId, verifications }cuando el servicio requiere una verificación adicional de la cuenta.thread/tokenUsage/updated: actualizaciones de uso del hilo activo.
turn/diff/updated y turn/plan/updated actualmente incluyen arreglos items vacíos incluso cuando se transmiten eventos de elementos. Usa las notificaciones item/* como referencia definitiva para los elementos del turno.
Elementos
ThreadItem es el tipo unión etiquetado que se incluye en las respuestas de turno y en las notificaciones item/*. Entre los tipos de elementos más comunes se encuentran los siguientes:
userMessage:{id, content}dondecontentes una lista de entradas del usuario (text,imageolocalImage).functionCallOutput:{id, name, namespace, output}para la salida independiente de una herramienta proporcionada medianteturn/start.toolOutput.namespacepuede sernull.agentMessage:{id, text, phase?}con la respuesta acumulada del agente. Cuando está presente,phaseusa los valores del protocolo de la API de Responses (commentary,partial_answer,final_answer). Unpartial_answercontiene texto de respuesta estable al que pueden seguir más contenido o llamadas a herramientas.plan:{id, text}con el texto del plan propuesto en modo plan. Toma el elementoplanfinal deitem/completedcomo versión definitiva.reasoning:{id, summary, content}dondesummarycontiene los resúmenes de razonamiento transmitidos ycontentcontiene los bloques de razonamiento sin procesar.commandExecution:{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.fileChange:{id, changes, status}describe los cambios propuestos.changesenumera entradas con la estructura{path, kind, diff}.mcpToolCall: registra los camposid,server,tool,statusyargumentsde la llamada. La llamada también incluyeappContext,mcpAppUi,pluginId,readOnlyHint,result,errorydurationMs. Cada uno de estos campos puede sernull. El campo heredadomcpAppResourceUries opcional. Para las apps MCP de confianza,appContextcontieneconnectorId. Los demás campos de ese objeto (linkId,resourceUri,appNameyactionName) pueden sernull. Cuando el descriptor de la herramienta especifica un URI de recurso y un modo de visualización (inlineofullscreen),mcpAppUicontieneresourceUriypreferredModelDisplayMode. Para las llamadas guardadas sin estos metadatos de presentación, app-server devuelvenullenmcpAppUi.dynamicToolCall:{id, tool, arguments, status, contentItems?, success?, durationMs?}para las llamadas a herramientas dinámicas que ejecuta el cliente.collabToolCall:{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.webSearch:{id, query, action?}para las solicitudes de búsqueda web que emite el agente.imageView:{id, path}se emite cuando el agente invoca la herramienta de visualización de imágenes.enteredReviewMode:{id, review}se envía cuando se inicia el revisor.exitedReviewMode:{id, review}se emite cuando termina el revisor.contextCompaction:{id}se emite cuando Codex compacta el historial de la conversación.
En webSearch.action, el type de la acción puede ser search (query?, queries?), openPage (url?) o findInPage (url?, pattern?).
En app-server, la notificación anterior thread/compacted está obsoleta. Usa el elemento contextCompaction.
Todos los elementos emiten dos eventos del ciclo de vida:
item/started: emite elitemcompleto cuando comienza una nueva unidad de trabajo. Elitem.idcoincide con elitemIdque usan las actualizaciones incrementales.item/completed: envía elitemfinal cuando termina el trabajo. Tómalo como el estado definitivo.
Actualizaciones incrementales de elementos
item/agentMessage/delta: agrega el texto que se transmite al mensaje del agente.item/plan/delta: transmite el texto del plan propuesto. El elementoplanfinal puede diferir de la concatenación de los fragmentos.item/reasoning/summaryTextDelta: transmite resúmenes legibles del razonamiento.summaryIndexaumenta cuando se abre una nueva sección del resumen.item/reasoning/summaryPartAdded: marca el límite entre secciones del resumen de razonamiento.item/reasoning/textDelta: transmite el texto de razonamiento sin procesar (cuando el modelo lo admite).item/commandExecution/outputDelta: transmite stdout y stderr de un comando. Agrega los fragmentos en orden.item/fileChange/outputDelta: notificación de compatibilidad obsoleta para la salida de texto anterior deapply_patch. Las versiones actuales de app-server ya no la emiten. Usa los elementosfileChangey la notificaciónturn/diff/updated.
Errores
Cuando app-server rechaza trabajo nuevo durante un cierre ordenado, devuelve un error JSON-RPC con el código -32600 y data.reason establecido en serverShuttingDown.
La notificación error incluye un objeto error anidado con un campo message y un campo opcional additionalDetails. Su campo codexErrorInfo puede ser null. Si willRetry es true, el servidor vuelve a intentarlo y el turno sigue activo. Si el turno falla, finaliza con status: "failed". Entre los valores habituales de codexErrorInfo se encuentran contextWindowExceeded, usageLimitExceeded, badRequest, unauthorized y sandboxError. Si falla una solicitud a un servicio del que depende el servidor, el valor puede ser un objeto como { "httpConnectionFailed": { "httpStatusCode": 503 } }.
Aprobaciones
Según la configuración de Codex del usuario, la ejecución de comandos y los cambios en archivos pueden requerir aprobación. App-server envía al cliente una solicitud JSON-RPC iniciada por el servidor y el cliente responde con los datos de su decisión.
-
Decisiones para la ejecución de comandos:
accept,acceptForSession,decline,cancelo{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }. -
Decisiones para cambios en archivos:
accept,acceptForSession,decline,cancel. -
Las solicitudes incluyen
threadIdyturnId. Úsalos para limitar el estado de la interfaz a la conversación activa. -
El servidor reanuda o rechaza el trabajo y finaliza el elemento con
item/completed.
Aprobaciones para ejecutar comandos
Orden de los mensajes:
item/startedmuestra el elementocommandExecutionpendiente concommand,cwdy otros campos.item/commandExecution/requestApprovalincluyeitemId,threadId,turnIdy los campos opcionalesreason,command,cwd,commandActions,proposedExecpolicyAmendment,networkApprovalContextyavailableDecisions. Cuandoinitialize.params.capabilities.experimentalApi = true, la solicitud también puede incluir el campo experimentaladditionalPermissions, que describe el acceso al sandbox solicitado para ese comando. Todas las rutas del sistema de archivos enadditionalPermissionsse transmiten como rutas absolutas.- El cliente responde con una de las decisiones de aprobación de ejecución de comandos indicadas antes.
serverRequest/resolvedconfirma que la solicitud pendiente recibió respuesta o se descartó.item/completeddevuelve el elementocommandExecutionfinal constatus: completed | failed | declined.
Cuando está presente networkApprovalContext, la solicitud corresponde al acceso de red administrado y no a una aprobación general del comando de shell. El esquema v2 actual expone el host y el protocol de destino. Los clientes deben mostrar una solicitud específica de acceso a la red y evitar asumir que command contiene una vista previa del comando de shell que el usuario pueda interpretar.
Codex agrupa las solicitudes simultáneas de aprobación de red por destino (host, protocolo y puerto). Por eso, app-server puede enviar una sola solicitud de aprobación que desbloquee varias solicitudes en cola para el mismo destino. Los puertos distintos de un mismo host se tratan por separado.
Aprobaciones para cambios en archivos
Orden de los mensajes:
item/startedemite un elementofileChangecon loschangespropuestos ystatus: "inProgress".item/fileChange/requestApprovalincluyeitemId,threadId,turnIdy los campos opcionalesreasonygrantRoot.- El cliente responde con una de las decisiones de aprobación de cambios en archivos indicadas antes.
serverRequest/resolvedconfirma que la solicitud pendiente recibió respuesta o se descartó.item/completeddevuelve el elementofileChangefinal constatus: completed | failed | declined.
tool/requestUserInput
Cuando el cliente responde a item/tool/requestUserInput, app-server emite serverRequest/resolved con { threadId, requestId }. Si el inicio, la finalización o la interrupción de un turno descarta la solicitud pendiente antes de que el cliente responda, el servidor emite la misma notificación para indicar que se descartó.
Los parámetros de la solicitud incluyen autoResolutionMs, que puede ser un tiempo de espera expresado como un número entero de milisegundos o null. Si se especifica el intervalo y el usuario no responde, los clientes host pueden resolver la solicitud automáticamente cuando venza el plazo.
Solicitudes de permisos
La herramienta integrada request_permissions envía item/permissions/requestApproval con threadId, turnId, itemId, environmentId, cwd, un reason opcional y los permisos de red o del sistema de archivos solicitados. Responde con permissions e incluye únicamente el subconjunto concedido. Establece scope en "session" para conservar los permisos en turnos posteriores de la misma sesión. Omítelo o usa "turn" para limitar los permisos al turno. Los permisos que no se solicitaron se ignoran.
Solicitudes de información de servidores MCP
Un servidor MCP puede interrumpir un turno con mcpServer/elicitation/request. La solicitud incluye threadId, un turnId opcional, serverName y una de estas estructuras:
mode: "form"omode: "openai/form", conmessageyrequestedSchema.mode: "url", conmessage,urlyelicitationId.
Responde con action: "accept" y el content solicitado, o con action: "decline" o "cancel" y content: null. Luego app-server emite serverRequest/resolved. Para recibir la variante openai/form, habilita initialize.params.capabilities.mcpServerOpenaiFormElicitation.
Llamadas a herramientas dinámicas (experimental)
El campo dynamicTools de thread/start y el flujo correspondiente de solicitudes y respuestas de item/tool/call son API experimentales.
Los nombres de herramientas dinámicas y de espacios de nombres deben cumplir las restricciones de nombres de la API de Responses. Evita los nombres de espacios de nombres reservados para las herramientas integradas de Codex.
Cuando se invoca una herramienta dinámica durante un turno, la secuencia de app-server es la siguiente:
item/startedconitem.type = "dynamicToolCall",status = "inProgress", además detoolyarguments.item/tool/callcomo solicitud del servidor al cliente.- La respuesta del cliente con los elementos de contenido devueltos.
item/completedconitem.type = "dynamicToolCall", elstatusfinal y cualquier valor devuelto decontentItemsosuccess.
Aprobaciones de llamadas a herramientas MCP (apps)
Las llamadas a herramientas de apps (conectores) también pueden requerir aprobación. Cuando una llamada a una herramienta de una app tiene efectos secundarios, el servidor puede solicitar aprobación mediante tool/requestUserInput con opciones como Aceptar, Rechazar y Cancelar. Las anotaciones que indican operaciones destructivas siempre activan la solicitud de aprobación, incluso si la herramienta también declara indicaciones de menores privilegios. Si el usuario rechaza o cancela la solicitud, el elemento mcpToolCall correspondiente termina con un error sin ejecutar la herramienta.
Habilidades
Para invocar una habilidad, incluye $<skill-name> en la entrada de texto del usuario. Agrega un elemento de entrada skill (recomendado) para que el servidor incorpore las instrucciones completas de la habilidad sin depender de que el modelo resuelva el nombre.
{
"method": "turn/start",
"id": 101,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$skill-creator Agrega una habilidad para diagnosticar fallas intermitentes en la integración continua."
},
{
"type": "skill",
"name": "skill-creator",
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
}
]
}
}
Si omites el elemento skill, el modelo seguirá interpretando el marcador $<skill-name> e intentará localizar la habilidad, lo que puede aumentar la latencia.
Ejemplo:
$skill-creator Agrega una habilidad para diagnosticar fallas intermitentes en la integración continua e incluye instrucciones de uso paso a paso.
Usa skills/list para obtener las habilidades disponibles (puedes limitar el ámbito mediante cwds y usar forceReload). También puedes incluir perCwdExtraUserRoots para examinar rutas absolutas adicionales en el ámbito user para valores específicos de cwd. App-server ignora las entradas cuyo cwd no aparece en cwds. skills/list puede reutilizar un resultado en caché por cwd. Establece forceReload: true para volver a cargarlo desde el disco. Cuando están presentes, el servidor lee interface y dependencies de 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": []
}]
} }
El servidor también emite notificaciones skills/changed cuando cambian los archivos locales de habilidades que se supervisan. Usa esta notificación como señal de que los resultados anteriores dejaron de ser válidos y vuelve a ejecutar skills/list con tus parámetros actuales cuando sea necesario.
Para habilitar o deshabilitar una habilidad por ruta:
{
"method": "skills/config/write",
"id": 26,
"params": {
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
"enabled": false
}
}
Apps (conectores)
Usa app/installed para leer la última instantánea confirmada del estado de ejecución de las apps instaladas. Cada resultado incluye el id de la app, runtimeName (o null), el estado efectivo enabled y el estado callable. Solo se puede invocar una app cuando la configuración efectiva la habilita y al menos una herramienta visible para el modelo cumple las políticas de la app y de las herramientas.
{
"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
}
]
}
}
Omite threadId para usar la configuración global en lugar de la de un hilo cargado. Establece forceRefresh: true para actualizar la instantánea de ejecución del conector antes de leerla. Cuando una política global o del espacio de trabajo bloquea el acceso a una app, la app detectada aún puede aparecer con enabled y callable establecidos en false.
Usa app/list para obtener las apps disponibles. En la CLI o la interfaz de terminal, /apps abre el selector para el usuario. En los clientes personalizados, llama a app/list directamente. Cada entrada incluye isAccessible (disponible para el usuario) e isEnabled (habilitada en config.toml) para que los clientes puedan distinguir la instalación y el acceso de la habilitación local. Las entradas de apps también pueden incluir los campos opcionales branding, appMetadata y labels.
{ "method": "app/list", "id": 50, "params": {
"cursor": null,
"limit": 50,
"threadId": "thread-1",
"forceRefetch": false
} }
{ "id": 50, "result": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
],
"nextCursor": null
} }
Si proporcionas threadId, la habilitación de la función de apps (features.apps) se determina a partir de la instantánea de configuración de ese hilo. Si lo omites, app-server usa la configuración global más reciente.
app/list devuelve la respuesta después de cargar tanto las apps accesibles como las del directorio. Establece forceRefetch: true para omitir las cachés de apps y obtener datos nuevos. Las entradas de caché solo se reemplazan si la actualización tiene éxito.
El servidor también emite notificaciones app/list/updated cada vez que termina de cargar una de las dos fuentes (apps accesibles o apps del directorio). Cada notificación incluye la lista combinada más reciente.
{
"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
}
]
}
}
Usa app/read cuando ya conozcas los ID de las apps y necesites sus metadatos en lugar del estado de ejecución de las apps instaladas. Pasa un máximo de 100 ID en appIds. El servidor conserva solo la primera aparición de cada ID repetido y mantiene ese orden tanto en apps como en missingAppIds. Las apps desconocidas o inaccesibles se devuelven en missingAppIds sin que falle toda la solicitud.
{
"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"]
}
}
Establece includeTools: true para solicitar resúmenes públicos de herramientas solo para visualización. La respuesta con metadatos no incluye el estado de ejecución de las apps instaladas ni autoriza una llamada a una herramienta. Usa app/installed para comprobar los estados efectivos enabled y callable.
Para invocar una app, inserta $<app-slug> en la entrada de texto y agrega un elemento de entrada mention con la ruta app://<id> (recomendado).
{
"method": "turn/start",
"id": 51,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$demo-app Obtén las novedades más recientes del equipo."
},
{
"type": "mention",
"name": "Demo App",
"path": "app://demo-app"
}
]
}
}
Ejemplos de RPC para configurar apps
Usa config/read, config/value/write y config/batchWrite para inspeccionar o actualizar los controles de las apps en config.toml.
Lee la estructura de la configuración efectiva de las apps (incluidos _default y los ajustes específicos de cada herramienta):
{ "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 establece el revisor para todas las apps, salvo que se indique otro para una app específica. Si se omiten ambos ajustes, la app hereda el valor de approvals_reviewer de nivel superior. apps._default.default_tools_approval_mode establece el modo de aprobación que se usa si no hay un ajuste específico para la app o la herramienta. Los requisitos administrados del modo de aprobación tienen prioridad sobre los ajustes del modo de aprobación de las herramientas.
Actualiza un solo ajuste de una app:
{
"method": "config/value/write",
"id": 61,
"params": {
"keyPath": "apps.google_drive.default_tools_approval_mode",
"value": "prompt",
"mergeStrategy": "replace"
}
}
Aplica varios cambios de configuración de apps de forma atómica:
{
"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"
}
]
}
}
Detectar e importar la configuración de agentes externos
Usa externalAgentConfig/detect para detectar recursos de agentes externos que se puedan migrar. Luego pasa las entradas seleccionadas a externalAgentConfig/import.
Ejemplo de detección:
{ "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
}
]
} }
Ejemplo de importación:
{ "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" } }
El parámetro de importación opcional source, de nivel superior, identifica el producto que generó los elementos seleccionados para la migración.
El servidor emite externalAgentConfig/import/progress a medida que termina de importar cada tipo de elemento y externalAgentConfig/import/completed una vez que finalizan todas las importaciones síncronas y en segundo plano. Estas notificaciones incluyen el mismo importId que la respuesta, además de itemTypeResults con successes y failures por tipo. La notificación de finalización puede llegar inmediatamente después de la respuesta o cuando terminen las importaciones remotas en segundo plano.
{ "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": []
}
]
} }
Consulta las importaciones anteriores que ya finalizaron:
{ "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": []
}
] } }
Los valores admitidos de itemType son AGENTS_MD, CONFIG, SKILLS, PLUGINS, MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS y SESSIONS. Para los elementos PLUGINS, details.plugins enumera cada marketplaceName y los pluginNames que Codex puede intentar migrar. La detección devuelve solo los elementos que aún requieren trabajo. Por ejemplo, Codex omite la migración de AGENTS cuando AGENTS.md ya existe y no está vacío. Las importaciones de habilidades no sobrescriben los directorios de habilidades existentes.
Al detectar complementos de .claude/settings.json, Codex lee los orígenes de marketplaces configurados en extraKnownMarketplaces. Si enabledPlugins contiene complementos de claude-plugins-official pero falta el origen del marketplace, Codex usa anthropics/claude-plugins-official como origen inferido.
Puntos de acceso de autenticación
Si creaste una aplicación local o de código abierto que usa la autenticación de Codex app-server, puedes seguir usándola. Te recomendamos migrar al inicio de sesión con ChatGPT para que los usuarios puedan ver y controlar mejor su uso. Consulta la documentación para desarrolladores sobre el inicio de sesión con ChatGPT y nuestra guía práctica de implementación. La autenticación de app-server nunca se ha permitido para servicios comerciales o alojados. Lanzamos el inicio de sesión con ChatGPT para dar soporte a estos casos de uso y nos entusiasma ver lo que crearás. Únete a nuestra lista de espera para socios.
La interfaz JSON-RPC de autenticación y cuentas ofrece métodos de solicitud y respuesta, además de notificaciones iniciadas por el servidor (sin id). Úsalos para determinar el estado de autenticación, iniciar o cancelar un inicio de sesión, cerrar la sesión, consultar los límites de solicitudes de ChatGPT y avisar a los propietarios del espacio de trabajo cuando se agoten los créditos o se alcance un límite de uso.
Modos de autenticación
Codex admite los siguientes modos de autenticación. account/updated.authMode muestra el modo activo e incluye el planType actual de ChatGPT cuando está disponible. account/read también informa los detalles de la cuenta y del plan.
- Clave de API (
apikey): quien realiza la llamada proporciona una clave de API de OpenAI contype: "apiKey"y Codex la guarda para las solicitudes a la API. - ChatGPT con autenticación administrada (
chatgpt): Codex gestiona el flujo OAuth de ChatGPT, guarda los tokens y los renueva automáticamente. Usatype: "chatgpt"para iniciar el flujo en el navegador otype: "chatgptDeviceCode"para el flujo con código de dispositivo. - Tokens externos de ChatGPT (
chatgptAuthTokens): modo experimental para apps host que ya gestionan el ciclo de vida de la autenticación de ChatGPT del usuario. La app host proporciona directamenteaccessToken,chatgptAccountIdy, de forma opcional,chatgptPlanType. Debe renovar el token cuando se le solicite. - Amazon Bedrock:
account/readidentifica las cuentas de Bedrock contype: "amazonBedrock"e indica si las credenciales proceden de una clave de API de Bedrock administrada por Codex (credentialSource: "codexManaged") o de la cadena externa de credenciales de AWS (credentialSource: "awsManaged").account/updated.authModeusabedrockApiKeypara las claves de API de Bedrock administradas por Codex.
Resumen de la API
account/read: obtiene la información actual de la cuenta y, opcionalmente, renueva los tokens.account/login/start: inicia el flujo de inicio de sesión (apiKey,chatgpt,chatgptDeviceCodeo el valor experimentalchatgptAuthTokens).account/login/completed(notificación): se emite cuando finaliza un intento de inicio de sesión, ya sea con éxito o con un error.account/login/cancel: cancela medianteloginIdun inicio de sesión administrado de ChatGPT que esté pendiente.account/logout: cierra la sesión y generaaccount/updated.account/updated(notificación): se emite cada vez que cambia el modo de autenticación (authMode:apikey,chatgpt,chatgptAuthTokens,agentIdentity,personalAccessToken,bedrockApiKeyonull) e incluyeplanTypecuando está disponible.account/chatgptAuthTokens/refresh(solicitud del servidor): solicita nuevos tokens de ChatGPT administrados externamente después de un error de autorización.account/rateLimits/read: obtiene los límites de solicitudes de ChatGPT.account/rateLimits/updated(notificación): se emite cada vez que cambian los límites de solicitudes de ChatGPT de un usuario.account/sendAddCreditsNudgeEmail: pide a ChatGPT que envíe un correo electrónico a un propietario del espacio de trabajo cuando se agoten los créditos o se alcance un límite de uso.account/rateLimitResetCredit/consume: consume uno de los restablecimientos obtenidos del límite de solicitudes mediante un valoridempotencyKeyproporcionado por quien realiza la llamada.account/usage/read: obtiene resúmenes de actividad de tokens de la cuenta de ChatGPT y datos agrupados por día.account/workspaceMessages/read: obtiene los mensajes activos del espacio de trabajo, incluidos los títulos de las notificaciones cuando están disponibles.mcpServer/oauthLogin/completed(notificación): se emite al finalizar un flujo demcpServer/oauth/login. Incluye{ name, threadId, loginId?, success, error? }. Los servidores anteriores omitenloginId.threadIdpuede sernullpara los flujos OAuth de una app o de un complemento.mcpServer/startupStatus/updated(notificación): se emite cuando cambia el estado de inicio de un servidor MCP configurado. Incluye{ threadId, name, status, error, failureReason }.threadIdesnullcuando el inicio corresponde a una app. Si el inicio falla,failureReason: "reauthenticationRequired"significa que las credenciales OAuth almacenadas vencieron y no se pudieron renovar. El cliente debe ofrecer la opción de volver a conectar el servidor.
1) Comprobar el estado de autenticación
Solicitud:
{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }
Ejemplos de respuesta:
{ "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
}
}
Notas sobre los campos:
refreshToken(booleano): establécelo entruepara forzar la renovación del token en el modo de autenticación administrada de ChatGPT. En el modo de tokens externos (chatgptAuthTokens), app-server ignora esta opción.emailesnullcuando la cuenta de ChatGPT no tiene una dirección de correo electrónico.requiresOpenaiAuthrefleja el proveedor activo. Si esfalse, Codex puede ejecutarse sin credenciales de OpenAI.- Amazon Bedrock devuelve
credentialSource: "codexManaged"cuando usa una clave de API de Bedrock administrada por Codex. DevuelvecredentialSource: "awsManaged"cuando usa el mecanismo externo de credenciales de AWS. El campo identifica el origen de credenciales seleccionado, pero no comprueba si la cadena de credenciales de AWS puede obtenerlas.
2) Iniciar sesión con una clave de API
-
Envía:
{ "method": "account/login/start", "id": 2, "params": { "type": "apiKey", "apiKey": "sk-..." } } -
Espera esta respuesta:
{ "id": 2, "result": { "type": "apiKey" } } -
Notificaciones:
{ "method": "account/login/completed", "params": { "loginId": null, "success": true, "error": null } }{ "method": "account/updated", "params": { "authMode": "apikey", "planType": null } }
3) Iniciar sesión con ChatGPT (flujo en el navegador)
-
Inicia el flujo:
{ "method": "account/login/start", "id": 3, "params": { "type": "chatgpt", "useHostedLoginSuccessPage": true, "appBrand": "chatgpt" } }De forma predeterminada, si la llamada de retorno del navegador tiene éxito, se redirige al usuario a una página local de confirmación. Establece
useHostedLoginSuccessPage: truepara usar la página de confirmación alojada cuando no se requiera configurar la organización. Si habilitas la página alojada,appBrandpuede ser"codex"o"chatgpt". Si se omite o esnull, el valor predeterminado es"codex".{ "id": 3, "result": { "type": "chatgpt", "loginId": "<uuid>", "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback" } } -
Abre
authUrlen un navegador. App-server atiende la llamada de retorno local. -
Espera las notificaciones:
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": true, "error": null } }{ "method": "account/updated", "params": { "authMode": "chatgpt", "planType": "plus" } }
3b) Iniciar sesión con ChatGPT (flujo con código de dispositivo)
Usa este flujo cuando tu cliente gestione el proceso de inicio de sesión o cuando la llamada de retorno del navegador sea poco confiable.
-
Inicia el flujo:
{ "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" } } -
Muestra
verificationUrlyuserCodeal usuario. El frontend se encarga de la experiencia de usuario. -
Espera las notificaciones:
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": true, "error": null } }{ "method": "account/updated", "params": { "authMode": "chatgpt", "planType": "plus" } }
3c) Iniciar sesión con tokens de ChatGPT administrados externamente (chatgptAuthTokens)
Usa este modo experimental solo cuando una aplicación host gestione el ciclo de vida de la autenticación de ChatGPT del usuario y proporcione los tokens directamente. Los clientes deben establecer capabilities.experimentalApi = true durante initialize antes de usar este tipo de inicio de sesión.
-
Envía:
{ "method": "account/login/start", "id": 7, "params": { "type": "chatgptAuthTokens", "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } } -
Espera esta respuesta:
{ "id": 7, "result": { "type": "chatgptAuthTokens" } } -
Notificaciones:
{ "method": "account/login/completed", "params": { "loginId": null, "success": true, "error": null } }{ "method": "account/updated", "params": { "authMode": "chatgptAuthTokens", "planType": "business" } }
Cuando el servidor recibe 401 Unauthorized, puede solicitar tokens renovados a la app host:
{
"method": "account/chatgptAuthTokens/refresh",
"id": 8,
"params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }
El servidor vuelve a intentar la solicitud original tras recibir una respuesta de renovación satisfactoria. El tiempo de espera de las solicitudes vence después de unos 10 segundos.
4) Cancelar un inicio de sesión de ChatGPT
{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }
5) Cerrar sesión
{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }
6) Límites de solicitudes (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 }
}
} }
Notas sobre los campos:
rateLimitses la vista de una sola cuota que mantiene la compatibilidad con versiones anteriores.rateLimitsByLimitId(si está presente) es la vista de varias cuotas, indexada por ellimit_idde la cuota medida (por ejemplo,codex).limitIdes el identificador de la cuota medida.limitNamees una etiqueta opcional de la cuota que se muestra al usuario.usedPercentindica el uso actual dentro del periodo de la cuota.windowDurationMinsindica la duración del periodo de la cuota.resetsAtes la marca de tiempo Unix (en segundos) del próximo restablecimiento.planTypese incluye cuando el servidor devuelve el plan de ChatGPT asociado a una cuota.creditsse incluye cuando el servidor devuelve detalles sobre los créditos restantes del espacio de trabajo.rateLimitReachedTypeidentifica el estado del límite según la clasificación del servidor cuando se alcanza un límite.rateLimitResetCreditscontiene la cantidad de restablecimientos obtenidos que están disponibles cuando el servicio proporciona ese dato. De lo contrario, esnull.rateLimitResetCredits.creditsesnullcuando solo se conoce la cantidad. Un arreglo vacío indica que el servicio consultó los detalles y no devolvió créditos disponibles. El servicio puede limitar el número de entradas detalladas, por lo queavailableCountindica la cantidad definitiva.- Cada entrada detallada incluye un
idopaco,resetType,status,grantedAt,expiresAt(puede sernull),title(puede sernull) ydescription(puede sernull). - Consulta
account/rateLimits/readdespués de consumir un restablecimiento.
7) Uso de tokens (ChatGPT)
Usa account/usage/read para obtener los campos de resumen de actividad de tokens de ChatGPT y, opcionalmente, los datos agrupados por día.
{ "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 }
]
} }
Notas sobre los campos:
- Los valores de
summarypueden sernullcuando el servicio no ha devuelto la métrica correspondiente. dailyUsageBucketspuede sernull. Cuando está presente, cada grupo incluyestartDateytokens.- El punto de acceso requiere autenticación respaldada por los servicios de Codex. Admite la autenticación con ChatGPT, tokens externos de ChatGPT, identidad de agente y tokens de acceso personal. No admite la autenticación solo con clave de API ni la autenticación de Bedrock.
8) Restablecimientos obtenidos del límite de solicitudes (ChatGPT)
Usa account/rateLimitResetCredit/consume para consumir uno de los restablecimientos obtenidos.
{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }
Notas sobre los campos:
idempotencyKeyno puede estar vacío. Usa un UUID por cada intento lógico de canje y reutiliza ese valor si vuelves a intentar el mismo canje.creditIdes opcional. Si lo proporcionas, debe ser un ID opaco no vacío devuelto poraccount/rateLimits/read. Si lo omites, el servicio selecciona el siguiente crédito disponible.resetsignifica que se consumió un crédito.alreadyRedeemedsignifica que ese mismo canje ya se completó. Trátalo como una operación idempotente exitosa y actualiza los límites de la cuenta.nothingToResetsignifica que no hay ningún periodo del límite de solicitudes que se pueda restablecer.noCreditsignifica que la cuenta no dispone de créditos obtenidos para restablecer el límite.- Consulta
account/rateLimits/readdespués de consumir un restablecimiento en lugar de deducir de esta respuesta los periodos actualizados.
9) Avisar a un propietario del espacio de trabajo sobre un límite
Usa account/sendAddCreditsNudgeEmail para pedir a ChatGPT que envíe un correo electrónico a un propietario del espacio de trabajo cuando se agoten los créditos o se alcance un límite de uso.
{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }
Usa creditType: "credits" cuando se agoten los créditos del espacio de trabajo o creditType: "usage_limit" cuando se alcance su límite de uso. Si el propietario ya recibió un aviso recientemente, el estado de la respuesta es cooldown_active.
10) Mensajes del espacio de trabajo (ChatGPT)
Usa account/workspaceMessages/read para obtener los mensajes activos del espacio de trabajo actual, incluidos los títulos de las notificaciones cuando estén disponibles.
{ "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 }
] } }