Added doc for auth v2 endpoints. Updated the auth section in Codex MCP interface doc too.
codex-app-server
codex app-server is the harness Codex uses to power rich interfaces such as the Codex VS Code extension. The message schema is currently unstable, but those who wish to build experimental UIs on top of Codex may find it valuable.
Protocol
Similar to MCP, codex app-server supports bidirectional communication, streaming JSONL over stdio. The protocol is JSON-RPC 2.0, though the "jsonrpc":"2.0" header is omitted.
Message Schema
Currently, you can dump a TypeScript version of the schema using codex generate-ts. It is specific to the version of Codex you used to run generate-ts, so the two are guaranteed to be compatible.
codex generate-ts --out DIR
Auth endpoints (v2)
The v2 JSON-RPC auth/account surface exposes request/response methods plus server-initiated notifications (no id). Use these to determine auth state, start or cancel logins, logout, and inspect ChatGPT rate limits.
Quick reference
account/read— fetch current account info; optionally refresh tokens.account/login/start— begin login (apiKeyorchatgpt).account/login/completed(notify) — emitted when a login attempt finishes (success or error).account/login/cancel— cancel a pending ChatGPT login byloginId.account/logout— sign out; triggersaccount/updated.account/updated(notify) — emitted whenever auth mode changes (authMode:apikey,chatgpt, ornull).account/rateLimits/read— fetch ChatGPT rate limits; updates arrive viaaccount/rateLimits/updated(notify).
1) Check auth state
Request:
{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }
Response examples:
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } } // no auth needed
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } } // auth needed
{ "id": 1, "result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true } }
{ "id": 1, "result": { "account": { "type": "chatgpt", "email": "user@example.com", "planType": "pro" }, "requiresOpenaiAuth": true } }
Field notes:
refreshToken(bool): settrueto force a token refresh.requiresOpenaiAuthreflects the active provider; whenfalse, Codex can run without OpenAI credentials.
2) Log in with an API key
- Send:
{ "method": "account/login/start", "id": 2, "params": { "type": "apiKey", "apiKey": "sk-…" } } - Expect:
{ "id": 2, "result": { "type": "apiKey" } } - Notifications:
{ "method": "account/login/completed", "params": { "loginId": null, "success": true, "error": null } } { "method": "account/updated", "params": { "authMode": "apikey" } }
3) Log in with ChatGPT (browser flow)
- Start:
{ "method": "account/login/start", "id": 3, "params": { "type": "chatgpt" } } { "id": 3, "result": { "type": "chatgpt", "loginId": "<uuid>", "authUrl": "https://chatgpt.com/…&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback" } } - Open
authUrlin a browser; the app-server hosts the local callback. - Wait for notifications:
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": true, "error": null } } { "method": "account/updated", "params": { "authMode": "chatgpt" } }
4) Cancel a ChatGPT login
{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "…" } }
5) Logout
{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null } }
6) Rate limits (ChatGPT)
{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": { "rateLimits": { "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 }, "secondary": null } } }
{ "method": "account/rateLimits/updated", "params": { "rateLimits": { … } } }
Field notes:
usedPercentis current usage within the OpenAI quota window.windowDurationMinsis the quota window length.resetsAtis a Unix timestamp (seconds) for the next reset.
Dev notes
codex generate-ts --out <dir>emits v2 typings underv2/.- See “Authentication and authorization” in the config docs for configuration knobs.