Français

Serveur d’application Codex

Pour consulter l’index complet de la documentation, reportez-vous à llms.txt. Les versions Markdown des pages de documentation sont disponibles en ajoutant .md à l’URL de la page.

Codex app-server est l’interface utilisée par Codex pour alimenter des clients riches (par exemple, l’extension Codex pour VS Code). Utilisez-la lorsque vous souhaitez intégrer Codex en profondeur dans votre propre produit : authentification, historique des conversations, approbations et événements diffusés en continu par l’agent. L’implémentation d’app-server est open source dans le dépôt GitHub de Codex (openai/codex/codex-rs/app-server). Consultez la page Open Source pour obtenir la liste complète des composants Codex open source.

Connecter l’interface de terminal du CLI

Le mode d’interface de terminal à distance vous permet d’exécuter app-server sur une machine et de connecter l’interface de terminal du CLI Codex depuis une autre. Démarrez un écouteur WebSocket :

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

Connectez ensuite l’interface de terminal :

codex --remote ws://127.0.0.1:4500

Pour une connexion non locale, configurez l’authentification WebSocket et placez la connexion derrière TLS. Stockez le jeton bearer dans une variable d’environnement et transmettez le nom de celle-ci au lieu d’inscrire le jeton sur la ligne de commande :

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

L’option --remote accepte les points de terminaison ws://, wss://, unix:// et unix://PATH. Utilisez des WebSockets non sécurisés uniquement pour localhost ou une connexion transférée par port SSH.

Connecter un hôte Code Mode distant

Par défaut, app-server démarre un hôte Code Mode local. Pour utiliser plutôt un hôte distant, transmettez son URL WebSocket sécurisée :

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

--code-mode-host contrôle la connexion sortante d’app-server vers son hôte Code Mode. Cette option ne modifie pas --listen, qui contrôle la manière dont les clients se connectent à app-server. Tous les threads d’un même processus app-server partagent la connexion à l’hôte Code Mode sélectionné.

Utilisez wss:// pour un hôte distant. N’utilisez ws:// que pour localhost ou une connexion transférée par SSH. La commande app-server et le transport WebSocket sont expérimentaux et ne sont pas pris en charge pour les charges de travail de production.

Protocole

À l’instar de MCP, codex app-server prend en charge la communication bidirectionnelle au moyen de messages JSON-RPC 2.0 (l’en-tête "jsonrpc":"2.0" étant omis lors de la transmission).

Transports pris en charge :

  • stdio (--listen stdio://, par défaut) : JSON délimité par des sauts de ligne (JSONL).
  • websocket (--listen ws://IP:PORT, expérimental et non pris en charge) : un message JSON-RPC par trame de texte WebSocket.
  • Socket Unix (--listen unix:// ou --listen unix://PATH) : connexions WebSocket via le socket de contrôle app-server par défaut de Codex ou un chemin de socket Unix personnalisé, à l’aide de la négociation HTTP Upgrade standard.
  • off (--listen off) : n’expose aucun transport local.

Lorsque vous utilisez --listen ws://IP:PORT, le même écouteur fournit également des sondes d’intégrité HTTP de base :

  • GET /readyz renvoie 200 OK dès que l’écouteur accepte de nouvelles connexions.
  • GET /healthz renvoie 200 OK lorsque la requête ne contient pas d’en-tête Origin.
  • Les requêtes comportant un en-tête Origin sont rejetées avec 403 Forbidden.

Le transport WebSocket est expérimental et non pris en charge. Les écouteurs locaux tels que ws://127.0.0.1:PORT conviennent aux workflows localhost et de transfert de port SSH. Pendant le déploiement progressif, les écouteurs WebSocket qui ne sont pas limités à l’interface de bouclage autorisent actuellement les connexions non authentifiées par défaut ; configurez donc l’authentification WebSocket avant d’en exposer un à distance.

Options d’authentification WebSocket prises en charge :

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

Pour les jetons bearer signés, vous pouvez également définir --ws-issuer, --ws-audience et --ws-max-clock-skew-seconds. Les clients présentent l’identifiant sous la forme Authorization: Bearer <token> pendant la négociation WebSocket, et app-server impose l’authentification avant le trafic JSON-RPC initialize.

Préférez --ws-token-file à la transmission de jetons bearer bruts sur la ligne de commande. N’utilisez --ws-token-sha256 que lorsque le client conserve le jeton brut à entropie élevée dans un magasin de secrets local distinct ; le hachage n’est qu’un vérificateur et les clients ont toujours besoin du jeton d’origine.

En mode WebSocket, app-server utilise des files d’attente de taille limitée. Lorsque la file d’entrée des requêtes est pleine, le serveur rejette les nouvelles requêtes avec le code d’erreur JSON-RPC -32001 et le message "Server overloaded; retry later." Les clients doivent réessayer avec un délai exponentiellement croissant et une gigue aléatoire.

Schéma des messages

Les requêtes comprennent method, params et id :

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

Les réponses reprennent le même id avec soit result, soit error :

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

Les notifications omettent id et utilisent uniquement method et params :

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

Vous pouvez générer un schéma TypeScript ou un ensemble JSON Schema depuis le CLI. Chaque sortie est propre à la version de Codex que vous avez exécutée, de sorte que les artefacts générés correspondent exactement à cette version :

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

Bien démarrer

  1. Démarrez le serveur avec codex app-server (transport stdio par défaut), codex app-server --listen ws://127.0.0.1:4500 (WebSocket TCP) ou codex app-server --listen unix:// (socket Unix par défaut).
  2. Connectez un client au moyen du transport sélectionné, puis envoyez initialize, suivi de la notification initialized.
  3. Démarrez un thread et un tour, puis continuez à lire les notifications dans le flux de transport actif.

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

Concepts fondamentaux

  • Thread : conversation entre un utilisateur et l’agent Codex. Les threads contiennent des tours.
  • Tour : requête unique d’un utilisateur et travail effectué ensuite par l’agent. Les tours contiennent des éléments et diffusent des mises à jour incrémentielles.
  • Élément : unité d’entrée ou de sortie (message utilisateur, message de l’agent, exécution de commande, modification de fichier, appel d’outil, etc.).

Utilisez les API de threads pour créer, répertorier ou archiver des conversations. Pilotez une conversation avec les API de tours et diffusez sa progression au moyen des notifications de tours.

Vue d’ensemble du cycle de vie

  • Initialiser une fois par connexion : immédiatement après l’ouverture d’une connexion de transport, envoyez une requête initialize avec les métadonnées de votre client, puis émettez initialized. Le serveur rejette toute requête envoyée sur cette connexion avant cette négociation.
  • Démarrer (ou reprendre) un thread : appelez thread/start pour une nouvelle conversation, thread/resume pour poursuivre une conversation existante ou thread/fork pour créer une branche de l’historique avec un nouvel identifiant de thread.
  • Commencer un tour : appelez turn/start avec le threadId cible et l’entrée utilisateur. Les champs facultatifs remplacent le modèle, la personnalité, cwd, la politique de bac à sable, etc.
  • Orienter un tour actif : appelez turn/steer pour ajouter une entrée utilisateur au tour actuellement en cours sans créer de nouveau tour.
  • Diffuser les événements : après turn/start, continuez à lire les notifications sur stdout : thread/archived, thread/unarchived, item/started, item/completed, item/agentMessage/delta, progression des outils et autres mises à jour.
  • Terminer le tour : le serveur émet turn/completed avec le statut final lorsque le modèle a terminé ou après une annulation turn/interrupt.

Initialisation

Les clients doivent envoyer une seule requête initialize par connexion de transport avant d’appeler toute autre méthode sur cette connexion, puis en accuser réception avec une notification initialized. Les requêtes envoyées avant l’initialisation reçoivent une erreur Not initialized, et les appels répétés à initialize sur la même connexion renvoient Already initialized.

Le serveur renvoie la chaîne user-agent qu’il présentera aux services en amont, ainsi que les valeurs platformFamily et platformOs décrivant la cible d’exécution. Définissez clientInfo pour identifier votre intégration.

initialize.params.capabilities prend également en charge les fonctionnalités client suivantes :

  • optOutNotificationMethods - noms exacts des méthodes de notification à supprimer pour cette connexion. La correspondance est exacte (sans caractères génériques ni préfixes) ; les noms inconnus sont acceptés et ignorés.
  • requestAttestation - activez la requête attestation/generate initiée par le serveur. Les hôtes de bureau qui fournissent une attestation en amont répondent avec une valeur { "token": "..." } opaque.
  • mcpServerOpenaiFormElicitation - autorise les serveurs MCP en aval à envoyer la variante étendue OpenAI de mcpServer/elicitation/request.

Important : utilisez clientInfo.name pour identifier votre client auprès de l’OpenAI Compliance Logs Platform. Si vous développez une nouvelle intégration Codex destinée à un usage en entreprise, veuillez contacter OpenAI afin de l’ajouter à la liste des clients connus. Pour plus de contexte, consultez la référence des journaux Codex.

Exemple (tiré de l’extension Codex pour VS Code) :

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

Exemple avec désactivation de certaines notifications :

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

Activation de l’API expérimentale

Certaines méthodes et certains champs d’app-server sont volontairement protégés par la fonctionnalité experimentalApi.

  • Omettez capabilities (ou définissez experimentalApi sur false) pour rester sur la surface d’API stable ; le serveur rejettera alors les méthodes et champs expérimentaux.
  • Définissez capabilities.experimentalApi sur true pour activer les méthodes et champs expérimentaux.
{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true
    }
  }
}

Si un client envoie une méthode ou un champ expérimental sans l’avoir activé, app-server le rejette avec :

<descriptor> requires experimentalApi capability

Vue d’ensemble de l’API

  • thread/start - crée un nouveau thread ; émet thread/started et vous abonne automatiquement aux événements de tours et d’éléments de ce thread.
  • thread/resume - rouvre un thread existant à partir de son identifiant afin que les appels turn/start ultérieurs y ajoutent du contenu.
  • thread/fork - crée une branche d’un thread avec un nouvel identifiant en copiant l’historique stocké. Transmettez lastTurnId pour copier l’historique jusqu’à ce tour et omettre les tours suivants, ou ephemeral: true pour créer une branche en mémoire. Émet thread/started pour le nouveau thread ; les threads renvoyés incluent forkedFromId lorsqu’il est disponible.
  • thread/read - lit un thread stocké à partir de son identifiant sans le reprendre ; définissez includeTurns pour renvoyer l’historique complet des tours. Les objets thread renvoyés incluent le status d’exécution.
  • thread/list - parcourt les journaux de threads stockés par pages ; prend en charge la pagination par curseur ainsi que modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm et les filtres expérimentaux parentThreadId ou ancestorThreadId. Les objets thread renvoyés incluent le status d’exécution.
  • thread/turns/list - expérimental ; parcourt par pages l’historique des tours d’un thread stocké sans le reprendre. itemsView détermine si les éléments des tours sont omis, résumés ou chargés intégralement.
  • thread/items/list - expérimental ; parcourt par pages les éléments persistants d’un thread, éventuellement limités à un turnId. Le stockage de threads actif doit prendre en charge la pagination des éléments.
  • thread/loaded/list - répertorie les identifiants des threads actuellement chargés en mémoire.
  • thread/name/set - définit ou met à jour le nom visible par l’utilisateur d’un thread chargé ou d’un rollout persistant ; émet thread/name/updated.
  • thread/goal/set - définit l’objectif d’un thread ; émet thread/goal/updated.
  • thread/goal/get - lit l’objectif actuel d’un thread.
  • thread/goal/clear - efface l’objectif d’un thread ; émet thread/goal/cleared.
  • thread/metadata/update - modifie les métadonnées d’un thread stocké basé sur SQLite, notamment les valeurs persistantes gitInfo et isPinned.
  • thread/archive - déplace le fichier journal d’un thread vers le répertoire d’archives et tente d’archiver les journaux des threads descendants générés qui ne le sont pas déjà ; renvoie {} en cas de réussite et émet thread/archived pour chaque thread archivé.
  • thread/delete - supprime définitivement un thread persistant actif ou archivé ainsi que tous ses threads descendants générés ; renvoie {} en cas de réussite et émet thread/deleted pour chaque thread supprimé.
  • thread/unsubscribe - désabonne cette connexion des événements de tours et d’éléments du thread. S’il s’agissait du dernier abonné, le serveur décharge le thread après un délai d’inactivité sans abonné et émet thread/closed.
  • thread/unarchive - restaure un rollout de thread archivé dans le répertoire des sessions actives ; renvoie le thread restauré et émet thread/unarchived.
  • thread/status/changed - notification émise lorsque le status d’exécution d’un thread chargé change.
  • thread/compact/start - déclenche la compaction de l’historique des conversations d’un thread ; renvoie immédiatement {} tandis que la progression est diffusée au moyen des notifications turn/* et item/*.
  • thread/shellCommand - exécute une commande shell lancée par l’utilisateur sur un thread. Cette commande s’exécute en dehors du bac à sable avec un accès complet et n’hérite pas de la politique de bac à sable du thread.
  • thread/backgroundTerminals/clean - arrête tous les terminaux en arrière-plan en cours d’exécution pour un thread (expérimental ; nécessite capabilities.experimentalApi).
  • thread/backgroundTerminals/list - répertorie les terminaux en arrière-plan en cours d’exécution pour un thread chargé (expérimental ; nécessite capabilities.experimentalApi).
  • thread/backgroundTerminals/terminate - arrête un terminal en arrière-plan en cours d’exécution à partir de son processId app-server (expérimental ; nécessite capabilities.experimentalApi).
  • thread/rollback - obsolète ; retire les N derniers tours du contexte en mémoire et conserve un marqueur de restauration ; renvoie le thread mis à jour.
  • turn/start - ajoute l’entrée utilisateur à un thread et démarre la génération Codex ; répond avec le turn initial et diffuse les événements. Pour collaborationMode, settings.developer_instructions: null signifie « utiliser les instructions intégrées pour le mode sélectionné ».
  • thread/inject_items - ajoute des éléments Responses API bruts à l’historique visible par le modèle d’un thread chargé sans démarrer de tour utilisateur.
  • turn/steer - ajoute une entrée utilisateur au tour actif en cours d’un thread ; renvoie le turnId accepté.
  • turn/interrupt - demande l’annulation d’un tour en cours ; la réussite est indiquée par {} et le tour se termine avec status: "interrupted".
  • review/start - lance l’outil de révision Codex pour un thread ; émet des éléments enteredReviewMode et exitedReviewMode.
  • command/exec - exécute une commande unique dans le bac à sable du serveur sans démarrer de thread ni de tour.
  • command/exec/write - écrit des octets stdin dans une session command/exec en cours d’exécution ou ferme stdin.
  • command/exec/resize - redimensionne une session command/exec en cours d’exécution utilisant un PTY.
  • command/exec/terminate - arrête une session command/exec en cours d’exécution.
  • command/exec/outputDelta (notification) - émise pour les fragments stdout/stderr encodés en base64 provenant d’une session command/exec diffusée en continu.
  • process/spawn - démarre une session de processus explicite en dehors du bac à sable de Codex (expérimental ; nécessite capabilities.experimentalApi).
  • process/writeStdin - écrit des octets stdin dans une session process/spawn en cours d’exécution ou ferme stdin (expérimental).
  • process/resizePty - redimensionne une session de processus en cours d’exécution utilisant un PTY (expérimental).
  • process/kill - arrête une session de processus en cours d’exécution (expérimental).
  • process/outputDelta et process/exited (notification) - émises pour la sortie de processus diffusée en continu et l’état de fin du processus (expérimental).
  • model/list - répertorie les modèles disponibles (définissez includeHidden: true pour inclure les entrées avec hidden: true), avec les options d’effort, un upgrade facultatif et inputModalities.
  • modelProvider/capabilities/read - lit les limites des fonctionnalités du fournisseur pour les combinaisons modèle/fournisseur.
  • experimentalFeature/list - répertorie les indicateurs de fonctionnalité avec les métadonnées de leur étape du cycle de vie et une pagination par curseur.
  • experimentalFeature/enablement/set - modifie les paramètres d’exécution en mémoire pour les clés de fonctionnalité prises en charge, telles que apps et plugins.
  • environment/info - expérimental ; se connecte à un environnement d’exécution configuré et renvoie son shell ainsi que son répertoire de travail par défaut.
  • permissionProfile/list - répertorie les profils d’autorisation bêta et indique si les exigences en vigueur les autorisent, avec une pagination par curseur.
  • collaborationMode/list - répertorie les préréglages du mode de collaboration (expérimental, sans pagination).
  • skills/list - répertorie les skills pour une ou plusieurs valeurs cwd (prend en charge forceReload et le paramètre facultatif perCwdExtraUserRoots).
  • skills/extraRoots/set - remplace les racines supplémentaires au niveau du processus utilisées pour découvrir les skills autonomes, sans les conserver.
  • skills/changed (notification) - émise lorsque les fichiers de skills locaux surveillés changent.
  • hooks/list - répertorie les hooks de cycle de vie découverts pour une ou plusieurs valeurs cwd.
  • marketplace/add - ajoute une marketplace de plugins distante et la conserve dans la configuration des marketplaces de l’utilisateur.
  • marketplace/remove - supprime une marketplace configurée ainsi que la racine de marketplace installée lorsqu’elle existe.
  • marketplace/upgrade - actualise une marketplace Git configurée, ou toutes les marketplaces Git configurées si vous omettez le nom de la marketplace.
  • plugin/list - en cours de développement ; répertorie les marketplaces de plugins découvertes et l’état des plugins, notamment les métadonnées de politique d’installation et d’authentification, les erreurs de chargement des marketplaces, les identifiants des plugins mis en avant et les métadonnées des sources de plugins locales, Git, de registre de paquets ou distantes. Les résumés peuvent inclure un version distant, un localVersion local, des icônes structurées pour les thèmes clair et sombre ainsi que installPolicySource, qui peut être null, WORKSPACE_SETTING ou IMPLICIT_CANONICAL_APP pour les lignes distantes actuelles. N’appelez pas encore cette méthode depuis des clients de production.
  • plugin/read - en cours de développement ; lit un plugin à partir du chemin de sa marketplace ou du nom de sa marketplace distante et de son nom de plugin, y compris les skills inclus, les apps, les noms de serveurs MCP et le shareUrl d’un plugin distant lorsque le catalogue distant en fournit un. N’appelez pas encore cette méthode depuis des clients de production.
  • plugin/install - en cours de développement ; installe un plugin depuis le chemin d’une marketplace ou le nom d’une marketplace distante. N’appelez pas encore cette méthode depuis des clients de production.
  • plugin/uninstall - en cours de développement ; désinstalle un plugin installé. N’appelez pas encore cette méthode depuis des clients de production.
  • plugin/skill/read - lit à la demande le Markdown du skill d’un plugin distant à partir de la marketplace distante, de l’identifiant du plugin et du nom du skill.
  • app/installed - lit l’état d’exécution des apps installées, notamment l’état effectif d’activation et d’appel de chaque app.
  • app/list - répertorie les apps (connecteurs) disponibles avec pagination et métadonnées d’accessibilité et d’activation.
  • app/read - récupère les métadonnées et, éventuellement, des résumés d’outils destinés uniquement à l’affichage pour des identifiants d’app spécifiques.
  • skills/config/write - active ou désactive des skills selon leur chemin.
  • mcpServer/oauth/login - démarre une connexion OAuth pour un serveur MCP configuré ; renvoie une URL d’autorisation et émet mcpServer/oauthLogin/completed une fois l’opération terminée.
  • tool/requestUserInput - invite l’utilisateur à répondre à 1 à 3 questions courtes pour un appel d’outil (expérimental) ; les questions peuvent définir isOther pour une option de saisie libre.
  • mcpServer/elicitation/request (requête serveur) - demande au client une saisie structurée dans un formulaire ou la confirmation d’un flux d’URL demandé par un serveur MCP.
  • item/permissions/requestApproval (requête serveur) - demande au client d’accorder un sous-ensemble des autorisations réseau ou de système de fichiers requises par l’outil request_permissions intégré.
  • config/mcpServer/reload - recharge la configuration des serveurs MCP depuis le disque et met en file d’attente une actualisation pour les threads chargés.
  • mcpServerStatus/list - répertorie les serveurs MCP, outils, ressources et états d’authentification (pagination par curseur et limite). Utilisez detail: "full" pour obtenir toutes les données ou detail: "toolsAndAuthOnly" pour omettre les ressources.
  • mcpServer/resource/read - lit une ressource MCP unique par l’intermédiaire d’un serveur MCP initialisé.
  • mcpServer/tool/call - appelle un outil sur le serveur MCP configuré d’un thread.
  • mcpServer/startupStatus/updated (notification) - émise lorsque l’état de démarrage d’un serveur MCP configuré change pour un thread chargé.
  • windowsSandbox/setupStart - démarre la configuration du bac à sable Windows pour le mode elevated ou unelevated ; renvoie rapidement une réponse, puis émet ultérieurement windowsSandbox/setupCompleted.
  • feedback/upload - envoie un rapport de commentaires (classification, motif/journaux facultatifs et identifiant de conversation, ainsi que des pièces jointes extraLogFiles facultatives).
  • config/read - récupère la configuration effective sur le disque après résolution des différentes couches de configuration.
  • externalAgentConfig/detect - détecte les artefacts d’agents externes pouvant être migrés avec includeHome et le paramètre facultatif cwds ; chaque élément détecté comprend cwd (null pour le répertoire personnel).
  • externalAgentConfig/import - applique les éléments de migration d’agents externes sélectionnés en transmettant explicitement migrationItems avec cwd (null pour le répertoire personnel). Les types d’éléments pris en charge incluent la configuration, les skills, AGENTS.md, les plugins, la configuration des serveurs MCP, les sous-agents, les hooks, les commandes et les sessions ; les importations non vides émettent externalAgentConfig/import/progress et externalAgentConfig/import/completed au fil de l’avancement. Les importations de plugins et de sessions peuvent se terminer de manière asynchrone.
  • config/value/write - écrit une seule paire clé/valeur de configuration dans le fichier config.toml de l’utilisateur sur le disque.
  • config/batchWrite - applique de manière atomique les modifications de configuration au fichier config.toml de l’utilisateur sur le disque.
  • configRequirements/read - récupère les exigences provenant de requirements.toml et/ou de MDM, y compris la configuration gérée exacte, les listes d’autorisation, les éléments featureRequirements épinglés et les exigences de résidence ou de réseau (ou null si vous n’en avez configuré aucune).
  • fs/readFile, fs/writeFile, fs/createDirectory, fs/getMetadata, fs/readDirectory, fs/remove, fs/copy, fs/watch, fs/unwatch et fs/changed (notification) - opèrent sur des chemins de système de fichiers absolus au moyen de l’API de système de fichiers app-server v2.

Les résumés de plugins incluent une union source. Les plugins locaux renvoient { "type": "local", "path": ... }, les entrées de marketplace basées sur Git renvoient { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }, les entrées de registre de paquets renvoient { "type": "npm", "package": ..., "version": ..., "registry": ... } et les entrées de catalogue distant renvoient { "type": "remote" }. Pour les entrées disponibles uniquement dans le catalogue distant, PluginMarketplaceEntry.path peut être null ; transmettez remoteMarketplaceName au lieu de marketplacePath lorsque vous lisez ou installez ces plugins.

Modèles

Répertorier les modèles (model/list)

Appelez model/list pour découvrir les modèles disponibles et leurs fonctionnalités avant d’afficher les sélecteurs de modèle ou de personnalité.

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

Chaque entrée de modèle peut inclure :

  • supportedReasoningEfforts - options d’effort prises en charge par le modèle.
  • defaultReasoningEffort - effort par défaut suggéré pour les clients.
  • upgrade - identifiant facultatif du modèle de mise à niveau recommandé pour les invites de migration dans les clients.
  • upgradeInfo - métadonnées facultatives de mise à niveau pour les invites de migration dans les clients.
  • hidden - indique si le modèle est masqué dans la liste de sélection par défaut.
  • inputModalities - types d’entrée pris en charge par le modèle (par exemple text, image).
  • supportsPersonality - indique si le modèle prend en charge des instructions propres à une personnalité, telles que /personality.
  • isDefault - indique si le modèle est le choix par défaut recommandé.

Par défaut, model/list renvoie uniquement les modèles visibles dans le sélecteur. Définissez includeHidden: true si vous avez besoin de la liste complète et souhaitez effectuer le filtrage côté client à l’aide de hidden.

Lorsque inputModalities est absent (anciens catalogues de modèles), traitez-le comme ["text", "image"] pour assurer la rétrocompatibilité.

Répertorier les fonctionnalités expérimentales (experimentalFeature/list)

Utilisez ce point de terminaison pour découvrir les indicateurs de fonctionnalité accompagnés de leurs métadonnées et de l’étape de leur cycle de vie :

{ "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 peut être beta, underDevelopment, stable, deprecated ou removed. Pour les indicateurs non bêta, displayName, description et announcement peuvent être null.

Inspecter un environnement d’exécution (expérimental)

Utilisez environment/info pour inspecter un environnement distant configuré avant d’y commencer le travail. Cette méthode nécessite 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 peut être null. Lorsqu’il est présent, il s’agit d’un URI file: canonique qui utilise la syntaxe de chemin native de l’environnement. Les identifiants d’environnement inconnus ainsi que les échecs de connexion ou de protocole renvoient des erreurs de requête.

Threads

  • thread/read lit un thread stocké sans s’y abonner ; définissez includeTurns pour inclure les tours.
  • thread/turns/list est expérimental et parcourt par pages l’historique des tours d’un thread stocké sans le reprendre. Utilisez itemsView pour choisir si les éléments des tours sont omis, résumés ou chargés intégralement.
  • thread/items/list est expérimental et parcourt par pages les éléments persistants d’un thread, éventuellement limités à un seul tour.
  • thread/list prend en charge la pagination par curseur ainsi que les filtres modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm et les filtres expérimentaux parentThreadId ou ancestorThreadId.
  • thread/loaded/list renvoie les identifiants des threads actuellement en mémoire.
  • thread/archive déplace le journal JSONL persistant du thread dans le répertoire d’archives et tente d’archiver les journaux des threads descendants générés qui ne le sont pas déjà.
  • thread/delete supprime définitivement un thread persistant actif ou archivé ainsi que ses threads descendants générés.
  • thread/metadata/update modifie les métadonnées du thread stocké, notamment les valeurs persistantes gitInfo et isPinned.
  • thread/unsubscribe désabonne la connexion actuelle d’un thread chargé et peut déclencher thread/closed après un délai d’inactivité.
  • thread/unarchive restaure un rollout de thread archivé dans le répertoire des sessions actives.
  • thread/compact/start déclenche la compaction et renvoie immédiatement {}.
  • thread/rollback est obsolète. Il retire les N derniers tours du contexte en mémoire et enregistre un marqueur de restauration dans le journal JSONL persistant du thread.
  • thread/inject_items ajoute des éléments Responses API bruts à l’historique visible par le modèle d’un thread chargé sans démarrer de tour utilisateur.

Démarrer ou reprendre un thread

Démarrez un nouveau thread lorsque vous avez besoin d’une nouvelle conversation 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 est facultatif. Définissez-le lorsque vous souhaitez qu’app-server associe aux métriques du thread le nom de service de votre intégration.

thread/start, thread/resume et thread/fork renvoient instructionSources, un tableau de chemins de fichiers d’instructions chargés. Chaque chemin utilise la syntaxe absolue native de son environnement source, y compris pour les environnements distants.

Les clients expérimentaux peuvent définir historyMode sur thread/start avec la valeur "legacy" (par défaut) ou "paginated". La création paginée de threads n’est pas encore prise en charge et renvoie l’erreur JSON-RPC -32601. App-server peut répertorier et lire les résumés des enregistrements paginés existants, mais la lecture de l’historique complet, la pagination des tours et la reprise échouent de manière sécurisée tant que l’historique paginé n’est pas pris en charge.

Les clients bêta qui activent capabilities.experimentalApi peuvent transmettre l’identifiant nommé d’un profil d’autorisation dans permissions au lieu du champ historique sandbox. N’envoyez pas permissions et sandbox ensemble. Utilisez permissionProfile/list avec le cwd du projet pour découvrir les profils disponibles et vérifier si les exigences gérées autorisent chacun d’eux.

thread.sessionId identifie la racine actuelle de l’arborescence des sessions actives. Les threads racines utilisent leur propre identifiant de thread comme identifiant de session ; les threads issus d’une branche conservent l’identifiant de session de la racine dont ils proviennent. Les clients doivent lire l’identifiant de session dans thread.sessionId au lieu de le déduire de l’identifiant du thread.

Pour poursuivre une session stockée, appelez thread/resume avec le thread.id que vous avez enregistré précédemment. La structure de la réponse correspond à thread/start. Vous pouvez également transmettre les mêmes remplacements de configuration que ceux pris en charge par thread/start, tels que 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 } } }

La reprise d’un thread ne met pas à jour thread.updatedAt (ni l’heure de modification du fichier de rollout) à elle seule. L’horodatage est mis à jour lorsque vous démarrez un tour.

Si vous marquez un serveur MCP activé comme required dans la configuration et que l’initialisation de ce serveur échoue, thread/start et thread/resume échouent au lieu de poursuivre sans lui.

dynamicTools sur thread/start est un champ expérimental (nécessite capabilities.experimentalApi = true). Codex conserve ces outils dynamiques dans les métadonnées de rollout du thread et les restaure lors de thread/resume lorsque vous ne fournissez pas de nouveaux outils dynamiques.

Si vous reprenez un thread avec un modèle différent de celui enregistré dans le rollout, Codex émet un avertissement et applique une instruction ponctuelle de changement de modèle au tour suivant.

Gérer l’objectif d’un thread

Utilisez thread/goal/set, thread/goal/get et thread/goal/clear pour gérer le même état d’objectif persistant que celui affiché par /goal dans 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
  }
} }

Les objectifs doivent contenir entre 1 et 4 000 caractères. La fourniture d’un nouvel objectif remplace l’objectif existant et réinitialise le suivi de l’utilisation. La fourniture de l’objectif non terminal actuel, ou l’omission de objective, met à jour le statut ou le budget de jetons tout en conservant l’historique d’utilisation.

Pour créer une branche à partir d’une session stockée, appelez thread/fork avec le thread.id. Cela crée un nouvel identifiant de thread et émet une notification thread/started correspondante. Transmettez lastTurnId pour copier l’historique jusqu’à ce tour inclus et omettre les tours suivants :

{ "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 rejette un lastTurnId en cours. Si vous omettez ce champ alors que le thread source se trouve au milieu d’un tour, la branche enregistre un marqueur d’interruption au lieu de conserver un tour partiel sans marqueur.

Transmettez ephemeral: true pour créer une branche en mémoire sans l’ajouter aux listes de threads stockés :

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

Les branches éphémères de threads paginés nécessitent également excludeTurns: true. Ce champ est expérimental et nécessite capabilities.experimentalApi = true.

Lorsqu’un titre de thread visible par l’utilisateur a été défini, app-server renseigne thread.name dans les réponses thread/list, thread/read, thread/resume, thread/unarchive et thread/rollback. thread/start et thread/fork peuvent omettre name (ou renvoyer null) jusqu’à ce qu’un titre soit défini ultérieurement.

Lire un thread stocké (sans le reprendre)

Utilisez thread/read lorsque vous souhaitez accéder aux données d’un thread stocké sans le reprendre ni vous abonner à ses événements.

  • includeTurns - lorsque la valeur est true, la réponse inclut les tours du thread ; lorsque la valeur est false ou qu’elle est omise, vous obtenez uniquement le résumé du thread.
  • Les objets thread renvoyés incluent le status d’exécution (notLoaded, idle, systemError ou active avec 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": [] } } }

Contrairement à thread/resume, thread/read ne charge pas le thread en mémoire et n’émet pas thread/started.

Répertorier les tours d’un thread

thread/turns/list est expérimental. Utilisez-le pour parcourir par pages l’historique des tours d’un thread stocké sans le reprendre. Par défaut, les résultats sont classés du plus récent au plus ancien afin que les clients puissent récupérer les tours plus anciens avec nextCursor. La réponse inclut également backwardsCursor ; transmettez-le en tant que cursor avec sortDirection: "asc" pour récupérer les tours plus récents que le premier élément de la page précédente.

itemsView détermine la quantité de données d’éléments de tours incluse dans la réponse :

  • notLoaded omet les éléments.
  • summary renvoie des données d’éléments résumées et constitue la valeur par défaut en cas d’omission.
  • full renvoie les données d’éléments complètes.
{ "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 est également expérimental. Il parcourt par pages les éléments persistants sans reprendre le thread. Transmettez turnId pour limiter les résultats à un seul tour, ou omettez-le pour parcourir les éléments de l’ensemble du thread. Le stockage de threads actif doit prendre en charge la pagination des éléments ; dans le cas contraire, le serveur renvoie une erreur indiquant que la méthode n’est pas prise en charge.

Répertorier les threads (avec pagination et filtres)

thread/list vous permet d’afficher une interface d’historique. Par défaut, les résultats sont classés du plus récent au plus ancien selon createdAt. Les filtres s’appliquent avant la pagination. Transmettez n’importe quelle combinaison des paramètres suivants :

  • cursor - chaîne opaque provenant d’une réponse précédente ; omettez-la pour la première page.
  • limit - le serveur utilise par défaut une taille de page raisonnable si ce paramètre n’est pas défini.
  • sortKey - created_at (par défaut), updated_at ou recency_at.
  • sortDirection - desc (par défaut) ou asc.
  • modelProviders - limite les résultats à des fournisseurs spécifiques ; une valeur non définie, null ou un tableau vide inclut tous les fournisseurs.
  • sourceKinds - limite les résultats à des sources de threads spécifiques. Si ce paramètre est omis ou vaut [], le serveur utilise par défaut uniquement les sources interactives : cli et vscode.
  • archived - lorsque la valeur est true, répertorie uniquement les threads archivés. Lorsque la valeur est false ou qu’elle est omise, répertorie les threads non archivés (par défaut).
  • isPinned - lorsqu’il est fourni, renvoie uniquement les threads dont l’état d’épinglage persistant correspond. Omettez-le pour renvoyer les threads épinglés et non épinglés.
  • cwd - limite les résultats aux threads dont le répertoire de travail actuel de la session correspond exactement à ce chemin ou à l’un des chemins d’un tableau. Les chemins relatifs sont résolus à partir du répertoire de travail du processus app-server.
  • useStateDbOnly - lorsque la valeur est true, renvoie les résultats de la base de données d’état sans analyser les journaux de threads JSONL pour réparer les métadonnées. Omettez ce paramètre ou transmettez false pour conserver le comportement par défaut d’analyse et de réparation.
  • searchTerm - limite les résultats aux threads dont le titre extrait contient ce fragment de texte sensible à la casse.
  • parentThreadId - limite les résultats aux threads enfants directs du thread indiqué. Ce filtre est expérimental et nécessite capabilities.experimentalApi = true.
  • ancestorThreadId - limite les résultats aux descendants générés du thread indiqué, quelle que soit leur profondeur. Ce filtre est expérimental et nécessite capabilities.experimentalApi = true ; ne l’associez pas à parentThreadId.

sourceKinds accepte les valeurs suivantes :

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

Exemple :

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

Lorsque nextCursor vaut null, vous avez atteint la dernière page.

Mettre à jour les métadonnées d’un thread stocké

Utilisez thread/metadata/update pour modifier les métadonnées d’un thread stocké sans reprendre le thread. Définissez isPinned pour épingler ou désépingler le thread, ou mettez à jour gitInfo pour modifier les métadonnées Git persistantes. Les champs omis restent inchangés ; une valeur null explicite efface une valeur de métadonnées Git stockée.

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

Suivre les changements d’état d’un thread

thread/status/changed est émis chaque fois que l’état d’exécution d’un thread chargé change. La charge utile comprend threadId et le nouveau status.

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

Répertorier les threads chargés

thread/loaded/list renvoie les identifiants des threads actuellement chargés en mémoire.

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

Se désabonner d’un thread chargé

thread/unsubscribe supprime l’abonnement de la connexion actuelle à un thread. L’état de la réponse est l’un des suivants :

  • unsubscribed lorsque la connexion était abonnée et que l’abonnement est désormais supprimé.
  • notSubscribed lorsque la connexion n’était pas abonnée à ce thread.
  • notLoaded lorsque le thread n’est pas chargé.

S’il s’agissait du dernier abonné, le serveur conserve le thread chargé jusqu’à ce qu’il n’ait plus aucun abonné ni aucune activité pendant 30 minutes. À l’expiration du délai, app-server décharge le thread et émet une transition thread/status/changed vers notLoaded ainsi que thread/closed.

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

Si le thread expire ultérieurement :

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

Archiver un thread

Utilisez thread/archive pour déplacer le journal persistant du thread (stocké sous forme de fichier JSONL sur le disque) vers le répertoire des sessions archivées. L’archivage d’un thread tente également d’archiver les threads descendants générés qui ne le sont pas déjà.

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

Les fils archivés n’apparaîtront pas dans les futurs appels à thread/list, sauf si vous transmettez archived: true. Le serveur émet une notification thread/archived pour chaque fil qu’il archive effectivement ; si un descendant créé ne peut pas être archivé, la requête peut tout de même aboutir sans notification d’archivage pour ce descendant.

Supprimer un fil

Utilisez thread/delete pour supprimer définitivement un fil actif ou archivé persistant ainsi que les fils descendants qu’il a créés. Le serveur supprime les fichiers de rollout existants et les métadonnées associées avant de renvoyer une réponse indiquant la réussite ; les fichiers de rollout manquants sont considérés comme déjà supprimés. Les fils racines éphémères ne peuvent pas être supprimés.

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

Désarchiver un fil

Utilisez thread/unarchive pour replacer le rollout d’un fil archivé dans le répertoire des sessions actives.

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

Déclencher la compaction d’un fil

Utilisez thread/compact/start pour déclencher manuellement la compaction de l’historique d’un fil. La requête renvoie immédiatement {}.

App-server communique la progression au moyen des notifications standard turn/* et item/* sur le même threadId, notamment le cycle de vie d’un élément contextCompaction (item/started puis item/completed).

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

Exécuter une commande shell dans un fil

Utilisez thread/shellCommand pour les commandes shell lancées par l’utilisateur et rattachées à un fil. La requête renvoie immédiatement {}, tandis que la progression est diffusée par les notifications standard turn/* et item/*.

Cette API s’exécute hors du bac à sable avec un accès complet et n’hérite pas de la politique de bac à sable du fil. Les clients ne doivent l’exposer que pour des commandes explicitement lancées par l’utilisateur.

Si le fil comporte déjà un tour actif, la commande s’exécute comme action auxiliaire de ce tour et sa sortie mise en forme est injectée dans le flux de messages du tour. Si le fil est inactif, app-server lance un tour autonome pour la commande shell.

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

Nettoyer les terminaux en arrière-plan

Utilisez thread/backgroundTerminals/clean pour arrêter tous les terminaux en arrière-plan en cours d’exécution associés à un fil. Cette méthode est expérimentale et nécessite capabilities.experimentalApi = true.

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

Utilisez thread/backgroundTerminals/list pour inspecter les terminaux en arrière-plan en cours d’exécution pour un fil chargé. La requête prend en charge la pagination standard cursor et limit, et le processId renvoyé correspond à l’identifiant du processus app-server. Cette méthode est expérimentale et nécessite 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 } }

Utilisez thread/backgroundTerminals/terminate avec ce processId pour arrêter un terminal en arrière-plan. Cette méthode est expérimentale et nécessite capabilities.experimentalApi = true :

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

Annuler les tours récents

thread/rollback est obsolète et sera supprimé. Il retire les dernières entrées numTurns du contexte en mémoire et conserve un marqueur d’annulation dans le journal de rollout. Le thread renvoyé comprend turns renseigné après l’annulation.

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

Tours

Le champ input accepte une liste d’éléments :

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

Vous pouvez remplacer les paramètres de configuration pour chaque tour (modèle, effort, personnalité, cwd, politique de bac à sable, résumé). Lorsqu’ils sont spécifiés, ces paramètres deviennent les valeurs par défaut des tours suivants du même fil. outputSchema ne s’applique qu’au tour en cours. Pour sandboxPolicy.type = "externalSandbox", définissez networkAccess sur restricted ou enabled ; pour workspaceWrite, networkAccess reste une valeur booléenne.

Pour turn/start.collaborationMode, settings.developer_instructions: null signifie « utiliser les instructions intégrées du mode sélectionné » et non effacer les instructions du mode.

Accès en lecture du bac à sable (ReadOnlyAccess)

sandboxPolicy prend en charge des contrôles explicites de l’accès en lecture :

  • readOnly : access facultatif ({ "type": "fullAccess" } par défaut, ou racines restreintes).
  • workspaceWrite : readOnlyAccess facultatif ({ "type": "fullAccess" } par défaut, ou racines restreintes).

Structure de l’accès en lecture restreint :

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

Sous macOS, includePlatformDefaults: true ajoute une politique Seatbelt prédéfinie pour la plateforme aux sessions dont l’accès en lecture est restreint. Cela améliore la compatibilité des outils sans autoriser largement l’ensemble de /System.

Exemples :

{ "type": "readOnly", "access": { "type": "fullAccess" } }
{
  "type": "workspaceWrite",
  "writableRoots": ["/Users/me/project"],
  "readOnlyAccess": {
    "type": "restricted",
    "includePlatformDefaults": true,
    "readableRoots": ["/Users/me/shared-read-only"]
  },
  "networkAccess": false
}

Démarrer un tour

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

Injecter des éléments dans un fil

Utilisez thread/inject_items pour ajouter des éléments Responses API préconstruits à l’historique des prompts d’un fil chargé sans démarrer de tour utilisateur. Ces éléments sont conservés dans le rollout et inclus dans les requêtes ultérieures au modèle.

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

Orienter un tour actif

Utilisez turn/steer pour ajouter une nouvelle saisie utilisateur au tour actif en cours d’exécution.

  • Incluez expectedTurnId ; il doit correspondre à l’identifiant du tour actif.
  • La requête échoue si le fil ne comporte aucun tour actif.
  • turn/steer n’émet pas de nouvelle notification turn/started.
  • turn/steer n’accepte pas les remplacements au niveau du tour (model, cwd, sandboxPolicy ou 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" } }

Démarrer un tour (appeler une compétence)

Appelez explicitement une compétence en incluant $<skill-name> dans la saisie textuelle et en ajoutant un élément d’entrée skill à ses côtés.

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

Interrompre un tour

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

En cas de réussite, le tour se termine avec status: "interrupted".

Revue

review/start exécute le réviseur Codex pour un fil et diffuse les éléments de revue. Les cibles comprennent :

  • uncommittedChanges
  • baseBranch (diff par rapport à une branche)
  • commit (revue d’un commit précis)
  • custom (instructions libres)

Utilisez delivery: "inline" (valeur par défaut) pour exécuter la revue sur le fil existant, ou delivery: "detached" pour créer un nouveau fil de revue par bifurcation.

Exemple de requête et de réponse :

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

Pour une revue détachée, utilisez "delivery": "detached". La réponse présente la même structure, mais reviewThreadId correspond à l’identifiant du nouveau fil de revue (différent du threadId d’origine). Le serveur émet également une notification thread/started pour ce nouveau fil avant de diffuser le tour de revue.

Codex diffuse la notification turn/started habituelle, suivie d’un item/started contenant un élément enteredReviewMode :

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

Lorsque le réviseur termine, le serveur émet item/started et item/completed contenant un élément exitedReviewMode avec le texte final de la revue :

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

Utilisez cette notification pour afficher la sortie du réviseur dans votre client.

Exécution de processus

process/* est une API expérimentale et explicite de contrôle des processus. Elle nécessite capabilities.experimentalApi = true et s’exécute hors du bac à sable de Codex. Utilisez-la uniquement lorsque votre client expose délibérément le contrôle des processus locaux sans bac à sable.

Démarrez un processus avec process/spawn et fournissez un processHandle, puis utilisez ce handle pour les requêtes d’entrée standard, de redimensionnement et d’arrêt. La sortie est diffusée au moyen des notifications process/outputDelta, et la fin du processus au moyen de 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
} }

Utilisez process/writeStdin avec deltaBase64, closeStdin ou les deux pour envoyer des données d’entrée. Utilisez process/resizePty pour les événements de redimensionnement du PTY et process/kill pour mettre fin à un processus en cours d’exécution.

Exécution de commandes

command/exec exécute une seule commande (tableau argv) dans le bac à sable du serveur sans créer de fil.

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

Utilisez sandboxPolicy.type = "externalSandbox" si vous placez déjà le processus serveur dans un bac à sable et souhaitez que Codex ignore son propre mécanisme de bac à sable. Pour le mode de bac à sable externe, définissez networkAccess sur restricted (valeur par défaut) ou enabled. Pour readOnly et workspaceWrite, utilisez la même structure facultative access / readOnlyAccess que celle présentée ci-dessus.

Remarques :

  • Le serveur rejette les tableaux command vides.
  • sandboxPolicy accepte la même structure que turn/start (par exemple, dangerFullAccess, readOnly, workspaceWrite, externalSandbox).
  • Lorsqu’il est omis, timeoutMs reprend la valeur par défaut du serveur.
  • Définissez tty: true pour les sessions reposant sur un PTY et utilisez processId lorsque vous prévoyez d’effectuer ensuite un appel à command/exec/write, command/exec/resize ou command/exec/terminate.
  • Définissez streamStdoutStderr: true pour recevoir des notifications command/exec/outputDelta pendant l’exécution de la commande.

Lire les exigences d’administration (configRequirements/read)

Utilisez configRequirements/read pour inspecter les exigences d’administration effectives chargées depuis requirements.toml et/ou MDM.

{ "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 vaut null lorsqu’aucune exigence n’est configurée. Consultez la documentation sur requirements.toml pour en savoir plus sur les clés et valeurs prises en charge.

Configuration du bac à sable Windows (windowsSandbox/setupStart)

Les clients Windows personnalisés peuvent déclencher la configuration du bac à sable de manière asynchrone au lieu de bloquer pendant les vérifications de démarrage.

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

App-server lance la configuration en arrière-plan, puis émet ultérieurement une notification d’achèvement :

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

Modes :

  • elevated - exécute le processus de configuration avec élévation du bac à sable Windows.
  • unelevated - exécute l’ancien processus de configuration/vérification préalable.

Système de fichiers

Les API de système de fichiers v2 utilisent des chemins absolus. Utilisez fs/watch lorsqu’un client doit invalider l’état de l’interface utilisateur après la modification d’un fichier ou d’un répertoire.

{ "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 surveillance d’un fichier émet fs/changed pour le chemin de ce fichier, y compris pour les mises à jour effectuées par des opérations de remplacement ou de renommage.

Événements

Les notifications d’événements constituent le flux émis par le serveur pour les cycles de vie des fils, des tours et des éléments qu’ils contiennent. Après avoir démarré ou repris un fil, continuez à lire le flux de transport actif pour recevoir les notifications thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* et serverRequest/resolved.

Désactivation des notifications

Les clients peuvent supprimer certaines notifications pour chaque connexion en envoyant leurs noms de méthode exacts dans initialize.params.capabilities.optOutNotificationMethods.

  • Correspondance exacte uniquement : item/agentMessage/delta ne supprime que cette méthode.
  • Les noms de méthode inconnus sont ignorés.
  • S’applique aux notifications v2 thread/*, turn/*, item/* et associées de la connexion actuelle.
  • Ne s’applique pas aux requêtes, réponses ni erreurs.

Événements de recherche approximative de fichiers (expérimental)

L’API de session de recherche approximative de fichiers émet des notifications pour chaque requête :

  • fuzzyFileSearch/sessionUpdated - { sessionId, query, files } avec les correspondances actuelles de la requête active.
  • fuzzyFileSearch/sessionCompleted - { sessionId } une fois l’indexation et la recherche des correspondances terminées pour cette requête.

Événements d’avertissement

  • configWarning - { summary, details?, path?, range? } pour les problèmes récupérables de configuration ou d’initialisation.
  • warning - { threadId?, message } pour les avertissements d’exécution non fatals.

Événements de configuration du bac à sable Windows

  • windowsSandbox/setupCompleted - { mode, success, error } émis à l’issue d’une requête windowsSandbox/setupStart.

Événements de tour

  • turn/started - { turn } avec l’identifiant du tour, un items vide et status: "inProgress".
  • turn/completed - { turn }turn.status vaut completed, interrupted ou failed ; les échecs incluent { error: { message, codexErrorInfo?, additionalDetails? } }.
  • turn/diff/updated - { threadId, turnId, diff } avec le dernier diff unifié agrégé de toutes les modifications de fichiers du tour.
  • turn/plan/updated - { turnId, explanation?, plan } chaque fois que l’agent partage ou modifie son plan ; chaque entrée plan est un { step, status } dont status vaut pending, inProgress ou completed.
  • hook/started et hook/completed - { threadId, turnId?, run } lorsqu’un hook de cycle de vie démarre et lorsque le résumé final de son exécution est disponible.
  • model/safetyBuffering/updated - { threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel } lorsqu’une réponse entre dans une mémoire tampon de sécurité transitoire.
  • model/rerouted - { threadId, turnId, fromModel, toModel, reason } lorsque le service achemine une requête vers un autre modèle.
  • model/verification - { threadId, turnId, verifications } lorsque le service exige une vérification supplémentaire du compte.
  • thread/tokenUsage/updated - mises à jour de l’utilisation pour le fil actif.

turn/diff/updated et turn/plan/updated comprennent actuellement des tableaux items vides même lorsque des événements d’élément sont diffusés. Utilisez les notifications item/* comme source de référence pour les éléments du tour.

Éléments

ThreadItem est l’union discriminée transmise dans les réponses des tours et les notifications item/*. Les types d’éléments courants comprennent :

  • userMessage - {id, content}content est une liste d’entrées utilisateur (text, image ou localImage).
  • agentMessage - {id, text, phase?} contenant la réponse cumulée de l’agent. Lorsqu’il est présent, phase utilise les valeurs de protocole de Responses API (commentary, final_answer).
  • plan - {id, text} contenant le texte du plan proposé en mode plan. Considérez l’élément plan final de item/completed comme faisant autorité.
  • reasoning - {id, summary, content}summary contient les résumés de raisonnement diffusés et content les blocs de raisonnement bruts.
  • commandExecution - {id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.
  • fileChange - {id, changes, status} décrivant les modifications proposées ; la liste changes contient des {path, kind, diff}.
  • mcpToolCall - {id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Pour les apps MCP de confiance, appContext peut inclure connectorId, linkId, resourceUri, appName, templateId et le connecteur stable actionName. Les anciens éléments conservés peuvent omettre les métadonnées plus récentes. Utilisez appContext.resourceUri au lieu du champ de premier niveau obsolète mcpAppResourceUri.
  • dynamicToolCall - {id, tool, arguments, status, contentItems?, success?, durationMs?} pour les appels d’outils dynamiques exécutés par le client.
  • collabToolCall - {id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.
  • webSearch - {id, query, action?} pour les requêtes de recherche sur le Web lancées par l’agent.
  • imageView - {id, path} émis lorsque l’agent appelle l’outil de visualisation d’images.
  • enteredReviewMode - {id, review} envoyé au démarrage du réviseur.
  • exitedReviewMode - {id, review} émis lorsque le réviseur termine.
  • contextCompaction - {id} émis lorsque Codex compacte l’historique de la conversation.

Pour webSearch.action, l’action type peut être search (query?, queries?), openPage (url?) ou findInPage (url?, pattern?).

App-server rend obsolète l’ancienne notification thread/compacted ; utilisez plutôt l’élément contextCompaction.

Tous les éléments émettent deux événements de cycle de vie communs :

  • item/started - émet le item complet lorsqu’une nouvelle unité de travail commence ; le item.id correspond au itemId utilisé par les deltas.
  • item/completed - envoie le item final lorsque le travail se termine ; considérez-le comme l’état faisant autorité.

Deltas d’élément

  • item/agentMessage/delta - ajoute le texte diffusé au message de l’agent.
  • item/plan/delta - diffuse le texte du plan proposé. L’élément plan final peut ne pas correspondre exactement aux deltas concaténés.
  • item/reasoning/summaryTextDelta - diffuse des résumés lisibles du raisonnement ; summaryIndex s’incrémente lorsqu’une nouvelle section du résumé s’ouvre.
  • item/reasoning/summaryPartAdded - marque une limite entre les sections du résumé du raisonnement.
  • item/reasoning/textDelta - diffuse le texte brut du raisonnement (lorsque le modèle le prend en charge).
  • item/commandExecution/outputDelta - diffuse stdout/stderr pour une commande ; ajoutez les deltas dans l’ordre.
  • item/fileChange/outputDelta - notification de compatibilité obsolète pour l’ancienne sortie textuelle apply_patch. Les versions actuelles d’app-server ne l’émettent plus ; utilisez les éléments fileChange et turn/diff/updated à la place.

Erreurs

Si un tour échoue, le serveur émet un événement error avec { error: { message, codexErrorInfo?, additionalDetails? } }, puis termine le tour avec status: "failed". Lorsqu’un statut HTTP en amont est disponible, il apparaît dans codexErrorInfo.httpStatusCode.

Les valeurs codexErrorInfo courantes comprennent :

  • ContextWindowExceeded
  • UsageLimitExceeded
  • HttpConnectionFailed (erreurs 4xx/5xx en amont)
  • ResponseStreamConnectionFailed
  • ResponseStreamDisconnected
  • ResponseTooManyFailedAttempts
  • BadRequest, Unauthorized, SandboxError, InternalServerError, Other

Lorsqu’un statut HTTP en amont est disponible, le serveur le transmet dans httpStatusCode sur la variante codexErrorInfo concernée.

Approbations

Selon les paramètres Codex de l’utilisateur, l’exécution de commandes et les modifications de fichiers peuvent nécessiter une approbation. App-server envoie au client une requête JSON-RPC initiée par le serveur, et le client répond avec une charge utile de décision.

  • Décisions relatives à l’exécution de commandes : accept, acceptForSession, decline, cancel ou { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.

  • Décisions relatives aux modifications de fichiers : accept, acceptForSession, decline, cancel.

  • Les requêtes comprennent threadId et turnId ; utilisez-les pour limiter l’état de l’interface utilisateur à la conversation active.

  • Le serveur reprend ou refuse le travail, puis termine l’élément avec item/completed.

Approbations de l’exécution de commandes

Ordre des messages :

  1. item/started affiche l’élément commandExecution en attente avec command, cwd et d’autres champs.
  2. item/commandExecution/requestApproval comprend itemId, threadId, turnId, le champ facultatif reason, le champ facultatif command, le champ facultatif cwd, le champ facultatif commandActions, le champ facultatif proposedExecpolicyAmendment, le champ facultatif networkApprovalContext et le champ facultatif availableDecisions. Lorsque initialize.params.capabilities.experimentalApi = true, la charge utile peut également comprendre le champ expérimental additionalPermissions décrivant l’accès au bac à sable demandé pour chaque commande. Tous les chemins de système de fichiers dans additionalPermissions sont absolus dans le protocole.
  3. Le client répond avec l’une des décisions d’approbation de l’exécution de commandes ci-dessus.
  4. serverRequest/resolved confirme que la requête en attente a reçu une réponse ou a été effacée.
  5. item/completed renvoie l’élément commandExecution final avec status: completed | failed | declined.

Lorsque networkApprovalContext est présent, l’invite concerne un accès réseau géré (et non l’approbation générale d’une commande shell). Le schéma v2 actuel expose la cible host et protocol ; les clients doivent afficher une invite propre au réseau et ne pas supposer que command constitue un aperçu de commande shell pertinent pour l’utilisateur.

Codex regroupe les invites d’approbation réseau simultanées par destination (host, protocole et port). App-server peut donc envoyer une seule invite qui débloque plusieurs requêtes en attente vers la même destination, tandis que différents ports d’un même hôte sont traités séparément.

Approbations des modifications de fichiers

Ordre des messages :

  1. item/started émet un élément fileChange avec les champs proposés changes et status: "inProgress".
  2. item/fileChange/requestApproval comprend itemId, threadId, turnId, le champ facultatif reason et le champ facultatif grantRoot.
  3. Le client répond avec l’une des décisions d’approbation des modifications de fichiers ci-dessus.
  4. serverRequest/resolved confirme que la requête en attente a reçu une réponse ou a été effacée.
  5. item/completed renvoie l’élément fileChange final avec status: completed | failed | declined.

tool/requestUserInput

Lorsque le client répond à item/tool/requestUserInput, app-server émet serverRequest/resolved avec { threadId, requestId }. Si la requête en attente est effacée au démarrage, à la fin ou lors de l’interruption du tour avant la réponse du client, le serveur émet la même notification pour ce nettoyage.

Les paramètres de la requête comprennent autoResolutionMs sous la forme d’un délai d’expiration entier en millisecondes ou null. Lorsqu’il est présent, les clients hôtes peuvent résoudre automatiquement l’invite après cet intervalle si l’utilisateur ne répond pas.

Demandes d’autorisation

L’outil intégré request_permissions envoie item/permissions/requestApproval avec threadId, turnId, itemId, environmentId, cwd, le champ facultatif reason et les autorisations réseau ou de système de fichiers demandées. Répondez avec permissions contenant uniquement le sous-ensemble accordé. Définissez scope sur "session" pour conserver l’autorisation pour les tours ultérieurs de la même session ; omettez-le ou utilisez "turn" pour limiter l’autorisation au tour. Les autorisations qui n’ont pas été demandées sont ignorées.

Demandes de sollicitation du serveur MCP

Un serveur MCP peut interrompre un tour avec mcpServer/elicitation/request. La requête comprend threadId, le champ facultatif turnId, serverName et l’une des structures de requête suivantes :

  • mode: "form" ou mode: "openai/form", avec message et requestedSchema.
  • mode: "url", avec message, url et elicitationId.

Répondez avec action: "accept" et le content demandé, ou avec action: "decline" ou "cancel" et content: null. App-server émet ensuite serverRequest/resolved. Pour recevoir la variante openai/form, activez-la avec initialize.params.capabilities.mcpServerOpenaiFormElicitation.

Appels d’outils dynamiques (expérimental)

dynamicTools sur thread/start et le flux de requête ou de réponse item/tool/call correspondant sont des API expérimentales.

Les noms d’outils dynamiques et d’espaces de noms doivent respecter les contraintes de nommage de Responses API. Évitez les noms d’espaces de noms réservés utilisés par les outils Codex intégrés.

Lorsqu’un outil dynamique est appelé pendant un tour, app-server émet :

  1. item/started avec item.type = "dynamicToolCall", status = "inProgress", ainsi que tool et arguments.
  2. item/tool/call en tant que requête du serveur au client.
  3. La charge utile de réponse du client avec les éléments de contenu renvoyés.
  4. item/completed avec item.type = "dynamicToolCall", le status final et toute valeur contentItems ou success renvoyée.

Approbations des appels d’outils MCP (apps)

Les appels d’outils d’apps (connecteurs) peuvent également nécessiter une approbation. Lorsqu’un appel d’outil d’app produit des effets secondaires, le serveur peut solliciter une approbation avec tool/requestUserInput et des options telles que Accepter, Refuser et Annuler. Les annotations d’outils destructifs déclenchent toujours une approbation, même si l’outil indique également des caractéristiques moins privilégiées. Si l’utilisateur refuse ou annule, l’élément mcpToolCall associé se termine avec une erreur au lieu d’exécuter l’outil.

Compétences

Appelez une compétence en incluant $<skill-name> dans la saisie textuelle. Ajoutez un élément d’entrée skill (recommandé) afin que le serveur injecte l’intégralité des instructions de la compétence au lieu de laisser le modèle résoudre son nom.

{
  "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 vous omettez l’élément skill, le modèle analysera tout de même le marqueur $<skill-name> et tentera de localiser la compétence, ce qui peut augmenter la latence.

Exemple :

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

Utilisez skills/list pour récupérer les compétences disponibles (éventuellement limitées par cwds, avec forceReload). Vous pouvez également inclure perCwdExtraUserRoots pour analyser des chemins absolus supplémentaires en tant que portée user pour des valeurs cwd précises. App-server ignore les entrées dont cwd n’est pas présent dans cwds. skills/list peut réutiliser un résultat mis en cache pour chaque cwd ; définissez forceReload: true pour actualiser les données depuis le disque. Lorsqu’ils sont présents, le serveur lit interface et dependencies depuis 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": []
  }]
} }

Le serveur émet également des notifications skills/changed lorsque les fichiers de compétences locaux surveillés changent. Considérez-les comme un signal d’invalidation et réexécutez skills/list avec vos paramètres actuels si nécessaire.

Pour activer ou désactiver une compétence par chemin :

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

Apps (connecteurs)

Utilisez app/installed pour lire le dernier instantané d’exécution validé des apps installées. Chaque résultat comprend le id de l’app, runtimeName (ou null), l’état effectif enabled et l’état callable. Une app ne peut être appelée que lorsque la configuration effective l’active et qu’au moins un outil visible par le modèle respecte les politiques de l’app et des outils.

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

Omettez threadId pour utiliser la configuration globale au lieu de celle d’un fil chargé. Définissez forceRefresh: true pour actualiser l’instantané d’exécution du connecteur avant de le lire. Lorsque la politique globale ou celle de l’espace de travail bloque l’accès aux apps, une app observée peut tout de même apparaître avec enabled et callable définis sur false.

Utilisez app/list pour récupérer les apps disponibles. Dans la CLI/TUI, /apps est le sélecteur affiché à l’utilisateur ; dans les clients personnalisés, appelez directement app/list. Chaque entrée comprend à la fois isAccessible (disponible pour l’utilisateur) et isEnabled (activé dans config.toml), afin que les clients puissent distinguer l’installation ou l’accès de l’état d’activation local. Les entrées d’app peuvent également comprendre les champs facultatifs branding, appMetadata et 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 vous fournissez threadId, le contrôle des fonctionnalités de l’app (features.apps) utilise l’instantané de configuration de ce fil. Lorsqu’il est omis, app-server utilise la dernière configuration globale.

app/list renvoie une réponse une fois les apps accessibles et celles du répertoire chargées. Définissez forceRefetch: true pour contourner les caches d’apps et récupérer des données actualisées. Les entrées du cache ne sont remplacées que si l’actualisation réussit.

Le serveur émet également des notifications app/list/updated chaque fois que le chargement de l’une des deux sources (apps accessibles ou apps du répertoire) se termine. Chaque notification comprend la dernière liste fusionnée des apps.

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

Utilisez app/read lorsque vous connaissez déjà les identifiants des apps et avez besoin de leurs métadonnées plutôt que de leur état d’exécution installé. Transmettez au maximum 100 appIds. Le serveur ne conserve que la première occurrence de chaque identifiant répété et maintient cet ordre dans apps comme dans missingAppIds. Les apps inconnues ou inaccessibles sont renvoyées dans missingAppIds sans faire échouer l’ensemble de la requête.

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

Définissez includeTools: true pour demander des résumés publics des outils destinés uniquement à l’affichage. La réponse de métadonnées ne comprend pas l’état d’exécution des apps installées et n’autorise pas un appel d’outil ; utilisez app/installed pour vérifier les états effectifs enabled et callable.

Appelez une app en insérant $<app-slug> dans la saisie textuelle et en ajoutant un élément d’entrée mention avec le chemin app://<id> (recommandé).

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

Exemples de RPC de configuration pour les paramètres d’apps

Utilisez config/read, config/value/write et config/batchWrite pour inspecter ou mettre à jour les contrôles des apps dans config.toml.

Lisez la structure effective de la configuration des apps (notamment _default et les remplacements propres à chaque outil) :

{ "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 définit le réviseur pour toutes les apps, sauf si une valeur propre à une app la remplace. Lorsque les deux sont omises, l’app hérite de la valeur approvals_reviewer de premier niveau. apps._default.default_tools_approval_mode définit le mode d’approbation de secours pour les outils sans remplacement propre à l’app ou à l’outil. Les exigences de mode d’approbation gérées prévalent sur les paramètres de mode d’approbation des outils.

Mettez à jour un seul paramètre d’app :

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

Appliquez plusieurs modifications d’app de manière atomique :

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

Détecter et importer la configuration d’un agent externe

Utilisez externalAgentConfig/detect pour découvrir les artefacts d’agents externes pouvant être migrés, puis transmettez les entrées sélectionnées à externalAgentConfig/import.

Exemple de détection :

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

Exemple d’importation :

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

Le paramètre d’importation facultatif de premier niveau source indique le produit ayant généré les éléments de migration sélectionnés.

Le serveur émet externalAgentConfig/import/progress à mesure que les types d’éléments se terminent, et externalAgentConfig/import/completed une fois toutes les importations synchrones et en arrière-plan terminées. Ces notifications comprennent le même importId que la réponse et itemTypeResults avec les champs successes et failures pour chaque type. La notification d’achèvement peut arriver immédiatement après la réponse ou une fois les importations distantes en arrière-plan terminées.

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

Lire les importations précédemment terminées :

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

Les valeurs itemType prises en charge sont AGENTS_MD, CONFIG, SKILLS, PLUGINS, MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS et SESSIONS. Pour les éléments PLUGINS, details.plugins répertorie chaque marketplaceName et le pluginNames que Codex peut tenter de migrer. La détection ne renvoie que les éléments pour lesquels il reste du travail. Par exemple, Codex ignore la migration d’AGENTS lorsque AGENTS.md existe déjà et n’est pas vide, et les importations de compétences n’écrasent pas les répertoires de compétences existants.

Lors de la détection de plugins depuis .claude/settings.json, Codex lit les sources de marketplace configurées dans extraKnownMarketplaces. Si enabledPlugins contient des plugins provenant de claude-plugins-official mais que la source du marketplace est absente, Codex déduit que anthropics/claude-plugins-official est la source.

Points de terminaison d’authentification

La surface JSON-RPC d’authentification et de compte expose des méthodes de requête/réponse ainsi que des notifications initiées par le serveur (sans id). Utilisez-les pour déterminer l’état d’authentification, démarrer ou annuler des connexions, se déconnecter, inspecter les limites d’utilisation de ChatGPT et avertir les propriétaires de l’espace de travail lorsque les crédits sont épuisés ou les limites d’utilisation atteintes.

Modes d’authentification

Codex prend en charge les modes d’authentification suivants. account/updated.authMode indique le mode actif et comprend le planType ChatGPT actuel lorsqu’il est disponible. account/read fournit également des informations sur le compte et l’abonnement.

  • API key (apikey) - l’appelant fournit une OpenAI API key avec type: "apiKey", et Codex la conserve pour les requêtes API.
  • Géré par ChatGPT (chatgpt) - Codex prend en charge le flux OAuth de ChatGPT, conserve les jetons et les actualise automatiquement. Commencez par type: "chatgpt" pour le flux dans le navigateur ou par type: "chatgptDeviceCode" pour le flux par code d’appareil.
  • Jetons ChatGPT externes (chatgptAuthTokens) - fonctionnalité expérimentale destinée aux apps hôtes qui gèrent déjà le cycle de vie de l’authentification ChatGPT de l’utilisateur. L’app hôte fournit directement un accessToken, un chatgptAccountId et, facultativement, un chatgptPlanType, et doit actualiser le jeton à la demande.
  • Amazon Bedrock - account/read signale les comptes Bedrock comme type: "amazonBedrock" et indique si les identifiants proviennent d’une Bedrock API key gérée par Codex (credentialSource: "codexManaged") ou de la chaîne d’identifiants AWS externe (credentialSource: "awsManaged"). account/updated.authMode utilise bedrockApiKey pour les Bedrock API keys gérées par Codex.

Vue d’ensemble de l’API

  • account/read - récupère les informations actuelles du compte ; peut éventuellement actualiser les jetons.
  • account/login/start - commence la connexion (apiKey, chatgpt, chatgptDeviceCode ou le mode expérimental chatgptAuthTokens).
  • account/login/completed (notification) - émise lorsqu’une tentative de connexion se termine (réussite ou erreur).
  • account/login/cancel - annule une connexion ChatGPT gérée en attente à l’aide de loginId.
  • account/logout - déconnecte l’utilisateur ; déclenche account/updated.
  • account/updated (notification) - émise chaque fois que le mode d’authentification change (authMode : apikey, chatgpt, chatgptAuthTokens, agentIdentity, personalAccessToken, bedrockApiKey ou null) et comprend planType lorsqu’il est disponible.
  • account/chatgptAuthTokens/refresh (requête du serveur) - demande de nouveaux jetons ChatGPT gérés en externe après une erreur d’autorisation.
  • account/rateLimits/read - récupère les limites d’utilisation de ChatGPT.
  • account/rateLimits/updated (notification) - émise chaque fois que les limites d’utilisation de ChatGPT d’un utilisateur changent.
  • account/sendAddCreditsNudgeEmail - demande à ChatGPT d’envoyer un e-mail au propriétaire d’un espace de travail lorsque les crédits sont épuisés ou qu’une limite d’utilisation est atteinte.
  • account/rateLimitResetCredit/consume - utilise une réinitialisation de limite d’utilisation acquise à l’aide d’une valeur idempotencyKey fournie par l’appelant.
  • account/usage/read - récupère les résumés d’activité des jetons du compte ChatGPT et les compartiments quotidiens.
  • account/workspaceMessages/read - récupère les messages actifs de l’espace de travail, notamment les titres des notifications lorsqu’ils sont disponibles.
  • mcpServer/oauthLogin/completed (notification) - émise à la fin d’un flux mcpServer/oauth/login ; la charge utile comprend { name, threadId, success, error? }. threadId peut valoir null pour les flux OAuth limités à une app ou à un plugin.
  • mcpServer/startupStatus/updated (notification) - émise lorsque l’état de démarrage d’un serveur MCP configuré change ; la charge utile comprend { threadId, name, status, error, failureReason }. threadId vaut null pour un démarrage limité à une app. En cas d’échec du démarrage, failureReason: "reauthenticationRequired" signifie que les identifiants OAuth conservés ont expiré et n’ont pas pu être actualisés ; le client doit donc proposer de reconnecter le serveur.

1) Vérifier l’état d’authentification

Requête :

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

Exemples de réponses :

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

Remarques sur les champs :

  • refreshToken (booléen) : définissez true pour forcer l’actualisation du jeton en mode ChatGPT géré. En mode de jetons externes (chatgptAuthTokens), app-server ignore cet indicateur.
  • email vaut null lorsque le compte ChatGPT ne possède pas d’adresse e-mail.
  • requiresOpenaiAuth reflète le fournisseur actif ; lorsque false, Codex peut fonctionner sans identifiants OpenAI.
  • Amazon Bedrock indique credentialSource: "codexManaged" lorsqu’il utilise une Bedrock API key gérée par Codex. Il indique credentialSource: "awsManaged" pour le chemin d’identifiants AWS externe. Cela identifie la source d’identifiants sélectionnée, sans valider que la chaîne d’identifiants AWS peut résoudre les identifiants.

2) Se connecter avec une API key

  1. Envoyez :
   {
     "method": "account/login/start",
     "id": 2,
     "params": { "type": "apiKey", "apiKey": "sk-..." }
   }
  1. Attendez-vous à recevoir :
   { "id": 2, "result": { "type": "apiKey" } }
  1. Notifications :
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "apikey", "planType": null }
   }

3) Se connecter avec ChatGPT (flux dans le navigateur)

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

Par défaut, un rappel de navigateur réussi redirige vers une page locale confirmant la réussite. Définissez useHostedLoginSuccessPage: true pour utiliser la page de réussite hébergée lorsque la configuration de l’organisation n’est pas requise. Lorsque la page de réussite hébergée est activée, appBrand peut valoir "codex" ou "chatgpt" ; les valeurs omises ou null utilisent par défaut "codex".

   {
     "id": 3,
     "result": {
       "type": "chatgpt",
       "loginId": "<uuid>",
       "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
     }
   }
  1. Ouvrez authUrl dans un navigateur ; app-server héberge le rappel local.
  2. Attendez les notifications :
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3b) Se connecter avec ChatGPT (flux par code d’appareil)

Utilisez ce flux lorsque votre client gère l’expérience de connexion ou lorsqu’un rappel de navigateur est peu fiable.

  1. Démarrez :
   {
     "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. Présentez verificationUrl et userCode à l’utilisateur ; le frontend gère l’expérience utilisateur.
  2. Attendez les notifications :
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3c) Se connecter avec des jetons ChatGPT gérés en externe (chatgptAuthTokens)

Utilisez ce mode expérimental uniquement lorsqu’une application hôte gère le cycle de vie de l’authentification ChatGPT de l’utilisateur et fournit directement les jetons. Les clients doivent définir capabilities.experimentalApi = true pendant initialize avant d’utiliser ce type de connexion.

  1. Envoyez :
   {
     "method": "account/login/start",
     "id": 7,
     "params": {
       "type": "chatgptAuthTokens",
       "accessToken": "<jwt>",
       "chatgptAccountId": "org-123",
       "chatgptPlanType": "business"
     }
   }
  1. Attendez-vous à recevoir :
   { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  1. Notifications :
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
   }

Lorsque le serveur reçoit un 401 Unauthorized, il peut demander des jetons actualisés à l’app hôte :

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

Le serveur réessaie la requête d’origine après une réponse d’actualisation réussie. Les requêtes expirent après environ 10 secondes.

4) Annuler une connexion ChatGPT

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

5) Se déconnecter

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

6) Limites d’utilisation (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 }
  }
} }

Remarques sur les champs :

  • rateLimits est la vue à compartiment unique assurant la rétrocompatibilité.
  • rateLimitsByLimitId (lorsqu’il est présent) est la vue à plusieurs compartiments indexée par limit_id mesuré (par exemple codex).
  • limitId est l’identifiant du compartiment mesuré.
  • limitName est un libellé facultatif du compartiment destiné à l’utilisateur.
  • usedPercent correspond à l’utilisation actuelle dans la fenêtre de quota.
  • windowDurationMins correspond à la durée de la fenêtre de quota.
  • resetsAt est un horodatage Unix (en secondes) de la prochaine réinitialisation.
  • planType est inclus lorsque le serveur renvoie l’abonnement ChatGPT associé à un compartiment.
  • credits est inclus lorsque le serveur renvoie les détails des crédits restants de l’espace de travail.
  • rateLimitReachedType identifie l’état de limite classé par le serveur lorsqu’une limite a été atteinte.
  • rateLimitResetCredits contient le nombre de réinitialisations acquises disponibles lorsque le service le fournit ; sinon, il vaut null.
  • rateLimitResetCredits.credits vaut null lorsque seul le nombre est connu. Un tableau vide signifie que le service a récupéré les détails et n’a renvoyé aucun crédit disponible. Le service peut limiter le nombre de lignes détaillées ; availableCount fait donc autorité.
  • Chaque ligne détaillée comprend un id opaque, resetType, status, grantedAt, expiresAt (qui peut valoir null), title (qui peut valoir null) et description (qui peut valoir null).
  • Récupérez account/rateLimits/read après avoir utilisé une réinitialisation.

7) Utilisation des jetons (ChatGPT)

Utilisez account/usage/read pour récupérer les champs du résumé d’activité des jetons ChatGPT et les compartiments quotidiens facultatifs.

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

Remarques sur les champs :

  • Les valeurs summary peuvent être null lorsque le service n’a pas renvoyé cette métrique.
  • dailyUsageBuckets peut valoir null ; lorsqu’il est présent, chaque compartiment comprend startDate et tokens.
  • Le point de terminaison exige une authentification reposant sur les services Codex. ChatGPT, les jetons ChatGPT externes, l’identité d’agent et l’authentification par jeton d’accès personnel fonctionnent ; l’authentification uniquement par API key et l’authentification Bedrock ne fonctionnent pas.

8) Réinitialisations acquises des limites d’utilisation (ChatGPT)

Utilisez account/rateLimitResetCredit/consume pour utiliser une réinitialisation acquise.

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

Remarques sur les champs :

  • idempotencyKey ne doit pas être vide. Utilisez un UUID pour chaque tentative logique d’utilisation et réutilisez la même valeur lorsque vous réessayez cette tentative.
  • creditId est facultatif. Lorsqu’il est fourni, il doit s’agir d’un identifiant opaque non vide provenant de account/rateLimits/read. Lorsqu’il est omis, le service sélectionne le prochain crédit disponible.
  • reset signifie qu’un crédit a été utilisé.
  • alreadyRedeemed signifie que la même utilisation a déjà abouti. Considérez-la comme une réussite idempotente et actualisez les limites du compte.
  • nothingToReset signifie qu’aucune fenêtre de limite d’utilisation admissible ne peut être réinitialisée.
  • noCredit signifie que le compte ne dispose d’aucun crédit de réinitialisation acquis.
  • Récupérez account/rateLimits/read après avoir utilisé une réinitialisation au lieu de déduire de cette réponse les fenêtres mises à jour.

9) Informer le propriétaire d’un espace de travail d’une limite

Utilisez account/sendAddCreditsNudgeEmail pour demander à ChatGPT d’envoyer un e-mail au propriétaire d’un espace de travail lorsque les crédits sont épuisés ou qu’une limite d’utilisation a été atteinte.

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

Utilisez creditType: "credits" lorsque les crédits de l’espace de travail sont épuisés, ou creditType: "usage_limit" lorsque la limite d’utilisation de l’espace de travail a été atteinte. Si le propriétaire a déjà été averti récemment, l’état de la réponse est cooldown_active.

10) Messages de l’espace de travail (ChatGPT)

Utilisez account/workspaceMessages/read pour récupérer les messages actifs de l’espace de travail actuel, notamment les titres des notifications lorsqu’ils sont 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 }
] } }