Español

App Server de Codex

App Server de Codex

Codex app-server es la interfaz que utiliza Codex para operar clientes avanzados (por ejemplo, la extensión de Codex para VS Code). Úsala cuando quieras una integración profunda en tu propio producto: autenticación, historial de conversaciones, aprobaciones y eventos del agente transmitidos en tiempo real. La implementación de app-server es de código abierto y está disponible en el repositorio de Codex en GitHub (openai/codex/codex-rs/app-server). Consulta la página Código abierto para ver la lista completa de componentes de código abierto de Codex.

Conectar la interfaz de terminal de la CLI

El modo de interfaz de terminal remota permite ejecutar app-server en una máquina y conectar la interfaz de terminal de la CLI de Codex desde otra. Inicia un servicio de escucha WebSocket:

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

Después, conecta la interfaz de terminal:

codex --remote ws://127.0.0.1:4500

Para una conexión no local, configura la autenticación de WebSocket y protege la conexión con TLS. Guarda el token de portador en una variable de entorno y pasa su nombre en lugar de incluir 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 endpoints ws://, wss://, unix:// y unix://PATH. Usa WebSockets sin cifrar únicamente para localhost o una conexión con reenvío de puertos mediante SSH.

Conectar un host remoto de Code Mode

De forma predeterminada, app-server inicia un host local de Code Mode. Para usar en su lugar un host remoto, pasa su URL segura de WebSocket:

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

--code-mode-host controla la conexión saliente de app-server a su host de Code Mode. No cambia --listen, que controla cómo se conectan los clientes a app-server. Todos los hilos del mismo proceso de app-server comparten la conexión seleccionada con el host de Code Mode.

Usa wss:// para un host remoto. Usa ws:// únicamente para una conexión localhost o con reenvío mediante SSH. El comando de app-server y el transporte WebSocket son experimentales y no se admiten para cargas de trabajo de producción.

Protocolo

Al igual que MCP, codex app-server admite comunicación bidireccional mediante mensajes JSON-RPC 2.0 (con el encabezado "jsonrpc":"2.0" omitido en la transmisión).

Transportes compatibles:

  • stdio (--listen stdio://, predeterminado): JSON delimitado por saltos de línea (JSONL).
  • websocket (--listen ws://IP:PORT, experimental y no compatible): un mensaje JSON-RPC por cada trama de texto WebSocket.
  • Socket Unix (--listen unix:// o --listen unix://PATH): conexiones WebSocket mediante el socket de control predeterminado de app-server de Codex o una ruta de socket Unix personalizada, utilizando el protocolo de enlace HTTP Upgrade estándar.
  • off (--listen off): no expone ningún transporte local.

Cuando se ejecuta con --listen ws://IP:PORT, el mismo servicio de escucha también atiende sondas HTTP básicas de estado:

  • GET /readyz devuelve 200 OK cuando el servicio de escucha acepta conexiones nuevas.
  • GET /healthz devuelve 200 OK cuando la solicitud no incluye un encabezado Origin.
  • Las solicitudes con un encabezado Origin se rechazan con 403 Forbidden.

El transporte WebSocket es experimental y no es compatible. Los servicios de escucha locales como ws://127.0.0.1:PORT son apropiados para flujos de trabajo en localhost y con reenvío de puertos mediante SSH. Actualmente, durante el despliegue progresivo, los servicios de escucha WebSocket que no son de bucle invertido permiten conexiones no autenticadas de forma predeterminada; por tanto, configura la autenticación de WebSocket antes de exponer uno de forma remota.

Indicadores de autenticación de WebSocket compatibles:

  • --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 tokens de portador firmados, también puedes establecer --ws-issuer, --ws-audience y --ws-max-clock-skew-seconds. Los clientes presentan la credencial como Authorization: Bearer <token> durante el protocolo de enlace WebSocket, y app-server aplica la autenticación antes de initialize de JSON-RPC.

Prefiere --ws-token-file en lugar de pasar tokens de portador sin procesar en la línea de comandos. Usa --ws-token-sha256 únicamente cuando el cliente mantenga el token sin procesar de alta entropía en un almacén de secretos local independiente; el hash solo sirve como verificador y los clientes siguen necesitando el token original.

En modo WebSocket, app-server utiliza colas limitadas. Cuando la entrada de solicitudes está llena, 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 volver a intentarlo con un retraso que aumente exponencialmente y una variación aleatoria.

Esquema de mensajes

Las solicitudes incluyen method, params y id:

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

Las respuestas repiten el id 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 utilizan method y params:

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

Puedes generar un esquema de TypeScript o un paquete de JSON Schema desde la CLI. Cada salida es específica de la versión de Codex que hayas ejecutado, por lo que los artefactos generados coinciden exactamente con esa versión:

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

Primeros pasos

  1. Inicia el servidor con codex app-server (transporte stdio predeterminado), codex app-server --listen ws://127.0.0.1:4500 (WebSocket TCP) o codex app-server --listen unix:// (socket Unix predeterminado).
  2. Conecta un cliente mediante el transporte seleccionado y, después, envía initialize seguido de la notificación initialized.
  3. Inicia un hilo y un turno; después, continúa leyendo las notificaciones del flujo de transporte activo.

Ejemplo (Node.js / TypeScript):




const proc = spawn("codex", ["app-server"], {
  stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });

const send = (message: unknown) => {
  proc.stdin.write(`${JSON.stringify(message)}\n`);
};

let threadId: string | null = null;

rl.on("line", (line) => {
  const msg = JSON.parse(line) as any;
  console.log("server:", msg);

  if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
    threadId = msg.result.thread.id;
    send({
      method: "turn/start",
      id: 2,
      params: {
        threadId,
        input: [{ type: "text", text: "Summarize this repo." }],
      },
    });
  }
});

send({
  method: "initialize",
  id: 0,
  params: {
    clientInfo: {
      name: "my_product",
      title: "My Product",
      version: "0.1.0",
    },
  },
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.6-terra" } });

Elementos fundamentales

  • Hilo: una conversación entre un usuario y el agente Codex. Los hilos contienen turnos.
  • Turno: una única solicitud del usuario y el trabajo posterior del agente. Los turnos contienen elementos y transmiten actualizaciones incrementales.
  • Elemento: una unidad de entrada o salida (mensaje del usuario, mensaje del agente, ejecuciones de comandos, cambio de archivo, llamada a una herramienta y más).

Usa las API de hilos para crear, enumerar o archivar conversaciones. Gestiona una conversación con las API de turnos y transmite el progreso mediante las notificaciones de turnos.

Descripción general del ciclo de vida

  • Inicializar una vez por conexión: inmediatamente después de abrir una conexión de transporte, envía una solicitud initialize con los metadatos de tu cliente y, después, emite initialized. El servidor rechaza cualquier solicitud realizada en esa conexión antes de este protocolo de enlace.
  • Iniciar (o reanudar) un hilo: llama a thread/start para una conversación nueva, a thread/resume para continuar una existente o a thread/fork para bifurcar el historial en un nuevo id de hilo.
  • Comenzar un turno: llama a turn/start con el threadId de destino y la entrada del usuario. Los campos opcionales sustituyen el modelo, la personalidad, cwd, la política de aislamiento y otros valores.
  • Dirigir un turno activo: llama a turn/steer para agregar la entrada del usuario al turno actualmente en curso sin crear uno nuevo.
  • Transmitir eventos: después de turn/start, continúa leyendo notificaciones en stdout: thread/archived, thread/unarchived, item/started, item/completed, item/agentMessage/delta, el progreso de las herramientas y otras actualizaciones.
  • Finalizar el turno: el servidor emite turn/completed con el estado final cuando el modelo termina o después de una cancelación mediante turn/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, después, confirmarla con una notificación initialized. Las solicitudes enviadas antes de la inicialización reciben un error Not initialized, y las llamadas repetidas a initialize en la misma conexión devuelven Already initialized.

El servidor devuelve la cadena del agente de usuario que presentará a los servicios ascendentes, además de los valores platformFamily y platformOs que describen el destino de ejecución. Establece 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 suprimir en esta conexión. La coincidencia es exacta (sin comodines ni prefijos); los nombres desconocidos se aceptan y se ignoran.
  • requestAttestation: habilita la solicitud attestation/generate iniciada por el servidor. Los hosts de escritorio que proporcionan certificación ascendente responden con un valor { "token": "..." } opaco.
  • mcpServerOpenaiFormElicitation: permite que los servidores MCP descendentes envíen la variante de formato extendido de OpenAI de mcpServer/elicitation/request.

Importante: Usa clientInfo.name para identificar tu cliente ante la Plataforma de registros de cumplimiento de OpenAI. Si estás desarrollando una nueva integración de Codex destinada al uso empresarial, ponte en contacto con OpenAI para que se añada a la lista de clientes conocidos. Para obtener más contexto, 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 con exclusión voluntaria de 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 están restringidos intencionalmente mediante la capacidad experimentalApi.

  • Omite capabilities (o establece experimentalApi en false) para mantenerte en la superficie estable de la API; el servidor rechazará los métodos y campos experimentales.
  • Establece capabilities.experimentalApi en true para 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 haberlo habilitado, app-server lo rechaza con:

<descriptor> requires experimentalApi capability

Descripción general de la API

  • thread/start: crea un hilo nuevo; emite thread/started y te suscribe automáticamente a los eventos de turnos/elementos de ese hilo.
  • thread/resume: vuelve a abrir un hilo existente por id para que las llamadas posteriores a turn/start se anexen a él.
  • thread/fork: bifurca un hilo en un nuevo id de hilo copiando el historial almacenado. Pasa lastTurnId para copiar el historial hasta ese turno y omitir los turnos posteriores, o ephemeral: true para crear una bifurcación en memoria. Emite thread/started para el hilo nuevo; los hilos devueltos incluyen forkedFromId cuando está disponible.
  • thread/read: lee un hilo almacenado por id sin reanudarlo; establece includeTurns para devolver el historial completo de turnos. Los objetos thread devueltos incluyen el status del entorno de ejecución.
  • thread/list: recorre por páginas los registros de hilos almacenados; admite paginación basada en cursor, además de modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm y los filtros experimentales parentThreadId o ancestorThreadId. Los objetos thread devueltos incluyen el status del entorno de ejecución.
  • thread/turns/list: experimental; recorre por páginas el historial de turnos de un hilo almacenado sin reanudarlo. itemsView controla si los elementos del turno se omiten, se resumen o se cargan por completo.
  • thread/items/list: experimental; recorre por páginas los elementos persistentes del hilo, con la opción de restringirlos a un solo turnId. El almacén de hilos activo debe admitir la paginación de elementos.
  • thread/loaded/list: enumera los ids de los hilos cargados actualmente en memoria.
  • thread/name/set: establece o actualiza el nombre visible para el usuario de un hilo cargado o de un rollout persistente; emite thread/name/updated.
  • thread/goal/set: establece el objetivo de un hilo; emite thread/goal/updated.
  • thread/goal/get: lee el objetivo actual de un hilo.
  • thread/goal/clear: borra el objetivo de un hilo; emite thread/goal/cleared.
  • thread/metadata/update: modifica los metadatos de hilos almacenados respaldados por SQLite, incluidos gitInfo y isPinned persistentes.
  • thread/archive: mueve el archivo de registro de un hilo al directorio de archivados e intenta archivar los registros de los hilos descendientes generados que aún no estén archivados; devuelve {} si se completa correctamente y emite thread/archived por cada hilo archivado.
  • thread/delete: elimina permanentemente un hilo persistente activo o archivado y todos sus hilos descendientes generados; devuelve {} si se completa correctamente y emite thread/deleted por cada hilo eliminado.
  • thread/unsubscribe: cancela la suscripción de esta conexión a los eventos de turnos/elementos del hilo. Si era el último suscriptor, el servidor descarga el hilo después de un periodo de gracia de inactividad sin suscriptores y emite thread/closed.
  • thread/unarchive: restaura el rollout de un hilo archivado en el directorio de sesiones activas; devuelve el thread restaurado y emite thread/unarchived.
  • thread/status/changed: notificación que se emite cuando cambia el status del entorno de ejecución de un hilo cargado.
  • thread/compact/start: inicia la compactación del historial de conversación de un hilo; devuelve {} de inmediato, mientras el progreso se transmite mediante las notificaciones turn/* y item/*.
  • thread/shellCommand: ejecuta un comando de shell iniciado por el usuario en un hilo. Se ejecuta fuera del entorno aislado con acceso completo y no hereda la política del entorno aislado del hilo.
  • thread/backgroundTerminals/clean: detiene todos los terminales en segundo plano que se estén ejecutando para un hilo (experimental; requiere capabilities.experimentalApi).
  • thread/backgroundTerminals/list: enumera los terminales en segundo plano en ejecución de un hilo cargado (experimental; requiere capabilities.experimentalApi).
  • thread/backgroundTerminals/terminate: finaliza un terminal en segundo plano en ejecución mediante el processId de app-server (experimental; requiere capabilities.experimentalApi).
  • thread/rollback: obsoleto; elimina los últimos N turnos del contexto en memoria y conserva un marcador de reversión; devuelve el thread actualizado.
  • turn/start: agrega una entrada del usuario o una salida independiente de una herramienta a un hilo e inicia la generación de Codex; responde con el turn inicial y transmite eventos. Para collaborationMode, settings.developer_instructions: null significa «usar las instrucciones integradas para el modo seleccionado».
  • thread/inject_items: agrega elementos sin procesar de Responses API al historial visible para el modelo de un hilo cargado sin iniciar un turno del usuario.
  • turn/steer: agrega una entrada del usuario al turno activo en curso de un hilo; devuelve el turnId aceptado.
  • turn/interrupt: solicita la cancelación de un turno en curso; la operación correcta se indica con {} y el turno finaliza con status: "interrupted".
  • review/start: inicia el revisor de Codex para un hilo; emite elementos enteredReviewMode y exitedReviewMode.
  • command/exec: ejecuta un solo comando en el entorno aislado del servidor sin iniciar un hilo/turno.
  • command/exec/write: escribe bytes stdin en una sesión command/exec en ejecución o cierra stdin.
  • command/exec/resize: cambia el tamaño de una sesión command/exec en ejecución respaldada por PTY.
  • command/exec/terminate: detiene una sesión command/exec en ejecución.
  • command/exec/outputDelta (notificación): se emite para fragmentos de stdout/stderr codificados en base64 provenientes de una sesión command/exec de transmisión.
  • process/spawn: inicia una sesión de proceso explícita fuera del entorno aislado de Codex (experimental; requiere capabilities.experimentalApi).
  • process/writeStdin: escribe bytes de stdin en una sesión process/spawn en ejecución o cierra stdin (experimental).
  • process/resizePty: cambia el tamaño de una sesión de proceso en ejecución respaldada por PTY (experimental).
  • process/kill: finaliza una sesión de proceso en ejecución (experimental).
  • process/outputDelta y process/exited (notificación): se emiten para la salida de proceso transmitida y el estado de salida del proceso (experimental).
  • model/list: enumera los modelos disponibles (establece includeHidden: true para incluir entradas con hidden: true) con opciones de esfuerzo, un upgrade opcional y inputModalities.
  • modelProvider/capabilities/read: lee los límites de las capacidades del proveedor para combinaciones de modelo/proveedor.
  • experimentalFeature/list: enumera los indicadores de características con metadatos de la etapa del ciclo de vida y paginación por cursor.
  • experimentalFeature/enablement/set: modifica la configuración del entorno de ejecución en memoria para claves de características compatibles, como apps y plugins.
  • environment/info: experimental; se conecta a un entorno de ejecución configurado y devuelve su shell y directorio de trabajo predeterminado.
  • permissionProfile/list: enumera los perfiles de permisos beta e indica si los requisitos efectivos los permiten, con paginación por cursor.
  • collaborationMode/list: enumera los ajustes predefinidos del modo de colaboración (experimental, sin paginación).
  • skills/list: enumera las skills para uno o varios valores cwd (admite forceReload y el valor opcional perCwdExtraUserRoots).
  • skills/extraRoots/set: sustituye las raíces adicionales del proceso que se usan para detectar skills independientes sin conservarlas.
  • skills/changed (notificación): se emite cuando cambian los archivos locales de skills supervisados.
  • hooks/list: enumera los hooks de ciclo de vida detectados para uno o varios valores cwd.
  • marketplace/add: agrega un marketplace remoto de plugins y lo conserva en la configuración de marketplaces del usuario.
  • marketplace/remove: elimina un marketplace configurado y, si existe, la raíz de su marketplace instalado.
  • marketplace/upgrade: actualiza un marketplace Git configurado, o todos los marketplaces Git configurados si se omite el nombre del marketplace.
  • plugin/list: en desarrollo; enumera los marketplaces de plugins detectados y el estado de los plugins, incluidos los metadatos de las políticas de instalación/autenticación, los errores de carga del marketplace, los ids de plugins destacados y los metadatos del origen local, Git, de registro de paquetes o remoto de los plugins. Los resúmenes pueden incluir el version remoto, el localVersion local, iconos estructurados para tema claro/oscuro y installPolicySource, que puede ser null, WORKSPACE_SETTING o IMPLICIT_CANONICAL_APP para las filas remotas actuales. No llames todavía a este método desde clientes de producción.
  • plugin/read: en desarrollo; lee un plugin mediante una ruta de marketplace o mediante el nombre del marketplace remoto y el nombre del plugin, incluidas las skills, las apps y los nombres de servidores MCP incluidos, así como un shareUrl de plugin remoto cuando el catálogo remoto proporciona uno. No llames todavía a este método desde clientes de producción.
  • plugin/install: en desarrollo; instala un plugin desde una ruta de marketplace o un nombre de marketplace remoto. No llames todavía a este método desde clientes de producción.
  • plugin/uninstall: en desarrollo; desinstala un plugin instalado. No llames todavía a este método desde clientes de producción.
  • plugin/skill/read: lee bajo demanda el Markdown de la skill de un plugin remoto mediante el marketplace remoto, el id del plugin y el nombre de la skill.
  • app/installed: lee el estado del entorno de ejecución de las apps instaladas, incluidos los estados efectivos de habilitación y disponibilidad para llamadas de cada app.
  • app/list: enumera las apps (conectores) disponibles con paginación y metadatos de accesibilidad/habilitación.
  • app/read: obtiene metadatos y resúmenes opcionales de herramientas solo para visualización correspondientes a ids de apps específicos.
  • skills/config/write: habilita o deshabilita skills por ruta.
  • mcpServer/oauth/login: inicia un acceso OAuth para un servidor MCP configurado; devuelve una URL de autorización y emite mcpServer/oauthLogin/completed al finalizar.
  • tool/requestUserInput: presenta al usuario entre 1 y 3 preguntas breves para una llamada a una herramienta (experimental); las preguntas pueden establecer isOther para ofrecer una opción de texto libre.
  • mcpServer/elicitation/request (solicitud del servidor): pide al cliente datos estructurados de un formulario o la confirmación de un flujo de 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 integrada request_permissions.
  • config/mcpServer/reload: vuelve a cargar desde el disco la configuración del servidor MCP y pone en cola una actualización para los hilos cargados.
  • mcpServerStatus/list: enumera los servidores, las herramientas, los recursos y el estado de autenticación de MCP (paginación mediante cursor + límite). Usa detail: "full" para obtener todos los datos o detail: "toolsAndAuthOnly" para omitir los recursos.
  • mcpServer/resource/read: lee un único recurso MCP mediante un servidor MCP inicializado.
  • mcpServer/tool/call: llama a una herramienta en el servidor MCP configurado de 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/setupStart: inicia la configuración del entorno aislado de Windows para el modo elevated o unelevated; devuelve una respuesta rápidamente y emite windowsSandbox/setupCompleted más adelante.
  • feedback/upload: envía un informe de comentarios (clasificación + motivo/registros opcionales + id de conversación, además de archivos adjuntos extraLogFiles opcionales).
  • config/read: obtiene la configuración efectiva en el disco después de resolver las capas de configuración.
  • externalAgentConfig/detect: detecta artefactos de agentes externos que se pueden migrar con includeHome y el valor opcional cwds; cada elemento detectado incluye cwd (null para el directorio personal).
  • externalAgentConfig/import: aplica los elementos seleccionados de la migración de agentes externos pasando valores migrationItems explícitos con cwd (null para el directorio personal). Los tipos de elementos compatibles incluyen configuración, skills, AGENTS.md, plugins, configuración de servidores MCP, subagentes, hooks, comandos y sesiones; las importaciones no vacías emiten externalAgentConfig/import/progress y externalAgentConfig/import/completed a medida que finaliza el trabajo. Las importaciones de plugins y sesiones pueden completarse de forma asíncrona.
  • config/value/write: escribe una única clave/valor de configuración en el config.toml del usuario en el disco.
  • config/batchWrite: aplica de forma atómica modificaciones de configuración al config.toml del usuario en el disco.
  • configRequirements/read: obtiene requisitos de requirements.toml y/o MDM, incluidos la configuración administrada exacta, las listas de permitidos, los featureRequirements fijados y los requisitos de red (o null si no se ha configurado ninguno).
  • fs/readFile, fs/writeFile, fs/createDirectory, fs/getMetadata, fs/readDirectory, fs/remove, fs/copy, fs/watch, fs/unwatch y fs/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 plugins incluyen una unión source. Los plugins locales devuelven { "type": "local", "path": ... }, las entradas de marketplaces respaldadas por Git devuelven { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }, las entradas del registro de paquetes devuelven { "type": "npm", "package": ..., "version": ..., "registry": ... } y las entradas del catálogo remoto devuelven { "type": "remote" }. Para entradas de catálogo exclusivamente remotas, PluginMarketplaceEntry.path puede ser null; pasa remoteMarketplaceName en lugar de marketplacePath al leer o instalar esos plugins.

Modelos

Enumerar modelos (model/list)

Llama a model/list para descubrir los modelos disponibles y sus capacidades antes de representar selectores de modelo o personalidad.

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

Cada entrada de modelo puede incluir:

  • supportedReasoningEfforts: opciones de esfuerzo compatibles con el modelo.
  • defaultReasoningEffort: esfuerzo predeterminado sugerido para los clientes.
  • upgrade: id opcional del modelo de actualización recomendado para las solicitudes de migración en los clientes.
  • upgradeInfo: metadatos opcionales de actualización para las solicitudes de migración en los clientes.
  • hidden: indica si el modelo está oculto en la lista predeterminada del selector.
  • inputModalities: tipos de entrada compatibles con el modelo (por ejemplo, text, image).
  • supportsPersonality: indica si el modelo admite instrucciones específicas de la personalidad, como /personality.
  • isDefault: indica si el modelo es el predeterminado recomendado.

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 (catálogos de modelos antiguos), trátalo como ["text", "image"] para mantener la compatibilidad con versiones anteriores.

Enumerar funcionalidades experimentales (experimentalFeature/list)

Usa este endpoint para descubrir indicadores de funcionalidades con metadatos y la etapa del 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 los indicadores que no estén en fase 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 file: canónico que utiliza la sintaxis de rutas nativa del entorno. Los id de entorno desconocidos y los errores de conexión o de protocolo devuelven errores de solicitud.

Hilos

  • thread/read lee un hilo almacenado sin suscribirse a él; establece includeTurns para incluir los turnos.
  • thread/turns/list es experimental y recorre por páginas el historial de turnos de un hilo almacenado sin reanudarlo. Usa itemsView para elegir si los elementos de los turnos se omiten, se resumen o se cargan por completo.
  • thread/items/list es experimental y recorre por páginas los elementos persistentes del hilo, con la opción de restringirlos a un turno.
  • thread/list admite paginación mediante cursor, además de modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm y los filtros experimentales parentThreadId o ancestorThreadId.
  • thread/loaded/list devuelve los id de los hilos que están actualmente en memoria.
  • thread/archive mueve el registro JSONL persistente del hilo al directorio de archivados e intenta archivar los registros de los hilos descendientes generados que aún no estén archivados.
  • thread/delete elimina de forma permanente un hilo persistente activo o archivado y sus hilos descendientes generados.
  • thread/metadata/update modifica los metadatos almacenados del hilo, incluidos gitInfo y isPinned persistentes.
  • thread/unsubscribe cancela la suscripción de la conexión actual a un hilo cargado y puede activar thread/closed después de un periodo de gracia de inactividad.
  • thread/unarchive restaura una ejecución de hilo archivada en el directorio de sesiones activas.
  • thread/compact/start activa la compactación y devuelve {} inmediatamente.
  • thread/rollback está obsoleto. Elimina los últimos N turnos del contexto en memoria y registra un marcador de reversión en el registro JSONL persistente del hilo.
  • thread/inject_items agrega elementos sin procesar de Responses API al historial visible para el modelo de un hilo cargado sin iniciar un turno del usuario.

Iniciar o reanudar un hilo

Inicia un hilo nuevo cuando necesites una conversación nueva de Codex.

{ "method": "thread/start", "id": 10, "params": {
  "model": "gpt-5.6-terra",
  "cwd": "/Users/me/project",
  "approvalPolicy": "never",
  "sandbox": "workspaceWrite",
  "personality": "friendly",
  "serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
  "thread": {
    "id": "thr_123",
    "sessionId": "thr_123",
    "preview": "",
    "ephemeral": false,
    "modelProvider": "openai",
    "createdAt": 1730910000
  }
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }

serviceName es opcional. Establécelo cuando quieras que app-server etiquete las métricas del hilo con el nombre de servicio de tu integración.

thread/start, thread/resume y thread/fork devuelven instructionSources, una matriz de rutas de archivos de instrucciones cargados. Cada ruta utiliza la sintaxis absoluta nativa de su entorno de origen, incluidos los entornos remotos.

Los clientes experimentales pueden establecer historyMode en thread/start como "legacy" (el valor predeterminado) o "paginated". La creación de hilos paginados aún no es compatible y devuelve el error JSON-RPC -32601. App-server puede enumerar y leer resúmenes de registros paginados existentes, pero las lecturas del historial completo, la paginación de turnos y la reanudación fallan de forma segura hasta que se admita el historial paginado.

Los clientes beta que habiliten capabilities.experimentalApi pueden pasar el id de un perfil de permisos con nombre en permissions en lugar del campo antiguo sandbox. No envíes permissions y sandbox juntos. Usa permissionProfile/list con el cwd del proyecto para descubrir los perfiles disponibles y si los requisitos administrados permiten cada uno de ellos.

thread.sessionId identifica la raíz actual del árbol de sesiones activas. Los hilos raíz utilizan su propio id de hilo como id de sesión; los hilos bifurcados mantienen 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 derivarlo del id del hilo.

Para continuar una sesión almacenada, llama a thread/resume con el thread.id que registraste anteriormente. La forma de la respuesta coincide con thread/start. También puedes pasar las mismas sustituciones de configuración que admite thread/start, como personality:

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

Reanudar un hilo no actualiza por sí solo thread.updatedAt (ni la hora de modificación del archivo de ejecución). La marca de tiempo se actualiza al iniciar un turno.

Si marcas un servidor MCP habilitado como required en la configuración y ese servidor no puede inicializarse, 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 conserva estas herramientas dinámicas en los metadatos de ejecución del hilo y las restaura al ejecutar thread/resume cuando no se proporcionan herramientas dinámicas nuevas.

Si reanudas con un modelo distinto del registrado en la ejecució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 TUI.

{ "method": "thread/goal/set", "id": 13, "params": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000,
  "tokensUsed": 0,
  "timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
  "threadId": "thr_123",
  "goal": {
    "threadId": "thr_123",
    "objective": "Finish the migration and keep tests green",
    "status": "active",
    "tokenBudget": 40000,
    "tokensUsed": 0,
    "timeUsedSeconds": 0
  }
} }

Los objetivos deben tener contenido y un máximo de 4.000 caracteres. Proporcionar un nuevo objetivo sustituye el actual y restablece la contabilidad de uso. Proporcionar el objetivo actual que no sea terminal u omitir objective actualiza el estado o el presupuesto de tokens sin eliminar el historial de uso.

Para bifurcar desde una sesión almacenada, llama a thread/fork con el thread.id. Esto crea un nuevo id de hilo y emite una notificación thread/started para él. Pasa lastTurnId para copiar el historial hasta ese turno, incluyéndolo, y omitir los turnos posteriores:

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

App-server rechaza un lastTurnId en curso. Si omites el campo mientras el hilo de origen se encuentra a mitad de un turno, la bifurcación registra un marcador de interrupción en lugar de conservar un turno parcial sin marcar.

Pasa ephemeral: true para crear una bifurcación en memoria sin agregarla a las listas de hilos almacenados:

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

Las bifurcaciones efímeras de hilos paginados también requieren excludeTurns: true. Ese campo es experimental y requiere capabilities.experimentalApi = true.

Cuando se ha establecido un título visible para el usuario, app-server rellena thread.name en las respuestas thread/list, thread/read, thread/resume, thread/unarchive y thread/rollback. thread/start y thread/fork pueden omitir name (o devolver null) hasta que se establezca un título posteriormente.

Leer un hilo almacenado (sin reanudarlo)

Usa thread/read cuando quieras obtener los datos de un hilo almacenado, pero no quieras reanudarlo ni suscribirte a sus eventos.

  • includeTurns: cuando es true, la respuesta incluye los turnos del hilo; cuando es false o se omite, solo se obtiene el resumen del hilo.
  • Los objetos thread devueltos incluyen el valor de ejecución status (notLoaded, idle, systemError o active con activeFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }

A diferencia de thread/resume, thread/read no carga el hilo en memoria ni emite thread/started.

Enumerar los turnos de un hilo

thread/turns/list es experimental. Úselo 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, de modo que los clientes puedan obtener turnos anteriores mediante nextCursor. La respuesta también incluye backwardsCursor; páselo como cursor con sortDirection: "asc" para obtener turnos posteriores al primer elemento de la página anterior.

itemsView controla cuántos datos de los elementos del turno incluye la respuesta:

  • notLoaded omite los elementos.
  • summary devuelve datos resumidos de los elementos y es el valor predeterminado cuando se omite.
  • full devuelve todos los datos 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"
} }

thread/items/list también es experimental. Recorre por páginas los elementos persistentes sin reanudar el hilo. Pasa turnId para restringir los resultados a un turno u omítelo para recorrer por páginas los elementos de todo el hilo. 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 compatible.

Enumerar hilos (con paginación y filtros)

thread/list permite representar una interfaz de historial. De forma predeterminada, los resultados se ordenan por createdAt del más reciente al más antiguo. Los filtros se aplican antes de la paginación. Pasa cualquier combinación de:

  • cursor: cadena opaca de una respuesta anterior; omítala para la primera página.
  • limit: si no se establece, el servidor utiliza de forma predeterminada un tamaño de página razonable.
  • sortKey: created_at (predeterminado), updated_at o recency_at.
  • sortDirection: desc (predeterminado) o asc.
  • modelProviders: restringe los resultados a proveedores específicos; si no se establece, es nulo o es una matriz vacía, incluye todos los proveedores.
  • sourceKinds: restringe los resultados a orígenes de hilos específicos. Cuando se omite o es [], el servidor utiliza de forma predeterminada únicamente orígenes interactivos: cli y vscode.
  • archived: cuando es true, enumera únicamente los hilos archivados. Cuando es false o se omite, enumera los hilos no archivados (opción predeterminada).
  • isPinned: cuando se proporciona, devuelve únicamente los hilos cuyo estado de fijación persistente coincida. Omítalo para devolver hilos fijados y no fijados.
  • cwd: restringe los resultados a los hilos cuyo directorio de trabajo actual de la sesión coincida exactamente con esta ruta o con una de las rutas de una matriz. Las rutas relativas se resuelven desde el directorio de trabajo del proceso de app-server.
  • useStateDbOnly: cuando es true, devuelve los resultados de la base de datos de estado sin examinar los registros JSONL de los hilos para reparar los metadatos. Omítelo o pasa false para utilizar el comportamiento predeterminado de examen y reparación.
  • searchTerm: restringe los resultados a los hilos cuyo título extraído contenga este fragmento de texto, con distinción entre mayúsculas y minúsculas.
  • parentThreadId: restringe los resultados a los hilos secundarios directos del hilo indicado. Este filtro es experimental y requiere capabilities.experimentalApi = true.
  • ancestorThreadId: restringe los resultados a los descendientes generados del hilo indicado a cualquier profundidad. Este filtro es experimental y requiere capabilities.experimentalApi = true; no lo combine con parentThreadId.

sourceKinds acepta los valores siguientes:

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

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, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
    { "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
  ],
  "nextCursor": "opaque-token-or-null"
} }

Cuando nextCursor es null, has llegado a la última página.

Actualizar los metadatos almacenados de un hilo

Usa thread/metadata/update para modificar los metadatos almacenados de un hilo sin reanudarlo. Establece isPinned para fijar o dejar de fijar el hilo, o actualiza gitInfo para cambiar los metadatos Git persistentes. Los campos omitidos no cambian; un valor null explícito borra un valor de metadatos Git almacenado.

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

Realizar un seguimiento de los cambios de estado de los hilos

thread/status/changed se emite cada vez que cambia el estado de ejecución de un hilo cargado. La carga útil 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 que están actualmente 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 elimina la suscripción de la conexión actual a un hilo. El estado de la respuesta es uno de los siguientes:

  • unsubscribed cuando la conexión estaba suscrita y la suscripción ya se ha eliminado.
  • notSubscribed cuando la conexión no estaba suscrita a ese hilo.
  • notLoaded cuando el hilo no está cargado.

Si era el último suscriptor, el servidor mantiene el hilo cargado hasta que no tenga suscriptores ni actividad durante 30 minutos. Cuando vence el periodo de gracia, app-server descarga el hilo y emite una transición thread/status/changed a notLoaded, además de thread/closed.

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

Si el hilo vence posteriormente:

{ "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 persistente del hilo (almacenado como un archivo JSONL en el disco) al directorio de sesiones archivadas. Al archivar un hilo, también se 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 realmente archiva; si no se puede archivar un descendiente generado, la solicitud puede completarse correctamente sin emitir una notificación de archivo para ese descendiente.

Eliminar un hilo

Usa thread/delete para eliminar permanentemente un hilo activo o archivado persistente y los hilos descendientes que haya generado. El servidor elimina los archivos de rollout existentes y los metadatos asociados antes de devolver una respuesta correcta; los archivos de rollout ausentes se consideran ya eliminados. Los hilos raíz efímeros no se pueden eliminar.

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

Activar la compactación de un hilo

Usa thread/compact/start para activar manualmente la compactación del historial de un hilo. La solicitud devuelve inmediatamente {}.

App-server emite el progreso mediante notificaciones turn/* y item/* estándar en el mismo threadId, incluido el ciclo de vida de un elemento contextCompaction (item/started y después 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 los comandos de shell iniciados por el usuario que pertenezcan a un hilo. La solicitud devuelve inmediatamente {} mientras el progreso se transmite mediante las notificaciones turn/* y item/* estándar.

Esta API se ejecuta fuera del entorno aislado con acceso completo y no hereda la política de entorno aislado 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 con formato se inserta en el 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 se omite o se pasa null, se usa el valor predeterminado de una hora. 0 solicita un tiempo de espera inmediato; los valores negativos se rechazan. El tiempo de espera no retrasa la confirmación inmediata de RPC.

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

Limpiar 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 mediante cursor y limit, y el processId devuelto es el id. del proceso de 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 turnos recientes

thread/rollback está obsoleto y se eliminará. Elimina las últimas numTurns entradas del contexto en memoria y conserva un marcador de reversión en el registro del rollout. El thread devuelto incluye turns, que se rellena después de la reversión.

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

Turnos

El campo input acepta una lista de elementos:

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

Puedes sustituir los ajustes de configuración en cada turno (modelo, esfuerzo, personalidad, cwd, política de entorno aislado y resumen). Cuando se especifican, 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 valor booleano.

En turn/start.collaborationMode, settings.developer_instructions: null significa «usar las instrucciones integradas del modo seleccionado», no borrar las instrucciones del modo.

Acceso de lectura del entorno aislado (ReadOnlyAccess)

sandboxPolicy admite controles explícitos de acceso de lectura:

  • readOnly: access opcional ({ "type": "fullAccess" } de forma predeterminada o raíces restringidas).
  • workspaceWrite: readOnlyAccess opcional ({ "type": "fullAccess" } de forma predeterminada o raíces restringidas).

Estructura del acceso de lectura restringido:

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

En macOS, includePlatformDefaults: true añade una política Seatbelt predeterminada de la plataforma y seleccionada específicamente para las sesiones con lectura restringida. Esto mejora la compatibilidad de las herramientas sin permitir ampliamente 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": "unlessTrusted",
  "sandboxPolicy": {
    "type": "workspaceWrite",
    "writableRoots": ["/Users/me/project"],
    "networkAccess": true
  },
  "model": "gpt-5.6-terra",
  "effort": "medium",
  "summary": "concise",
  "personality": "friendly",
  "outputSchema": {
    "type": "object",
    "properties": { "answer": { "type": "string" } },
    "required": ["answer"],
    "additionalProperties": false
  }
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }

Para iniciar un turno con la salida de una herramienta que ejecutó tu cliente, pasa toolOutput con un name no vacío, un namespace opcional y una cadena output o un arreglo de elementos de contenido. Establece input como un arreglo vacío; no puedes combinar toolOutput con una entrada del usuario no 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 permanece como salida de herramienta en la conversación y aparece como un elemento functionCallOutput en las notificaciones y el historial persistente. 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 añadir elementos preconstruidos de la Responses API al historial de mensajes de un hilo cargado sin iniciar un turno de usuario. Estos elementos se conservan en el rollout y se incluyen en 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 añadir más entradas del usuario al turno activo en curso.

  • Incluye expectedTurnId; debe coincidir con el id. del turno activo.
  • La solicitud falla si el hilo no tiene ningún turno activo.
  • turn/steer no emite una nueva notificación turn/started.
  • turn/steer no acepta sustituciones en el ámbito del turno (model, cwd, sandboxPolicy ni outputSchema).
{ "method": "turn/steer", "id": 32, "params": {
  "threadId": "thr_123",
  "input": [ { "type": "text", "text": "Actually focus on failing tests first." } ],
  "expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }

Iniciar un turno (invocar una skill)

Invoca una skill explícitamente incluyendo $<skill-name> en la entrada de texto y añadiendo junto a ella un elemento de entrada skill.

{ "method": "turn/start", "id": 33, "params": {
  "threadId": "thr_123",
  "input": [
    { "type": "text", "text": "$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage." },
    { "type": "skill", "name": "skill-creator", "path": "/Users/me/.codex/skills/skill-creator/SKILL.md" }
  ]
} }
{ "id": 33, "result": { "turn": { "id": "turn_457", "status": "inProgress", "items": [], "error": null } } }

Interrumpir un turno

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

Si la operación se completa correctamente, el turno finaliza con status: "interrupted".

Revisión

review/start ejecuta el revisor de Codex para un hilo y transmite los elementos de revisión. Los objetivos incluyen:

  • uncommittedChanges
  • baseBranch (diferencias respecto a una rama)
  • commit (revisar un commit específico)
  • custom (instrucciones en formato libre)

Usa delivery: "inline" (valor predeterminado) para ejecutar la revisión en el hilo existente o delivery: "detached" para bifurcar un hilo de revisión nuevo.

Ejemplo de solicitud/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"
} }

Para realizar una revisión separada, usa "delivery": "detached". La respuesta tiene la misma estructura, pero reviewThreadId será el id. del nuevo hilo de revisión (distinto del threadId original). El servidor también emite una notificación thread/started para ese nuevo hilo antes de transmitir el turno de revisión.

Codex transmite la notificación turn/started habitual, seguida de un 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 y item/completed, que contienen un elemento exitedReviewMode con 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 representar la salida del revisor en tu cliente.

Ejecución de procesos

process/* es una API experimental y explícita de control de procesos. Requiere capabilities.experimentalApi = true y se ejecuta fuera del entorno aislado de Codex. Úsala solo cuando tu cliente exponga intencionalmente el control local de procesos sin un entorno aislado.

Inicia un proceso con process/spawn y proporciona un processHandle; después, usa ese identificador para las solicitudes de entrada estándar, cambio de tamaño y finalización. La salida se transmite mediante notificaciones process/outputDelta y la finalización, 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 entradas. Usa process/resizePty para los eventos de cambio de tamaño de PTY y process/kill para finalizar un proceso en ejecución.

Ejecución de comandos

command/exec ejecuta un solo comando (matriz argv) en el entorno aislado 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 entorno aislado y quieres que Codex omita la aplicación de su propio entorno aislado. Para el modo de entorno aislado externo, establece networkAccess en restricted (valor predeterminado) o enabled. Para readOnly y workspaceWrite, usa la misma estructura opcional access / readOnlyAccess mostrada anteriormente.

Notas:

  • El servidor rechaza las matrices command vacías.
  • sandboxPolicy acepta la misma estructura que turn/start (por ejemplo, dangerFullAccess, readOnly, workspaceWrite y externalSandbox).
  • Si se omite, timeoutMs recurre al valor predeterminado del servidor.
  • Establece tty: true para las sesiones respaldadas por PTY y usa processId cuando tengas previsto continuar con command/exec/write, command/exec/resize o command/exec/terminate.
  • Establece streamStdoutStderr: true para recibir notificaciones command/exec/outputDelta mientras se ejecuta el comando.

Consultar los requisitos de administración (configRequirements/read)

Usa configRequirements/read para inspeccionar los requisitos de administración efectivos cargados desde requirements.toml o MDM, o desde ambos.

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

result.requirements es null cuando no hay requisitos configurados. Consulta la documentación sobre requirements.toml para obtener información sobre las claves y los valores admitidos.

Configuración del entorno aislado de Windows (windowsSandbox/setupStart)

Los clientes personalizados de Windows pueden activar la configuración del entorno aislado de forma asíncrona en lugar de bloquearse durante las comprobaciones de inicio.

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

App-server inicia la configuración en segundo plano y posteriormente emite una notificación de finalización:

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

Modos:

  • elevated: ejecuta la ruta de configuración elevada del entorno aislado de Windows.
  • unelevated: ejecuta la ruta heredada de configuración/comprobación previa.

Sistema de archivos

Las API v2 del sistema de archivos operan con rutas absolutas. Usa fs/watch cuando un cliente necesite invalidar el estado de la interfaz de usuario después de que cambie 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": {} }

La supervisión de un archivo emite fs/changed para la ruta de ese archivo, incluidas las actualizaciones realizadas mediante operaciones de sustitución o cambio de nombre.

Eventos

Las notificaciones de eventos son el flujo iniciado por el servidor para los ciclos de vida de los hilos, los ciclos de vida de los turnos y los elementos que contienen. Después de iniciar o reanudar un hilo, continúa 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.

Exclusión voluntaria de notificaciones

Los clientes pueden suprimir notificaciones específicas por conexión enviando los nombres de método exactos en initialize.params.capabilities.optOutNotificationMethods.

  • Solo coincidencias exactas: item/agentMessage/delta suprime únicamente ese método.
  • Los nombres de método desconocidos se ignoran.
  • Se aplica a las notificaciones thread/*, turn/*, item/* y otras notificaciones v2 relacionadas actuales.
  • 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 finalizan la indexación y la búsqueda de coincidencias de esa consulta.

Eventos de advertencia

  • configWarning: { summary, details?, path?, range? } para problemas recuperables de configuración o inicialización.
  • warning: { threadId?, message } para advertencias no fatales durante la ejecución.

Eventos de configuración del entorno aislado de Windows

  • windowsSandbox/setupCompleted: { mode, success, error } emitido después de finalizar una solicitud windowsSandbox/setupStart.

Eventos de turno

  • turn/started: { turn } con el id. del turno, un items vacío y status: "inProgress".
  • turn/completed: { turn } donde turn.status es completed, interrupted o failed; los fallos incluyen { error: { message, codexErrorInfo?, additionalDetails? } }.
  • turn/diff/updated: { threadId, turnId, diff } con las últimas diferencias unificadas agregadas de todos los cambios de archivos del turno.
  • turn/plan/updated: { turnId, explanation?, plan } cada vez que el agente comparte o modifica su plan; cada entrada plan es { step, status } con status en pending, inProgress o completed.
  • hook/started y hook/completed: { threadId, turnId?, run } cuando comienza un hook de ciclo de vida síncrono y cuando está disponible el resumen de su ejecución final. Estas notificaciones no se emiten para hooks asíncronos.
  • model/safetyBuffering/updated: { threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel } cuando una respuesta entra en un búfer de seguridad transitorio.
  • model/rerouted: { threadId, turnId, fromModel, toModel, reason } cuando el servicio dirige 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 incluyen actualmente matrices items vacías incluso cuando se transmiten eventos de elementos. Usa las notificaciones item/* como fuente de verdad para los elementos del turno.

Elementos

ThreadItem es la unión etiquetada incluida en las respuestas de los turnos y en las notificaciones item/*. Entre los tipos de elementos habituales se incluyen:

  • userMessage: {id, content} donde content es una lista de entradas del usuario (text, image o localImage).
  • functionCallOutput: {id, name, namespace, output} para la salida independiente de una herramienta proporcionada mediante turn/start.toolOutput. namespace puede ser null.
  • agentMessage: {id, text, phase?} que contiene la respuesta acumulada del agente. Cuando está presente, phase usa los valores de conexión de Responses API (commentary, final_answer).
  • plan: {id, text} que contiene el texto del plan propuesto en el modo de planificación. Considera autoritativo el elemento plan final de item/completed.
  • reasoning: {id, summary, content} donde summary contiene resúmenes de razonamiento transmitidos y content contiene bloques de razonamiento sin procesar.
  • commandExecution: {id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.
  • fileChange: {id, changes, status} que describe las modificaciones propuestas; changes enumera {path, kind, diff}.
  • mcpToolCall: {id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Para apps MCP de confianza, appContext puede incluir connectorId, linkId, resourceUri, appName, templateId y el actionName estable del conector. Los elementos persistentes más antiguos pueden omitir los metadatos más recientes. Usa appContext.resourceUri en lugar del mcpAppResourceUri de nivel superior obsoleto.
  • dynamicToolCall: {id, tool, arguments, status, contentItems?, success?, durationMs?} para invocaciones dinámicas de herramientas ejecutadas por el cliente.
  • collabToolCall: {id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.
  • webSearch: {id, query, action?} para solicitudes de búsqueda web emitidas por el agente.
  • imageView: {id, path} emitido cuando el agente invoca la herramienta de visualización de imágenes.
  • enteredReviewMode: {id, review} enviado cuando se inicia el revisor.
  • exitedReviewMode: {id, review} emitido cuando finaliza el revisor.
  • contextCompaction: {id} emitido cuando Codex compacta el historial de conversación.

Para webSearch.action, la acción type puede ser search (query?, queries?), openPage (url?) o findInPage (url?, pattern?).

El app server declara obsoleta la notificación heredada thread/compacted; usa en su lugar el elemento contextCompaction.

Todos los elementos emiten dos eventos de ciclo de vida compartidos:

  • item/started: emite el item completo cuando comienza una nueva unidad de trabajo; el item.id coincide con el itemId utilizado por los deltas.
  • item/completed: envía el item final cuando termina el trabajo; considéralo el estado autoritativo.

Deltas de elementos

  • item/agentMessage/delta: añade el texto transmitido del mensaje del agente.
  • item/plan/delta: transmite el texto del plan propuesto. Es posible que el elemento plan final no coincida exactamente con los deltas concatenados.
  • item/reasoning/summaryTextDelta: transmite resúmenes legibles del razonamiento; summaryIndex aumenta cuando se abre una nueva sección del resumen.
  • item/reasoning/summaryPartAdded: marca un límite entre las 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/stderr de un comando; añade los deltas en orden.
  • item/fileChange/outputDelta: notificación de compatibilidad obsoleta para la salida de texto heredada apply_patch. Las versiones actuales de app-server ya no la emiten; usa los elementos fileChange y turn/diff/updated en su lugar.

Errores

Si un turno falla, el servidor emite un evento error con { error: { message, codexErrorInfo?, additionalDetails? } } y después finaliza el turno con status: "failed". Cuando hay disponible un estado HTTP del servicio ascendente, aparece en codexErrorInfo.httpStatusCode.

Entre los valores habituales de codexErrorInfo se incluyen:

  • ContextWindowExceeded
  • UsageLimitExceeded
  • HttpConnectionFailed (errores ascendentes 4xx/5xx)
  • ResponseStreamConnectionFailed
  • ResponseStreamDisconnected
  • ResponseTooManyFailedAttempts
  • BadRequest, Unauthorized, SandboxError, InternalServerError, Other

Cuando hay disponible un estado HTTP del servicio ascendente, el servidor lo reenvía en httpStatusCode dentro de la variante codexErrorInfo pertinente.

Aprobaciones

Según los ajustes de Codex del usuario, la ejecución de comandos y los cambios de archivos pueden requerir aprobación. App-server envía al cliente una solicitud JSON-RPC iniciada por el servidor, y el cliente responde con una carga útil de decisión.

  • Decisiones de ejecución de comandos: accept, acceptForSession, decline, cancel o { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.

  • Decisiones de cambios de archivos: accept, acceptForSession, decline, cancel.

  • Las solicitudes incluyen threadId y turnId; úsalos para limitar el estado de la interfaz de usuario a la conversación activa.

  • El servidor reanuda o rechaza el trabajo y finaliza el elemento con item/completed.

Aprobaciones de ejecución de comandos

Orden de los mensajes:

  1. item/started muestra el elemento commandExecution pendiente con command, cwd y otros campos.
  2. item/commandExecution/requestApproval incluye itemId, threadId, turnId, reason opcional, command opcional, cwd opcional, commandActions opcional, proposedExecpolicyAmendment opcional, networkApprovalContext opcional y availableDecisions opcional. Cuando se usa initialize.params.capabilities.experimentalApi = true, la carga útil también puede incluir el additionalPermissions experimental, que describe el acceso al entorno aislado solicitado por comando. Todas las rutas del sistema de archivos incluidas en additionalPermissions son absolutas durante la transmisión.
  3. El cliente responde con una de las decisiones de aprobación de ejecución de comandos anteriores.
  4. serverRequest/resolved confirma que se ha respondido o eliminado la solicitud pendiente.
  5. item/completed devuelve el elemento commandExecution final con status: completed | failed | declined.

Cuando networkApprovalContext está presente, la solicitud pide acceso administrado a la red (no una aprobación general de un comando de shell). El esquema v2 actual expone el host y el protocol de destino; los clientes deben mostrar una solicitud específica de red y no depender de que command sea una vista previa del comando de shell comprensible para el usuario.

Codex agrupa las solicitudes simultáneas de aprobación de red por destino (host, protocolo y puerto). Por tanto, app-server puede enviar una sola solicitud que desbloquee varias solicitudes en cola para el mismo destino, mientras que los distintos puertos del mismo host se tratan por separado.

Aprobaciones de cambios de archivos

Orden de los mensajes:

  1. item/started emite un elemento fileChange con los changes y status: "inProgress" propuestos.
  2. item/fileChange/requestApproval incluye itemId, threadId, turnId, reason opcional y grantRoot opcional.
  3. El cliente responde con una de las decisiones de aprobación de cambios de archivos anteriores.
  4. serverRequest/resolved confirma que se ha respondido o eliminado la solicitud pendiente.
  5. item/completed devuelve el elemento fileChange final con status: completed | failed | declined.

tool/requestUserInput

Cuando el cliente responde a item/tool/requestUserInput, app-server emite serverRequest/resolved con { threadId, requestId }. Si la solicitud pendiente se elimina al iniciar, completar o interrumpir el turno antes de que responda el cliente, el servidor emite la misma notificación para esa limpieza.

Los parámetros de la solicitud incluyen autoResolutionMs como un tiempo de espera entero en milisegundos o null. Cuando está presente, los clientes host pueden resolver automáticamente la solicitud después de ese intervalo si el usuario no responde.

Solicitudes de permisos

La herramienta integrada request_permissions envía item/permissions/requestApproval con threadId, turnId, itemId, environmentId, cwd, reason opcional y los permisos de red o del sistema de archivos solicitados. Responde con permissions, que debe contener solo el subconjunto concedido. Establece scope en "session" para conservar la concesión en turnos posteriores de la misma sesión; omítelo o usa "turn" para concederla únicamente durante el turno. Los permisos que no se hayan solicitado se ignoran.

Solicitudes de obtención de información del servidor 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 de solicitud:

  • mode: "form" o mode: "openai/form", con message y requestedSchema.
  • mode: "url", con message, url y elicitationId.

Responde con action: "accept" y el content solicitado, o con action: "decline" o "cancel" y content: null. A continuación, app-server emite serverRequest/resolved. Para recibir la variante openai/form, habilítala con initialize.params.capabilities.mcpServerOpenaiFormElicitation.

Llamadas a herramientas dinámicas (experimental)

dynamicTools en thread/start y el flujo correspondiente de solicitud o respuesta item/tool/call son API experimentales.

Los nombres de las herramientas dinámicas y de los espacios de nombres deben cumplir las restricciones de nomenclatura de Responses API. Evita los nombres de espacios de nombres reservados que utilizan las herramientas integradas de Codex.

Cuando se invoca una herramienta dinámica durante un turno, app-server emite:

  1. item/started con item.type = "dynamicToolCall", status = "inProgress", además de tool y arguments.
  2. item/tool/call como solicitud del servidor al cliente.
  3. La carga útil de respuesta del cliente con los elementos de contenido devueltos.
  4. item/completed con item.type = "dynamicToolCall", el status final y cualquier valor contentItems o success devuelto.

Aprobaciones de llamadas a herramientas MCP (aplicaciones)

Las llamadas a herramientas de aplicaciones (conectores) también pueden requerir aprobación. Cuando una llamada a una herramienta de una aplicación tiene efectos secundarios, el servidor puede solicitar aprobación mediante tool/requestUserInput y opciones como Aceptar, Rechazar y Cancelar. Las anotaciones de herramientas destructivas siempre activan la aprobación, aunque la herramienta también anuncie indicaciones con menos privilegios. Si el usuario rechaza o cancela la solicitud, el elemento mcpToolCall relacionado finaliza con un error en lugar de ejecutar la herramienta.

Skills

Invoca una skill incluyendo $<skill-name> en la entrada de texto del usuario. Añade un elemento de entrada skill (recomendado) para que el servidor inserte las instrucciones completas de la skill en lugar de depender de que el modelo resuelva el nombre.

{
  "method": "turn/start",
  "id": 101,
  "params": {
    "threadId": "thread-1",
    "input": [
      {
        "type": "text",
        "text": "$skill-creator Add a new skill for triaging flaky CI."
      },
      {
        "type": "skill",
        "name": "skill-creator",
        "path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
      }
    ]
  }
}

Si omites el elemento skill, el modelo seguirá analizando el marcador $<skill-name> e intentará localizar la skill, lo que puede aumentar la latencia.

Ejemplo:

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

Usa skills/list para obtener las skills disponibles (opcionalmente limitadas mediante cwds, con forceReload). También puedes incluir perCwdExtraUserRoots para examinar rutas absolutas adicionales como ámbito user de valores cwd específicos. App-server ignora las entradas cuyo cwd no esté presente en cwds. skills/list puede reutilizar un resultado almacenado en caché por cwd; establece forceReload: true para actualizarlo desde el disco. Cuando está presente, el servidor lee interface y dependencies desde 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 de skills locales supervisados. Trátalas como una señal de invalidación y vuelve a ejecutar skills/list con tus parámetros actuales cuando sea necesario.

Para activar o desactivar una skill por ruta:

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

Aplicaciones (conectores)

Usa app/installed para leer la última instantánea confirmada del entorno de ejecución de las aplicaciones instaladas. Cada resultado incluye el id de la aplicación, runtimeName (o null), el estado enabled efectivo y el estado callable. Solo se puede llamar a una aplicación cuando la configuración efectiva la habilita y al menos una herramienta visible para el modelo cumple las políticas de la aplicación y de la herramienta.

{
  "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 configuración de un hilo cargado. Establece forceRefresh: true para actualizar la instantánea del entorno de ejecución del conector antes de leerla. Cuando una política global o del espacio de trabajo bloquea el acceso a una aplicación, una aplicación detectada puede seguir apareciendo con enabled y callable establecidos en false.

Usa app/list para obtener las aplicaciones disponibles. En CLI/TUI, /apps es el selector para el usuario; en clientes personalizados, llama directamente a app/list. Cada entrada incluye tanto isAccessible (disponible para el usuario) como isEnabled (habilitada en config.toml), de modo que los clientes puedan distinguir la instalación o el acceso del estado habilitado local. Las entradas de aplicaciones 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 disponibilidad de funciones de la aplicación (features.apps) usa la instantánea de configuración de ese hilo. Si se omite, app-server usa la configuración global más reciente.

app/list devuelve una respuesta después de cargar tanto las aplicaciones accesibles como las del directorio. Establece forceRefetch: true para omitir las cachés de aplicaciones y obtener datos actualizados. Las entradas de caché solo se sustituyen cuando las actualizaciones se completan correctamente.

El servidor también emite notificaciones app/list/updated cada vez que termina de cargarse cualquiera de las fuentes (aplicaciones accesibles o aplicaciones del directorio). Cada notificación incluye la lista combinada más reciente de aplicaciones.

{
  "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 aplicaciones y necesites sus metadatos en lugar del estado del entorno de ejecución instalado. Pasa como máximo 100 appIds. El servidor conserva solo la primera aparición de cada id. repetido y mantiene ese orden tanto en apps como en missingAppIds. Las aplicaciones desconocidas o inaccesibles se devuelven en missingAppIds sin provocar el fallo de 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 únicamente para visualización. La respuesta de metadatos no incluye el estado del entorno de ejecución de las aplicaciones instaladas ni autoriza una llamada a una herramienta; usa app/installed para comprobar los estados efectivos enabled y callable.

Invoca una aplicación insertando $<app-slug> en la entrada de texto y añadiendo 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 Pull the latest updates from the team."
      },
      {
        "type": "mention",
        "name": "Demo App",
        "path": "app://demo-app"
      }
    ]
  }
}

Ejemplos de RPC de configuración para los ajustes de aplicaciones

Usa config/read, config/value/write y config/batchWrite para inspeccionar o actualizar los controles de las aplicaciones en config.toml.

Lee la estructura de configuración efectiva de las aplicaciones (incluidos _default y las sustituciones por 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 de todas las aplicaciones salvo que un valor por aplicación lo sustituya. Si se omiten ambos, la aplicación hereda el valor approvals_reviewer de nivel superior. apps._default.default_tools_approval_mode establece el modo de aprobación alternativo para las herramientas que no tengan una sustitución por aplicación o por herramienta. Los requisitos administrados del modo de aprobación sustituyen los ajustes del modo de aprobación de las herramientas.

Actualiza un único ajuste de aplicación:

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

Aplica varias ediciones de aplicaciones 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 artefactos de agentes externos que puedan migrarse y después 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 de migración seleccionados.

El servidor emite externalAgentConfig/import/progress a medida que se completan los tipos de elementos y externalAgentConfig/import/completed después de que finalicen todas las importaciones síncronas y en segundo plano. Estas notificaciones incluyen el mismo importId de la respuesta y itemTypeResults con successes y failures por tipo. La finalización puede producirse inmediatamente después de la respuesta o después de que 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": []
    }
  ]
} }

Lee las importaciones anteriores completadas:

{ "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 el pluginNames que Codex puede intentar migrar. La detección devuelve únicamente 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, y las importaciones de skills no sobrescriben los directorios de skills existentes.

Al detectar plugins desde .claude/settings.json, Codex lee las fuentes de marketplaces configuradas en extraKnownMarketplaces. Si enabledPlugins contiene plugins de claude-plugins-official, pero falta la fuente del marketplace, Codex deduce anthropics/claude-plugins-official como fuente.

Endpoints de autenticación

La superficie JSON-RPC de autenticación/cuenta expone métodos de solicitud/respuesta y notificaciones iniciadas por el servidor (sin id). Úsalos para determinar el estado de autenticación, iniciar o cancelar inicios de sesión, cerrar sesión, inspeccionar los límites de frecuencia de ChatGPT y notificar a los propietarios del espacio de trabajo sobre créditos agotados o límites de uso.

Modos de autenticación

Codex admite estos 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 de los detalles de la cuenta y del plan.

  • API key (apikey): el autor de la llamada proporciona una API key de OpenAI mediante type: "apiKey" y Codex la almacena para las solicitudes a la API.
  • ChatGPT administrado (chatgpt): Codex gestiona el flujo OAuth de ChatGPT, conserva los tokens y los actualiza automáticamente. Comienza con type: "chatgpt" para el flujo del navegador o con type: "chatgptDeviceCode" para el flujo de código de dispositivo.
  • Tokens externos de ChatGPT (chatgptAuthTokens): función experimental destinada a aplicaciones host que ya gestionan el ciclo de vida de autenticación de ChatGPT del usuario. La aplicación host proporciona directamente un accessToken, un chatgptAccountId y un chatgptPlanType opcional, y debe actualizar el token cuando se le solicite.
  • Amazon Bedrock: account/read informa de las cuentas de Bedrock como type: "amazonBedrock" e indica si las credenciales proceden de una API key de Bedrock administrada por Codex (credentialSource: "codexManaged") o de la cadena externa de credenciales de AWS (credentialSource: "awsManaged"). account/updated.authMode usa bedrockApiKey para las API keys de Bedrock administradas por Codex.

Descripción general de la API

  • account/read: obtiene la información actual de la cuenta; opcionalmente, actualiza los tokens.
  • account/login/start: inicia la sesión (apiKey, chatgpt, chatgptDeviceCode o el chatgptAuthTokens experimental).
  • account/login/completed (notificación): se emite cuando finaliza un intento de inicio de sesión (con éxito o error).
  • account/login/cancel: cancela un inicio de sesión administrado de ChatGPT pendiente mediante loginId.
  • account/logout: cierra la sesión; activa account/updated.
  • account/updated (notificación): se emite cada vez que cambia el modo de autenticación (authMode: apikey, chatgpt, chatgptAuthTokens, agentIdentity, personalAccessToken, bedrockApiKey o null) e incluye planType cuando 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 frecuencia de ChatGPT.
  • account/rateLimits/updated (notificación): se emite cada vez que cambian los límites de frecuencia de ChatGPT de un usuario.
  • account/sendAddCreditsNudgeEmail: solicita a ChatGPT que envíe un correo electrónico al propietario de un espacio de trabajo para avisarle de créditos agotados o de que se ha alcanzado un límite de uso.
  • account/rateLimitResetCredit/consume: consume un restablecimiento de límite de frecuencia obtenido mediante un valor idempotencyKey proporcionado por el autor de la llamada.
  • account/usage/read: obtiene resúmenes de actividad de tokens de la cuenta de ChatGPT y agrupaciones diarias.
  • account/workspaceMessages/read: obtiene los mensajes activos del espacio de trabajo, incluidos los titulares de notificaciones cuando están disponibles.
  • mcpServer/oauthLogin/completed (notificación): se emite después de que finaliza un flujo mcpServer/oauth/login; la carga útil incluye { name, threadId, success, error? }. threadId puede ser null para flujos OAuth limitados a una aplicación o un plugin.
  • mcpServer/startupStatus/updated (notificación): se emite cuando cambia el estado de inicio de un servidor MCP configurado; la carga útil incluye { threadId, name, status, error, failureReason }. threadId es null para un inicio limitado a una aplicación. Si el inicio falla, failureReason: "reauthenticationRequired" significa que las credenciales OAuth almacenadas han caducado y no se han podido actualizar, por lo que el cliente debe ofrecer la posibilidad 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): establece true para forzar la actualización de un token en el modo administrado de ChatGPT. En el modo de tokens externos (chatgptAuthTokens), app-server ignora esta marca.
  • email es null cuando la cuenta de ChatGPT no tiene una dirección de correo electrónico.
  • requiresOpenaiAuth refleja el proveedor activo; cuando es false, Codex puede ejecutarse sin credenciales de OpenAI.
  • Amazon Bedrock informa de credentialSource: "codexManaged" cuando utiliza una API key de Bedrock administrada por Codex. Informa de credentialSource: "awsManaged" para la ruta de credenciales externas de AWS. Esto identifica la fuente de credenciales seleccionada, pero no valida que la cadena de credenciales de AWS pueda resolver las credenciales.

2) Iniciar sesión con una API key

  1. Envía:
   {
     "method": "account/login/start",
     "id": 2,
     "params": { "type": "apiKey", "apiKey": "sk-..." }
   }
  1. Espera:
   { "id": 2, "result": { "type": "apiKey" } }
  1. 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 del navegador)

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

De forma predeterminada, una devolución de llamada correcta del navegador redirige a una página local de confirmación. Establece useHostedLoginSuccessPage: true para usar la página de confirmación alojada cuando no sea necesario configurar la organización. Con la confirmación alojada habilitada, appBrand puede ser "codex" o "chatgpt"; los valores omitidos o null usan de forma predeterminada "codex".

   {
     "id": 3,
     "result": {
       "type": "chatgpt",
       "loginId": "<uuid>",
       "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
     }
   }
  1. Abre authUrl en un navegador; app-server aloja la devolución de llamada local.
  2. 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 de código de dispositivo)

Usa este flujo cuando tu cliente gestione el proceso de inicio de sesión o cuando una devolución de llamada del navegador sea poco fiable.

  1. Inicia:
   {
     "method": "account/login/start",
     "id": 4,
     "params": { "type": "chatgptDeviceCode" }
   }
   {
     "id": 4,
     "result": {
       "type": "chatgptDeviceCode",
       "loginId": "<uuid>",
       "verificationUrl": "https://auth.openai.com/codex/device",
       "userCode": "ABCD-1234"
     }
   }
  1. Muestra verificationUrl y userCode al usuario; el frontend gestiona la UX.
  2. 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 únicamente cuando una aplicación host gestione el ciclo de vida de autenticación de ChatGPT del usuario y proporcione los tokens directamente. Los clientes deben establecer capabilities.experimentalApi = true durante initialize antes de utilizar este tipo de inicio de sesión.

  1. Envía:
   {
     "method": "account/login/start",
     "id": 7,
     "params": {
       "type": "chatgptAuthTokens",
       "accessToken": "<jwt>",
       "chatgptAccountId": "org-123",
       "chatgptPlanType": "business"
     }
   }
  1. Espera:
   { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  1. Notificaciones:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
   }

Cuando el servidor recibe un 401 Unauthorized, puede solicitar tokens actualizados a la aplicación 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 actualización correcta. Las solicitudes agotan el tiempo de espera 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 frecuencia (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:

  • rateLimits es la vista de una sola agrupación compatible con versiones anteriores.
  • rateLimitsByLimitId (cuando está presente) es la vista de varias agrupaciones indexada por el limit_id medido (por ejemplo, codex).
  • limitId es el identificador de la agrupación medida.
  • limitName es una etiqueta opcional de la agrupación para el usuario.
  • usedPercent es el uso actual dentro del intervalo de cuota.
  • windowDurationMins es la duración del intervalo de cuota.
  • resetsAt es una marca de tiempo Unix (segundos) para el próximo restablecimiento.
  • planType se incluye cuando el servidor devuelve el plan de ChatGPT asociado a una agrupación.
  • credits se incluye cuando el servidor devuelve detalles sobre el crédito restante del espacio de trabajo.
  • rateLimitReachedType identifica el estado del límite clasificado por el servidor cuando se ha alcanzado alguno.
  • rateLimitResetCredits contiene el número de restablecimientos obtenidos disponibles cuando el servicio lo proporciona; de lo contrario, es null.
  • rateLimitResetCredits.credits es null cuando solo se conoce la cantidad. Una matriz vacía significa que el servicio obtuvo los detalles y no devolvió créditos disponibles. El servicio puede limitar las filas de detalles, por lo que availableCount es autoritativo.
  • Cada fila de detalles incluye un id opaco, resetType, status, grantedAt, expiresAt (que puede ser null), title (que puede ser null) y description (que puede ser null).
  • Obtén account/rateLimits/read después de consumir un restablecimiento.

7) Uso de tokens (ChatGPT)

Usa account/usage/read para obtener los campos de resumen de la actividad de tokens de ChatGPT y las agrupaciones diarias opcionales.

{ "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 summary pueden ser null cuando el servicio no haya devuelto esa métrica.
  • dailyUsageBuckets puede ser null; cuando está presente, cada agrupación incluye startDate y tokens.
  • El endpoint requiere una autenticación respaldada por los servicios de Codex. Funcionan ChatGPT, los tokens externos de ChatGPT, la identidad del agente y la autenticación mediante token de acceso personal; no funcionan la autenticación solo mediante API key ni la autenticación de Bedrock.

8) Restablecimientos obtenidos de los límites de frecuencia (ChatGPT)

Usa account/rateLimitResetCredit/consume para consumir un restablecimiento obtenido.

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

  • idempotencyKey no debe estar vacío. Usa un UUID para cada intento lógico de canje y reutiliza el mismo valor al volver a intentar ese canje.
  • creditId es opcional. Si se proporciona, debe ser un id. opaco no vacío de account/rateLimits/read. Si se omite, el servicio selecciona el siguiente crédito disponible.
  • reset significa que se consumió un crédito.
  • alreadyRedeemed significa que el mismo canje ya se había completado. Trátalo como una operación idempotente correcta y actualiza los límites de la cuenta.
  • nothingToReset significa que no hay ningún intervalo de límite de frecuencia elegible para restablecer.
  • noCredit significa que la cuenta no dispone de créditos de restablecimiento obtenidos.
  • Obtén account/rateLimits/read después de consumir un restablecimiento en lugar de deducir los intervalos actualizados a partir de esta respuesta.

9) Notificar a un propietario del espacio de trabajo sobre un límite

Usa account/sendAddCreditsNudgeEmail para solicitar a ChatGPT que envíe un correo electrónico al propietario de un 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 el límite de uso del espacio de trabajo. Si ya se ha notificado recientemente al propietario, 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 titulares de 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 }
] } }