codex
Research notes on OpenAI Codex's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
How it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Research notes on OpenAI Codex's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Agent definition
codex.mdCodex Research
Research notes on OpenAI Codex's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Overview
- **Provider**: OpenAI
- **Execution Method (this repo)**: Codex App Server (JSON-RPC over stdio)
- **Execution Method (alternatives)**: SDK (`@openai/codex-sdk`) or CLI binary
- **Session Persistence**: Thread ID (string)
- **Import**: Dynamic import to avoid bundling issues
- **Binary Location**: `~/.nvm/versions/node/current/bin/codex` (npm global install)
SDK Architecture
**The SDK wraps a bundled binary** - it does NOT make direct API calls.
- The TypeScript SDK includes a pre-compiled Codex binary
- When you use the SDK, it spawns this binary as a child process
- Communication happens via stdin/stdout using JSONL (JSON Lines) format
- The binary itself handles the actual communication with OpenAI's backend services
Sources: [Codex SDK docs](https://developers.openai.com/codex/sdk/), [GitHub](https://github.com/openai/codex)
CLI Usage (Alternative to App Server / SDK)
You can use the `codex` binary directly instead of the SDK:
Interactive Mode
codex "your prompt here"
codex --model o3 "your prompt"
Non-Interactive Mode (`codex exec`)
codex exec "your prompt here"
codex exec --json "your prompt" # JSONL output
codex exec -m o3 "your prompt"
codex exec --dangerously-bypass-approvals-and-sandbox "prompt"
codex exec resume --last # Resume previous session
Key CLI Flags
| Flag | Description | |------|-------------| | `--json` | Print events to stdout as JSONL | | `-m, --model MODEL` | Model to use | | `-s, --sandbox MODE` | `read-only`, `workspace-write`, `danger-full-access` | | `--full-auto` | Auto-approve with workspace-write sandbox | | `--dangerously-bypass-approvals-and-sandbox` | Skip all prompts (dangerous) | | `-C, --cd DIR` | Working directory | | `-o, --output-last-message FILE` | Write final response to file | | `--output-schema FILE` | JSON Schema for structured output |
Session Management
codex resume # Pick from previous sessions
codex resume --last # Resume most recent
codex fork --last # Fork most recent session
Credential Discovery
Priority Order
1. User-configured credentials (from `credentials` array) 2. Environment variable: `CODEX_API_KEY` 3. Environment variable: `OPENAI_API_KEY` 4. Bootstrap extraction from config files
Config File Location
| Path | Description | |------|-------------| | `~/.codex/auth.json` | Primary auth config |
Auth File Structure
// API Key authentication
{
"OPENAI_API_KEY": "sk-..."
}
// OAuth authentication
{
"tokens": {
"access_token": "..."
}
}SDK Usage
Client Initialization
import { Codex } from "@openai/codex-sdk";
// With API key
const codex = new Codex({ apiKey: "sk-..." });
// Without API key (uses default auth)
const codex = new Codex();Dynamic import is used to avoid bundling the SDK:
const { Codex } = await import("@openai/codex-sdk");Thread Management
// Start new thread
const thread = codex.startThread();
// Resume existing thread
const thread = codex.resumeThread(threadId);
Running Prompts
const { events } = await thread.runStreamed(prompt);
for await (const event of events) {
// Process events
}App Server Protocol (JSON-RPC)
Codex App Server uses JSON-RPC 2.0 over JSONL/stdin/stdout (no port required).
Key Requests
- `initialize` → returns server info
- `thread/start` → starts a new thread
- `turn/start` → sends user input for a thread
Event Notifications (examples)
{ "method": "thread/started", "params": { "thread": { "id": "thread_abc123" } } }
{ "method": "item/completed", "params": { "item": { "type": "agentMessage", "text": "..." } } }
{ "method": "turn/completed", "params": { "threadId": "thread_abc123", "turn": { "items": [] } } }Approval Requests (server → client)
The server can send JSON-RPC requests (with `id`) for approvals:
- `item/commandExecution/requestApproval`
- `item/fileChange/requestApproval`
These require JSON-RPC responses with a decision payload.
App Server WebSocket Transport (Experimental)
Codex app-server also supports an experimental WebSocket transport:
codex app-server --listen ws://127.0.0.1:4500
Transport constraints
- Listen URL must be `ws://IP:PORT` (not `localhost`, not `http://...`)
- One JSON-RPC message per WebSocket text frame
- Incoming: text frame JSON is parsed as a JSON-RPC message
- Outgoing: JSON-RPC messages are serialized and sent as text frames
- Ping/Pong is handled; binary frames are ignored
Connection lifecycle
- Each accepted socket becomes a distinct connection with its own session state
- Every connection must send `initialize` first
- Sending non-`initialize` requests before init returns `"Not initialized"`
- Sending `initialize` twice on the same connection returns `"Already initialized"`
- Broadcast notifications are only sent to initialized connections
Operational notes
- WebSocket mode is currently marked experimental/unsupported upstream
- It is a raw WS server (no built-in TLS/auth); keep it on loopback or place it behind your own secure proxy/tunnel
Upstream implementation references (openai/codex `main`, commit `03adb5db`)
- `codex-rs/app-server/src/transport.rs`
- `codex-rs/app-server/src/message_processor.rs`
- `codex-rs/app-server/README.md`
Response Schema
// CodexRunResultSchema
type CodexRunResult = string | {
result?: string;
output?: string;
message?: string;
// ...additional fields via passthrough
};Content is extracted in priority order: `result` > `output` > `message`
Thread ID Retrieval
Thread ID can be obtained from multiple sources:
1. `thread.started` event's `thread_id` property 2. Thread object's `id` getter (after first turn) 3. Thread object's `
Read more
Codex Research
Research notes on OpenAI Codex's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Overview
- **Provider**: OpenAI
- **Execution Method (this repo)**: Codex App Server (JSON-RPC over stdio)
- **Execution Method (alternatives)**: SDK (`@openai/codex-sdk`) or CLI binary
- **Session Persistence**: Thread ID (string)
- **Import**: Dynamic import to avoid bundling issues
- **Binary Location**: `~/.nvm/versions/node/current/bin/codex` (npm global install)
SDK Architecture
**The SDK wraps a bundled binary** - it does NOT make direct API calls.
- The TypeScript SDK includes a pre-compiled Codex binary
- When you use the SDK, it spawns this binary as a child process
- Communication happens via stdin/stdout using JSONL (JSON Lines) format
- The binary itself handles the actual communication with OpenAI's backend services
Sources: [Codex SDK docs](https://developers.openai.com/codex/sdk/), [GitHub](https://github.com/openai/codex)
CLI Usage (Alternative to App Server / SDK)
You can use the `codex` binary directly instead of the SDK:
Interactive Mode
codex "your prompt here" codex --model o3 "your prompt"
Non-Interactive Mode (`codex exec`)
codex exec "your prompt here" codex exec --json "your prompt" # JSONL output codex exec -m o3 "your prompt" codex exec --dangerously-bypass-approvals-and-sandbox "prompt" codex exec resume --last # Resume previous session
Key CLI Flags
| Flag | Description | |------|-------------| | `--json` | Print events to stdout as JSONL | | `-m, --model MODEL` | Model to use | | `-s, --sandbox MODE` | `read-only`, `workspace-write`, `danger-full-access` | | `--full-auto` | Auto-approve with workspace-write sandbox | | `--dangerously-bypass-approvals-and-sandbox` | Skip all prompts (dangerous) | | `-C, --cd DIR` | Working directory | | `-o, --output-last-message FILE` | Write final response to file | | `--output-schema FILE` | JSON Schema for structured output |
Session Management
codex resume # Pick from previous sessions codex resume --last # Resume most recent codex fork --last # Fork most recent session
Credential Discovery
Priority Order
1. User-configured credentials (from `credentials` array) 2. Environment variable: `CODEX_API_KEY` 3. Environment variable: `OPENAI_API_KEY` 4. Bootstrap extraction from config files
Config File Location
| Path | Description | |------|-------------| | `~/.codex/auth.json` | Primary auth config |
Auth File Structure
// API Key authentication
{
"OPENAI_API_KEY": "sk-..."
}
// OAuth authentication
{
"tokens": {
"access_token": "..."
}
}SDK Usage
Client Initialization
import { Codex } from "@openai/codex-sdk";
// With API key
const codex = new Codex({ apiKey: "sk-..." });
// Without API key (uses default auth)
const codex = new Codex();Dynamic import is used to avoid bundling the SDK:
const { Codex } = await import("@openai/codex-sdk");Thread Management
// Start new thread const thread = codex.startThread(); // Resume existing thread const thread = codex.resumeThread(threadId);
Running Prompts
const { events } = await thread.runStreamed(prompt);
for await (const event of events) {
// Process events
}App Server Protocol (JSON-RPC)
Codex App Server uses JSON-RPC 2.0 over JSONL/stdin/stdout (no port required).
Key Requests
- `initialize` → returns server info
- `thread/start` → starts a new thread
- `turn/start` → sends user input for a thread
Event Notifications (examples)
{ "method": "thread/started", "params": { "thread": { "id": "thread_abc123" } } }
{ "method": "item/completed", "params": { "item": { "type": "agentMessage", "text": "..." } } }
{ "method": "turn/completed", "params": { "threadId": "thread_abc123", "turn": { "items": [] } } }Approval Requests (server → client)
The server can send JSON-RPC requests (with `id`) for approvals:
- `item/commandExecution/requestApproval`
- `item/fileChange/requestApproval`
These require JSON-RPC responses with a decision payload.
App Server WebSocket Transport (Experimental)
Codex app-server also supports an experimental WebSocket transport:
codex app-server --listen ws://127.0.0.1:4500
Transport constraints
- Listen URL must be `ws://IP:PORT` (not `localhost`, not `http://...`)
- One JSON-RPC message per WebSocket text frame
- Incoming: text frame JSON is parsed as a JSON-RPC message
- Outgoing: JSON-RPC messages are serialized and sent as text frames
- Ping/Pong is handled; binary frames are ignored
Connection lifecycle
- Each accepted socket becomes a distinct connection with its own session state
- Every connection must send `initialize` first
- Sending non-`initialize` requests before init returns `"Not initialized"`
- Sending `initialize` twice on the same connection returns `"Already initialized"`
- Broadcast notifications are only sent to initialized connections
Operational notes
- WebSocket mode is currently marked experimental/unsupported upstream
- It is a raw WS server (no built-in TLS/auth); keep it on loopback or place it behind your own secure proxy/tunnel
Upstream implementation references (openai/codex `main`, commit `03adb5db`)
- `codex-rs/app-server/src/transport.rs`
- `codex-rs/app-server/src/message_processor.rs`
- `codex-rs/app-server/README.md`
Response Schema
// CodexRunResultSchema
type CodexRunResult = string | {
result?: string;
output?: string;
message?: string;
// ...additional fields via passthrough
};Content is extracted in priority order: `result` > `output` > `message`
Thread ID Retrieval
Thread ID can be obtained from multiple sources:
1. `thread.started` event's `thread_id` property 2. Thread object's `id` getter (after first turn) 3. Thread object's `
Run Coding Agents in Sandboxes. Control Them Over HTTP. Supports Claude Code, Codex, OpenCode, and Amp.
Repo: rivet-dev/sandbox-agent
Other agents on sandbox-agent.
- amp
Research notes on Sourcegraph Amp's configuration, credential discovery, and runtime behavior.
Open agent - openclaw
Research notes on OpenClaw's architecture, API, and automation patterns for integration with sandbox-agent.
Open agent - opencode
Research notes on OpenCode's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Open agent

