Files
llmx/codex-rs/app-server
Celia Chen 2e81f1900d [App-server] Add auth v2 doc & update codex mcp interface auth section (#6353)
Added doc for auth v2 endpoints. Updated the auth section in Codex MCP
interface doc too.
2025-11-07 08:17:19 -08:00
..

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 (apiKey or chatgpt).
  • account/login/completed (notify) — emitted when a login attempt finishes (success or error).
  • account/login/cancel — cancel a pending ChatGPT login by loginId.
  • account/logout — sign out; triggers account/updated.
  • account/updated (notify) — emitted whenever auth mode changes (authMode: apikey, chatgpt, or null).
  • account/rateLimits/read — fetch ChatGPT rate limits; updates arrive via account/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): set true to force a token refresh.
  • requiresOpenaiAuth reflects the active provider; when false, Codex can run without OpenAI credentials.

2) Log in with an API key

  1. Send:
    { "method": "account/login/start", "id": 2, "params": { "type": "apiKey", "apiKey": "sk-…" } }
    
  2. Expect:
    { "id": 2, "result": { "type": "apiKey" } }
    
  3. 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)

  1. 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" } }
    
  2. Open authUrl in a browser; the app-server hosts the local callback.
  3. 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:

  • usedPercent is current usage within the OpenAI quota window.
  • windowDurationMins is the quota window length.
  • resetsAt is a Unix timestamp (seconds) for the next reset.

Dev notes