Codex Architecture Index
Codex Architecture Index (Rust)
Section titled “Codex Architecture Index (Rust)”Pinned SHA: 4ab44e2c5cc54ed47e47a6729dfd8aa5a3dc2476
Overview
Section titled “Overview”Codex is a Rust-based CLI and TUI application. It features a client-server architecture (though often running in the same process) where the TUI orchestrates high-level state and the core engine handles agent logic, tool execution, and sandboxing. The workspace contains 40+ crates under codex-rs/, with the major ones being core, tui, cli, protocol, config, state, exec, hooks, file-search, linux-sandbox, exec-server, shell-command, apply-patch, login, rmcp-client, mcp-server, app-server, app-server-protocol, network-proxy, keyring-store, and ansi-escape.
Workspace Crate Map
Section titled “Workspace Crate Map”| Crate | Path | Purpose |
|---|---|---|
cli | codex-rs/cli/ | Main binary, clap argument parsing, subcommand dispatch |
tui | codex-rs/tui/ | Interactive ratatui terminal UI, widgets, overlays |
core | codex-rs/core/ | Agent engine, tool dispatch, sandboxing, MCP, skills, context management |
protocol | codex-rs/protocol/ | Shared protocol types: Op submissions, EventMsg events, ResponseItem |
config | codex-rs/config/ | Multi-layer TOML configuration with merge, overrides, requirements |
state | codex-rs/state/ | SQLite state persistence, tracing log DB, session metadata |
exec | codex-rs/exec/ | Non-interactive execution engine for CI/scripting |
hooks | codex-rs/hooks/ | Event-driven hook system (AfterAgent, AfterToolUse) |
file-search | codex-rs/file-search/ | Fuzzy file search with nucleo + ignore |
linux-sandbox | codex-rs/linux-sandbox/ | Linux sandboxing: bubblewrap + Landlock + seccomp |
exec-server | codex-rs/exec-server/ | MCP server for privilege escalation and shell interception |
shell-command | codex-rs/shell-command/ | Tree-sitter bash parsing and command safety checking |
apply-patch | codex-rs/apply-patch/ | Unified diff patch parsing and atomic file application |
login | codex-rs/login/ | Device code auth, PKCE, login server |
rmcp-client | codex-rs/rmcp-client/ | MCP client (stdio + streamable HTTP transports) |
mcp-server | codex-rs/mcp-server/ | Codex as an MCP server (stdio transport) |
app-server | codex-rs/app-server/ | IDE integration server (stdio/WebSocket) |
app-server-protocol | codex-rs/app-server-protocol/ | Typed JSON-RPC protocol for IDE integration (v1/v2) |
network-proxy | codex-rs/network-proxy/ | HTTP + SOCKS5 proxy for network sandboxing |
keyring-store | codex-rs/keyring-store/ | Platform-independent credential storage abstraction |
ansi-escape | codex-rs/ansi-escape/ | ANSI escape to ratatui styled text conversion |
windows-sandbox-rs | codex-rs/windows-sandbox-rs/ | Windows sandboxing (restricted token) |
execpolicy | codex-rs/execpolicy/ | Execution policy rules engine |
secrets | codex-rs/secrets/ | MCP OAuth credential storage (keyring + file fallback) |
cloud-tasks | codex-rs/cloud-tasks/ | Codex Cloud task management |
Core Call Paths
Section titled “Core Call Paths”1. Bootstrapping and CLI Entry (codex-rs/cli/src/main.rs)
Section titled “1. Bootstrapping and CLI Entry (codex-rs/cli/src/main.rs)”main()->arg0_dispatch_or_else()->cli_main().cli_main()parses subcommands usingclap.- If no subcommand, it calls
run_interactive_tui(). run_interactive_tui()performs terminal checks (refuses “dumb” terminals without TTY) and callscodex_tui::run_main().
2. TUI Orchestration (codex-rs/tui/src/lib.rs)
Section titled “2. TUI Orchestration (codex-rs/tui/src/lib.rs)”run_main():- Loads configuration via
ConfigBuilder. - Initializes
AuthManager. - Sets up tracing/logging to
codex-tui.log. - Handles
--ossprovider selection if needed. - Calls
run_ratatui_app().
- Loads configuration via
run_ratatui_app():- Initializes
ratatuiterminal. - Runs
update_prompt::run_update_prompt_if_needed(). - Runs
onboarding::run_onboarding_app()for first-run trust/login. - Manages session selection (Resume, Fork, or StartFresh).
- Resolves CWD, prompting the user if the session history CWD differs from current.
- Calls
App::run().
- Initializes
3. Application Loop and State (codex-rs/tui/src/app.rs)
Section titled “3. Application Loop and State (codex-rs/tui/src/app.rs)”App::run():- Multi-event loop using
tokio::select!. app_event_rx: Internal UI events (e.g.,NewSession,InsertHistoryCell).active_thread_rx: Events from the agent engine (e.g.,SessionConfigured,UserMessage,ShutdownComplete).tui_events: User input (Keys, Pastes, Resizes).
- Multi-event loop using
handle_tui_event(): Processes keyboard input, managesOverlay(full-screen views), and triggers draws.handle_event(): Logic for UI commands (e.g.,ForkCurrentSessioncallsserver.fork_thread).handle_active_thread_event(): Routes agent events to the UI and handles thread lifecycle/failover.
4. History and Context Management
Section titled “4. History and Context Management”transcript_cells: AVec<Arc<dyn HistoryCell>>inAppstoring the conversation history.HistoryCelltrait: Implemented byUserHistoryCell,AgentMessageCell,SessionInfoCell, etc.project_doc.rs: Hierarchical discovery ofAGENTS.mdfiles from git root down to CWD.environment_context.rs: Serializes CWD, Shell, and Network state into XML tags for the LLM.
Agent Engine (codex-rs/core/)
Section titled “Agent Engine (codex-rs/core/)”The core crate is the heart of Codex with around 191 source files implementing the agent loop, tool dispatch, sandboxing, MCP integration, skills, context management, and state persistence.
Agent Lifecycle
Section titled “Agent Lifecycle”CODEX SPAWN (codex.rs) 1. Create Session (Arc<Session>) 2. Spawn submission_loop task 3. Return Codex { tx_sub, rx_event, agent_status }
SUBMISSION LOOP (codex.rs:3196) Async channel receiver for Op enum submissions while let Ok(sub) = rx_sub.recv().await { match sub.op { Op::UserInput { items, .. } Op::UserTurn { .. } Op::ExecApproval { .. } Op::PatchApproval { .. } Op::Undo, Op::Compact, Op::Review { .. } Op::Shutdown => break } }
handlers::user_input_or_turn -> spawn_task (tasks/mod.rs) Create Arc<RegularTask> (or ReviewTask, etc.) Spawn on tokio::spawn with cancellation token
REGULAR TASK: run_turn() (tasks/regular.rs:100) 1. Create TurnContext 2. Initialize ContextManager (token budget) 3. Build prompt (user message + history) 4. Call ModelClientSession.stream() for agent response 5. Stream ResponseEvent::Delta (reasoning/content chunks) 6. For each ResponseItem (text/toolcall), emit events 7. TOOL DISPATCH LOOP 8. Final turn event (TurnComplete or Error)Key Structs
Section titled “Key Structs”Codex (codex.rs):
pub struct Codex { pub tx_sub: Sender<Submission>, // Input: operations pub rx_event: Receiver<Event>, // Output: protocol events pub agent_status: watch::Receiver<AgentStatus>,}Session (codex.rs):
pub struct Session { pub conversation_id: ThreadId, pub services: Arc<SessionServices>, pub state: Arc<Mutex<SessionState>>, tx_event: Sender<Event>, agent_status: watch::Sender<AgentStatus>,}SessionServices (state/service.rs):
pub struct SessionServices { pub auth_manager: Arc<AuthManager>, pub models_manager: Arc<ModelsManager>, pub otel_manager: OtelManager, pub tool_approvals: Arc<Mutex<ApprovalStore>>, pub mcp_manager: Arc<McpConnectionManager>, pub agent_control: AgentControl, pub skills_manager: Arc<SkillsManager>, pub file_watcher: Arc<FileWatcher>,}TurnContext (codex.rs):
pub struct TurnContext { pub sub_id: String, pub cwd: PathBuf, pub approval_policy: AskForApproval, pub sandbox_policy: SandboxPolicy, pub windows_sandbox_level: WindowsSandboxLevel, pub network: Option<NetworkProxy>, pub shell_environment_policy: ShellEnvironmentPolicy, pub otel_manager: OtelManager,}Task Types
Section titled “Task Types”pub enum TaskKind { Regular, // Main agent loop Review, // Code review task Compact, // Context compaction task GhostSnapshot, // Git snapshot task Undo, // Undo task UserShell, // User shell command}
// Via SessionTask trait:// fn kind() -> TaskKind;// async fn run(self: Arc<Self>, session, ctx, input, cancellation_token) -> Option<String>;// async fn abort(...);Tool Dispatch System (codex-rs/core/src/tools/)
Section titled “Tool Dispatch System (codex-rs/core/src/tools/)”Dispatch Flow
Section titled “Dispatch Flow”ResponseItem (from model) -> ToolRouter::build_tool_call Matches: FunctionCall, CustomToolCall, LocalShellCall Creates ToolCall { tool_name, call_id, payload: ToolPayload }
ToolRouter::dispatch_tool_call (tools/router.rs:143) Resolve handler from registry Create ToolInvocation (session, turn, call_id, payload) Call handler.handle(invocation) -> ToolOutput
ToolOrchestrator::run (tools/orchestrator.rs:102) Approval check (Skip / NeedsApproval / Forbidden) If NeedsApproval: emit ExecApprovalRequest, wait for Op::ExecApproval SandboxManager::select_initial() -> SandboxType ToolRuntime::run(req, attempt, tool_ctx) On sandbox denial: retry with SandboxType::None
Handler-specific runtimes (tools/runtimes/) ShellRuntime: unified_exec/process.rs ApplyPatchRuntime: apply_patch.rs
Emit ToolOutput -> add to ResponseInputItem[] -> return to modelTool Handler Trait
Section titled “Tool Handler Trait”pub trait ToolHandler: Send + Sync { fn kind(&self) -> ToolKind; // Function | Freeform fn matches_kind(&self, payload: &ToolPayload) -> bool; async fn is_mutating(&self, invocation: &ToolInvocation) -> bool; async fn handle(&self, invocation: ToolInvocation) -> Result<ToolOutput, FunctionCallError>;}Built-in Tool Handlers
Section titled “Built-in Tool Handlers”| Handler | Type | File | Purpose |
|---|---|---|---|
| ShellHandler | Function | tools/handlers/shell.rs | Raw shell commands |
| UnifiedExecHandler | Function | tools/handlers/unified_exec.rs | Interactive PTY processes |
| ApplyPatchHandler | Function/Freeform | tools/handlers/apply_patch.rs | File patching with diff-match-patch |
| ReadFileHandler | Function | tools/handlers/read_file.rs | File reading (with token truncation) |
| ListDirHandler | Function | tools/handlers/list_dir.rs | Directory listing (recursive option) |
| GrepFilesHandler | Function | tools/handlers/grep_files.rs | Text search in files |
| JsReplHandler | Function | tools/handlers/js_repl.rs | JavaScript evaluation |
| McpHandler | Function | tools/handlers/mcp.rs | MCP tool invocation |
| McpResourceHandler | Function | tools/handlers/mcp_resource.rs | MCP resource reading |
| MultiAgentHandler | Function | tools/handlers/multi_agents.rs | Spawn sub-agents |
| PlanHandler | Function | tools/handlers/plan.rs | Task planning |
| RequestUserInputHandler | Function | tools/handlers/request_user_input.rs | Prompt user for input |
| SearchToolBm25Handler | Function | tools/handlers/search_tool_bm25.rs | BM25 semantic search |
| DynamicToolHandler | Function | tools/handlers/dynamic.rs | User-defined dynamic tools |
| ViewImageHandler | Function | tools/handlers/view_image.rs | Display images |
ToolPayload Variants
Section titled “ToolPayload Variants”pub enum ToolPayload { Function { arguments: String }, // JSON-serialized args Custom { input: String }, // Free-form text Mcp { server, tool, raw_arguments }, // MCP server tool call LocalShell { params: ShellToolCallParams },}Approval and Execution Policy
Section titled “Approval and Execution Policy”enum ExecApprovalRequirement { Skip { bypass_sandbox, proposed_execpolicy_amendment }, NeedsApproval { reason, proposed_execpolicy_amendment }, Forbidden { reason },}
// Approval caching:// ApprovalStore: HashMap<serialized_key, ReviewDecision>// with_cached_approval() checks cache first, stores per unique key
enum ReviewDecision { Approved, ApprovedForSession, ApprovedExecpolicyAmendment { amendment }, Denied, Abort,}Interactive Shell (Unified Exec)
Section titled “Interactive Shell (Unified Exec)”UnifiedExecProcessManager: open_process(ExecCommandRequest) -> ProcessHandle Build CommandSpec -> SandboxManager::select_initial() Spawn PTY (via execute_exec_env) Create UnifiedExecProcess { id, handle, buffer } write_stdin(process_id, input) -> async stream close_process(process_id) -> output
HeadTailBuffer: Ring buffer with fixed max size (1 MiB default) Head pointer: first N bytes (for user context) Tail pointer: last N bytes (for recent output) Middle bytes: discarded with "[...truncated...]" markerContext Management and Token Budgeting (codex-rs/core/src/context_manager/)
Section titled “Context Management and Token Budgeting (codex-rs/core/src/context_manager/)”pub struct ContextManager { messages: Vec<ContentItem>, token_budget: u32, reserved_for_model_response: u32, history_start_index: usize, // Compaction boundary}
pub struct TotalTokenUsageBreakdown { pub input_tokens: u32, pub output_tokens: u32, pub reasoning_tokens: Option<u32>, // For reasoning models}Token Strategies:
estimate_response_item_model_visible_bytes()estimates token cost per itemformatted_truncate_text()truncates with[... truncated ...]markershould_use_remote_compact_task()decides remote compaction
Inline Compaction (compact.rs):
When context exceeds token_budget:
run_inline_auto_compact_task()identifies compactible turns- Summarizes via model call
- Replaces original turns with
CompactedTurnItem - Updates token budget and continues
Streaming and Event Flow
Section titled “Streaming and Event Flow”Event Channel Architecture
Section titled “Event Channel Architecture”Client -> Op::UserInput { items } submission_loop receives spawn_task(RegularTask) run_turn() starts TurnStartedEvent -> tx_event ModelClient.stream() ResponseEvent::Delta -> AgentMessageContentDeltaEvent -> ReasoningContentDeltaEvent ResponseItem (toolcall) -> ItemStartedEvent -> ExecCommand{Begin,End} -> PatchApply{Begin,End} -> ItemCompletedEvent Loop: tool outputs as input items TurnCompleteEvent -> tx_eventClient <- rx_event.next_event()Event Types (from codex-protocol)
Section titled “Event Types (from codex-protocol)”| Category | Events |
|---|---|
| Turn lifecycle | TurnStartedEvent, TurnCompleteEvent, TurnAbortedEvent |
| Content streaming | AgentMessageContentDeltaEvent, ReasoningContentDeltaEvent, ReasoningRawContentDeltaEvent |
| Tool execution | ItemStartedEvent, ItemCompletedEvent, ExecCommandBeginEvent, ExecCommandEndEvent |
| File patching | PatchApplyBeginEvent, PatchApplyEndEvent |
| Approval | ExecApprovalRequestEvent, PatchApprovalRequestEvent |
| Diagnostics | ErrorEvent, WarningEvent, DeprecationNoticeEvent |
| State | SessionConfigured, UserMessage, ShutdownComplete |
| Web search | WebSearchBeginEvent, WebSearchEndEvent |
| Context | ContextCompactedEvent |
Protocol Crate (codex-rs/protocol/)
Section titled “Protocol Crate (codex-rs/protocol/)”Defines the shared communication contract between all Codex components.
Submission Queue (Client to Server): Op enum
Section titled “Submission Queue (Client to Server): Op enum”| Variant | Purpose |
|---|---|
UserTurn | Primary interaction: items, cwd, approval_policy, sandbox_policy, model, reasoning config |
UserInput | Legacy input variant |
ExecApproval / PatchApproval | User approval responses |
ResolveElicitation | MCP server request resolution |
UserInputAnswer / DynamicToolResponse | Tool response payloads |
Interrupt | Abort current task |
Compact | Summarize conversation |
Undo / ThreadRollback | Undo operations |
Review | Code review request |
Shutdown | Terminate session |
ResponseItem Variants (models.rs)
Section titled “ResponseItem Variants (models.rs)”| Variant | Purpose |
|---|---|
Message | Text/image content with optional phase (commentary/final_answer) |
Reasoning | Extended thinking with summary and encrypted content |
LocalShellCall | Local command execution |
FunctionCall / FunctionCallOutput | Tool invocations and results |
CustomToolCall / CustomToolCallOutput | User-defined tools |
McpToolCall | Model Context Protocol calls |
WebSearchCall | Web search integration |
GhostSnapshot | Git commit snapshots |
Compaction | Context compression metadata |
Key Protocol Structs
Section titled “Key Protocol Structs”| Struct | Purpose |
|---|---|
Submission | Wraps Op with unique ID for request correlation |
Event | Server event wrapper with timestamp and session context |
UserInput enum | Text, Image, LocalImage, Skill, Mention variants |
ShellToolCallParams | Command params (command, workdir, timeout_ms, sandbox_permissions) |
FunctionCallOutputPayload | Flexible output: plain text OR structured content items (text/image) |
AskForApproval enum | Untrusted, OnFailure, OnRequest (default), Never |
SandboxPolicy enum | DangerFullAccess, ReadOnly, ExternalSandbox, WorkspaceWrite |
ReadOnlyAccess enum | Restricted (with readable_roots) or FullAccess |
MCP Protocol Types (mcp.rs)
Section titled “MCP Protocol Types (mcp.rs)”Tooldefines name, description, input_schema, output_schemaResourceprovides readable resource metadata (name, uri, size, mime_type)CallToolResultis the MCP tool response: content[], structured_content, is_error flagRequestIdis polymorphic: either String or i64
Configuration System (codex-rs/config/)
Section titled “Configuration System (codex-rs/config/)”Layer Stack Architecture
Section titled “Layer Stack Architecture”Configuration is loaded from multiple sources and merged with precedence ordering.
Precedence Order (Low to High):
- System default config
- Project configs (root to cwd, if multiple)
- User config (
~/.codex/config.toml) - Legacy managed config
- MDM-provided config
- CLI session flags (
-c key=value)
ConfigLayerStack (state.rs):
pub struct ConfigLayerStack { layers: Vec<ConfigLayerEntry>, // Ordered low-to-high precedence user_layer_index: Option<usize>, // Tracks single user layer requirements: ConfigRequirements, // Constraints on merged config requirements_toml: Option<String>, // Preserves original allow-lists}
pub struct ConfigLayerEntry { name: ConfigLayerSource, // Mdm, System, User, Project, SessionFlags config: TomlValue, // Raw TOML config raw_toml: Option<String>, // Preserves original TOML text version: String, // Fingerprint for tracking disabled_reason: Option<String>, // Why layer is disabled}Key Operations:
merge_toml_values(base, overlay)does recursive TOML merge; overlay winsbuild_cli_overrides_layer(overrides)constructs layer from-c key=valueargseffective_config()merges all non-disabled layers in precedence orderorigins()maps each config key to its source layer metadata
Configuration Constraints (config_requirements.rs)
Section titled “Configuration Constraints (config_requirements.rs)”SandboxModeRequirementrestricts allowed sandbox modesNetworkConstraintsenforces network access policyResidencyRequirementenforces data residencyWebSearchModeRequirementcontrols web search enable/disableMcpServerRequirementrequires/forbids specific MCP servers
File Paths
Section titled “File Paths”- System:
/etc/codex/config.toml(Linux),~/Library/Application Support/Codex(macOS) - User:
~/.codex/config.toml - Project:
.codex/config.toml(scanned up directory tree)
State Persistence (codex-rs/state/)
Section titled “State Persistence (codex-rs/state/)”SQLite Database
Section titled “SQLite Database”Location: ~/.codex/state/state.sqlite
LogEntry (model/log.rs):
pub struct LogEntry { ts: i64, // Unix timestamp (seconds) ts_nanos: i64, // Nanosecond precision level: String, // TRACE, DEBUG, INFO, WARN, ERROR target: String, // Logger target (crate name) message: Option<String>, thread_id: Option<String>, process_uuid: Option<String>, // pid:uuid format module_path: Option<String>, file: Option<String>, line: Option<i64>,}StateRuntime (runtime.rs):
- Manages SQLite connection and log/metadata operations
insert_logs(entries)does batch insert of tracing eventsdelete_logs_before(cutoff_ts)does retention cleanup (90 days)- Metadata queries for thread information
LogDbLayer (log_db.rs):
- Implements
tracing_subscriber::Layerfor automatic log capture - Buffered: MPSC channel (capacity: 512)
- Batch inserts: batch size 64, flush interval 250ms
- Automatic cleanup of logs older than 90 days
- Captures
thread_idfield from tracing spans
Database Constants:
STATE_DB_VERSION = 5LOG_RETENTION_DAYS = 90LOG_BATCH_SIZE = 64LOG_FLUSH_INTERVAL = 250msLOG_QUEUE_CAPACITY = 512
Session Rollouts
Section titled “Session Rollouts”Session history stored as line-delimited JSON (JSONL) files. Backfill system processes rollouts for extraction:
BackfillStatetracks JSONL rollout processing stateBackfillStatusis in progress / complete / failedStage1JobClaim,Stage1Outputhandle job orchestration
Hooks System (codex-rs/hooks/)
Section titled “Hooks System (codex-rs/hooks/)”Hook Events
Section titled “Hook Events”| Event Type | Trigger | Data |
|---|---|---|
AfterAgent | Agent response complete | thread_id, turn_id, input_messages[], last_assistant_message |
AfterToolUse | Tool execution done | turn_id, call_id, tool_name, tool_kind, tool_input, executed, success, duration_ms, mutating, sandbox, sandbox_policy, output_preview |
Hook Architecture
Section titled “Hook Architecture”pub struct Hooks { after_agent: Vec<Hook>, after_tool_use: Vec<Hook>,}
pub struct HookPayload { session_id: ThreadId, cwd: PathBuf, triggered_at: DateTime<Utc>, // RFC3339 timestamp hook_event: HookEvent, // Tagged union of event types}Execution Model:
- Hooks run sequentially via async
HookFnfunctions - Results:
Success,FailedContinue(error, keep going),FailedAbort(error, stop pipeline) - Legacy support:
legacy_notify_argvconverted toAfterAgenthook for backward compatibility - Hooks receive JSON payload and can trigger external actions
Hook Tool Kinds
Section titled “Hook Tool Kinds”enum HookToolKind { Function, // Built-in function calls Custom, // Custom tool implementations LocalShell, // Shell command execution Mcp, // Model Context Protocol tools}Non-Interactive Execution (codex-rs/exec/)
Section titled “Non-Interactive Execution (codex-rs/exec/)”Architecture
Section titled “Architecture”Entry point parses CLI args, initializes config, spawns ThreadManager, and processes events.
Main Loop (main.rs:544-600):
- Submit initial operation (
UserTurnorReview) - Spawn thread listener tasks for all created threads
- Receive events from unbounded MPSC channel
- Route to
EventProcessor::process_event() - Handle shutdown signals and errors
EventProcessor Trait:
trait EventProcessor { fn print_config_summary(&mut self, config, prompt, session_configured); fn process_event(&mut self, event) -> CodexStatus; fn print_final_output(&mut self);}
enum CodexStatus { Running, // Continue processing events InitiateShutdown, // Gracefully shut down Shutdown, // Shutdown complete, exit}Output Modes:
EventProcessorWithJsonOutputemits JSONL (one event per line), for automationEventProcessorWithHumanOutputrenders human-readable with ANSI color codes
Approval in Non-Interactive Mode:
- Default policy:
AskForApproval::Never - Elicitation requests automatically cancelled
--full-autoforcesSandboxMode::WorkspaceWrite--dangerously-bypass-approvals-and-sandboxforces full access
Sandboxing and Security
Section titled “Sandboxing and Security”Platform Sandboxes
Section titled “Platform Sandboxes”| Platform | Sandbox Type | Implementation |
|---|---|---|
| Linux | Bubblewrap + Landlock + seccomp | codex-rs/linux-sandbox/ |
| macOS | Seatbelt (sandbox profiles) | core/src/seatbelt.rs |
| Windows | Restricted token / VM isolation | codex-rs/windows-sandbox-rs/ |
Linux Sandbox (codex-rs/linux-sandbox/)
Section titled “Linux Sandbox (codex-rs/linux-sandbox/)”Two-stage sandboxing: bubblewrap first, then seccomp.
Key files:
linux_run_main.rs(458 lines) is the main orchestrator, handlesPR_SET_NO_NEW_PRIVS, preflight/procmount testing, container environment detectionbwrap.rs(372 lines) does bubblewrap filesystem setup: read-only-by-default root with writable roots, symlink attack mitigation via/dev/nullbinding, network namespace isolationlandlock.rs(238 lines) installs Landlock filesystem rules (read-only root + writable paths) + seccomp filtervendored_bwrap.rs(71 lines) is an FFI wrapper to C bubblewrap binary (bwrap_main())
Seccomp Filter (blocked syscalls):
connect,accept,bind,listen,getpeername,setsockoptptrace,io_uring_*- All sockets blocked except
AF_UNIXdomain sockets
BwrapNetworkMode:
FullAccesshas no network restrictionIsolateddoes full network namespace isolationProxyOnlyroutes through network proxy
Sandboxing Flow:
- Parse
SandboxPolicy(read/write access, network access) - If restricting filesystem: wrap with bubblewrap (read-only root + selective writable binds)
- Apply
PR_SET_NO_NEW_PRIVSif needed - Install seccomp filter (denies network syscalls)
execvpinto target command
Sandbox Transform (core/src/sandboxing/mod.rs)
Section titled “Sandbox Transform (core/src/sandboxing/mod.rs)”CommandSpec { program, args, cwd, env, sandbox_permissions, justification} ->SandboxManager::transform(SandboxTransformRequest { spec, policy, sandbox: SandboxType, enforce_managed_network, network, sandbox_policy_cwd, ...}) ->ExecRequest { command, cwd, env, network, sandbox: SandboxType, sandbox_permissions, justification, arg0}Exec Server and Privilege Escalation (codex-rs/exec-server/)
Section titled “Exec Server and Privilege Escalation (codex-rs/exec-server/)”MCP server implementing privilege escalation policy for shell command execution with interception.
Privilege Escalation Flow
Section titled “Privilege Escalation Flow”TUI calls shell_tool MCP Server spawns Bash (with escalate socket FD) Patched Bash attempts exec() exec() wrapper sends EscalateRequest to MCP server MCP evaluates policy + heuristics -> decision Run: child execs directly Escalate: receive FDs, exec with elevated permissions Deny: return error to childKey Types
Section titled “Key Types”struct EscalateRequest { file: PathBuf, argv: Vec<String>, workdir: PathBuf, env: HashMap<String, String>,}
enum EscalateAction { Run, Escalate, Deny { reason: Option<String> },}Socket I/O (posix/socket.rs, 507 lines)
Section titled “Socket I/O (posix/socket.rs, 507 lines)”AsyncSocketis a stream-based socket with length-prefixed framesAsyncDatagramSocketis a datagram socket with FD support- Uses SCM_RIGHTS (Unix FD passing) via control messages, max 16 FDs per message
- Built on
socket2+tokio::io::AsyncFd
Shell Command Safety (codex-rs/shell-command/)
Section titled “Shell Command Safety (codex-rs/shell-command/)”Tree-sitter based bash parsing and command safety checking.
Parsing Strategy
Section titled “Parsing Strategy”bash.rs (577 lines) uses tree-sitter to parse bash scripts and extract only safe command patterns:
try_parse_shell()parses bash script into tree-sitter Treetry_parse_word_only_commands_sequence()extracts simple commands (no redirections, substitutions, etc.)parse_shell_lc_plain_commands()parsesbash -c "cmd1 && cmd2 | cmd3"sequences
Allowed operators: &&, ||, ;, |
Rejected constructs: $(), backticks, >, <, (), {}, variable expansions
Safety Strategy:
- Build allowed node kinds whitelist
- Walk tree depth-first, reject disallowed nodes
- Allow only specific punctuation operators
- Extract command words from safe patterns only
AST Node Types Used: program, list, pipeline, command, command_name, word, string, raw_string, number, concatenation
Command Safety Lists
Section titled “Command Safety Lists”is_dangerous_command.rshas a heuristic list of dangerous commands (rm, mkfs, dd, etc.)is_safe_command.rshas an allowlist of safe commandswindows_dangerous_commands.rs/windows_safe_commands.rshave Windows-specific lists
Patch Application (codex-rs/apply-patch/)
Section titled “Patch Application (codex-rs/apply-patch/)”Patch Format
Section titled “Patch Format”Uses a custom patch format (*** Begin Patch / *** End Patch) parsed into hunks:
enum Hunk { AddFile { path: PathBuf, contents: String }, DeleteFile { path: PathBuf }, UpdateFile { path: PathBuf, move_path: Option<PathBuf>, chunks: Vec<UpdateFileChunk> },}
struct UpdateFileChunk { change_context: Option<String>, // line to seek to old_lines: Vec<String>, new_lines: Vec<String>, is_end_of_file: bool,}Application Flow
Section titled “Application Flow”parse_patch()parses patch into hunks- For each
UpdateFilehunk: read original file, seek context line per chunk, matchold_lines, compute replacement - Apply replacements in reverse order (preserve indices)
- Write new file atomically
- Create/delete files as needed
unified_diff_from_chunks()generates unified diff output usingsimilar::TextDiff
File Search (codex-rs/file-search/)
Section titled “File Search (codex-rs/file-search/)”Architecture
Section titled “Architecture”Two-threaded system using nucleo fuzzy matcher:
struct FileSearchSession { inner: Arc<SessionInner> }
struct FileSearchOptions { pub limit: NonZero<usize>, pub exclude: Vec<String>, pub threads: NonZero<usize>, pub compute_indices: bool, pub respect_gitignore: bool,}
struct FileMatch { pub score: u32, pub path: PathBuf, pub root: PathBuf, pub indices: Option<Vec<u32>>, // matched character positions}
trait SessionReporter: Send + Sync { fn on_update(&self, snapshot: &FileSearchSnapshot); fn on_complete(&self);}Search Flow
Section titled “Search Flow”create_session() spawn walker_worker() Uses ignore::WalkBuilder (.gitignore support) Injects files into nucleo matcher
spawn matcher_worker() Consumes signals: QueryUpdated, NucleoNotify, WalkComplete, Shutdown Debounces results (10ms tick) Invokes reporter.on_update() for streaming results Invokes reporter.on_complete() when done
update_query() Matcher re-parses pattern and emits updatesMCP Integration
Section titled “MCP Integration”MCP Client (codex-rs/rmcp-client/)
Section titled “MCP Client (codex-rs/rmcp-client/)”pub struct RmcpClient { ... }
impl RmcpClient { pub async fn new_stdio_client(...) -> Self; // Spawn stdio subprocess pub async fn new_streamable_http_client(...) -> Self; // HTTP transport pub async fn initialize(...); // MCP handshake pub async fn list_tools(...) -> Vec<Tool>; pub async fn list_tools_with_connector_ids(...); pub async fn list_resources(...) -> Vec<Resource>; pub async fn list_resource_templates(...) -> Vec<ResourceTemplate>; pub async fn read_resource(...) -> ReadResourceResult; pub async fn call_tool(...) -> CallToolResult; pub async fn send_custom_notification(...); pub async fn send_custom_request(...);}MCP Connection Manager (core/src/mcp_connection_manager.rs)
Section titled “MCP Connection Manager (core/src/mcp_connection_manager.rs)”pub struct McpConnectionManager { clients: HashMap<String, Arc<RmcpClient>>, // One per configured server tools_cache: HashMap<String, Tool>, // Aggregated tools // Tool names: "<server>__<tool_name>" (double underscore delimiter)}MCP Tool Handler (core/src/tools/handlers/mcp.rs)
Section titled “MCP Tool Handler (core/src/tools/handlers/mcp.rs)”- Parse fully-qualified name:
"my_server__get_weather"becomes (server:"my_server", tool:"get_weather") - Look up
RmcpClientfor server - Call
client.call_tool(tool_name, args) - Handle elicitation (OAuth, prompts)
- Return
CallToolResult { content, is_error }
MCP Server (codex-rs/mcp-server/)
Section titled “MCP Server (codex-rs/mcp-server/)”Runs Codex itself as an MCP server via stdio transport. Allows other tools to call Codex as a tool provider.
MCP OAuth Credentials (codex-rs/secrets/)
Section titled “MCP OAuth Credentials (codex-rs/secrets/)”pub struct StoredOAuthTokens { pub server_name: String, pub url: String, pub client_id: String, pub token_response: WrappedOAuthTokenResponse, pub expires_at: Option<u64>,}
pub enum OAuthCredentialsStoreMode { Auto, // Keyring when available; otherwise File File, // ~/.codex/.credentials.json Keyring, // Keyring only, fail if unavailable}Uses OS keyring (macOS Keychain, Windows Credential Manager, Linux DBus Secret Service) with file fallback.
Authentication (codex-rs/login/)
Section titled “Authentication (codex-rs/login/)”Public API
Section titled “Public API”// Core auth flows:pub use device_code_auth::DeviceCode;pub use device_code_auth::complete_device_code_login;pub use device_code_auth::request_device_code;pub use device_code_auth::run_device_code_login;pub use server::LoginServer;pub use server::ServerOptions;pub use server::run_login_server;
// Re-exported from codex-core:pub use codex_core::AuthManager;pub use codex_core::CodexAuth;pub use codex_core::auth::AuthDotJson;pub use codex_core::auth::CLIENT_ID;pub use codex_core::auth::CODEX_API_KEY_ENV_VAR;pub use codex_core::auth::OPENAI_API_KEY_ENV_VAR;pub use codex_core::auth::login_with_api_key;pub use codex_core::auth::logout;pub use codex_core::auth::save_auth;Supports device code flow, PKCE, API key via stdin, and a local login server for OAuth callbacks.
Keyring Store (codex-rs/keyring-store/)
Section titled “Keyring Store (codex-rs/keyring-store/)”pub trait KeyringStore: Debug + Send + Sync { fn load(&self, service: &str, account: &str) -> Result<Option<String>, CredentialStoreError>; fn save(&self, service: &str, account: &str, value: &str) -> Result<(), CredentialStoreError>; fn delete(&self, service: &str, account: &str) -> Result<bool, CredentialStoreError>;}
pub struct DefaultKeyringStore; // Uses platform-native keyringPlatform Support:
- Linux:
keyring::linux-native-async-persistent(keyutils + async-secret-service) - macOS:
keyring::apple-native - Windows:
keyring::windows-native - FreeBSD/OpenBSD:
keyring::sync-secret-service - Fallback:
keyring::crypto-rust(software encryption)
Network Proxy (codex-rs/network-proxy/)
Section titled “Network Proxy (codex-rs/network-proxy/)”HTTP + SOCKS5 proxy for network sandboxing within the sandbox environment.
pub struct NetworkProxyBuilder { state: Option<Arc<NetworkProxyState>>, http_addr: Option<SocketAddr>, socks_addr: Option<SocketAddr>, admin_addr: Option<SocketAddr>, managed_by_codex: bool, policy_decider: Option<Arc<dyn NetworkPolicyDecider>>, blocked_request_observer: Option<Arc<dyn BlockedRequestObserver>>,}Components:
- HTTP proxy (
http_proxy.rs) does transparent HTTP/HTTPS proxying - SOCKS5 proxy (
socks5.rs) implements SOCKS5 protocol for TCP tunneling - Admin server (
admin.rs) provides management and metrics endpoint - Network policy (
network_policy.rs) definesNetworkPolicyDecidertrait for allow/deny decisions - Per-attempt proxy usernames for tracking (
metadata.rs)
App Server and IDE Integration
Section titled “App Server and IDE Integration”App Server (codex-rs/app-server/)
Section titled “App Server (codex-rs/app-server/)”Typed protocol for IDE integrations (VSCode extension confirmed).
Transports:
stdio://(default) for subprocess communicationws://IP:PORTfor WebSocket networked integrations
Generated bindings:
codex app-server generate-tsgenerates TypeScript bindingscodex app-server generate-json-schemagenerates JSON Schema
App Server Protocol (codex-rs/app-server-protocol/)
Section titled “App Server Protocol (codex-rs/app-server-protocol/)”Versioned protocol: v1 and v2 modules with shared common types.
Key Types:
pub enum AuthMode { ApiKey, // OpenAI API key stored by Codex Chatgpt, // ChatGPT OAuth managed by Codex ChatgptAuthTokens, // External host-supplied tokens (unstable)}
// Uses macro-generated ClientRequest enum with tagged JSON-RPC:// Each variant has params + response types// Supports experimental feature gating per-methodProtocol generates: TypeScript types via ts-rs, JSON Schema via schemars.
Skill System (codex-rs/core/src/skills/)
Section titled “Skill System (codex-rs/core/src/skills/)”SkillsManager
Section titled “SkillsManager”pub struct SkillsManager { skills_path: PathBuf, cache: HashMap<PathBuf, SkillMetadata>,}
// Loading:pub fn skills_for_config(&self, config: &Config) -> SkillLoadOutcome { skills: Vec<SkillMetadata>, errors: Vec<SkillError>, allowed_skills: HashSet<PathBuf>,}
// Format: <skills_dir>/<skill_name>/codex.tomlSkill Injection (skills/injection.rs)
Section titled “Skill Injection (skills/injection.rs)”- Parse
codex.toml:[tool.X]sections become tool definitions,[env]sections define env var requirements - Inject into prompt: tool specs go to
ToolsConfig, env vars go toTurnContext.env - Tool mentions (contextual injection): if user asks for “X skill”, inject it. Collected via
mentions.rs: collect_explicit_skill_mentions()
Multi-Agent Spawning (codex-rs/core/src/agent/control.rs)
Section titled “Multi-Agent Spawning (codex-rs/core/src/agent/control.rs)”pub struct AgentControl { manager: Weak<ThreadManagerState>, // Global agent registry state: Arc<Guards>, // Spawn depth guards}
pub async fn spawn_agent(&self, config: Config, items: Vec<UserInput>) -> CodexResult<ThreadId>{ 1. Check spawn depth limits (MAX_THREAD_SPAWN_DEPTH = 8) 2. Call ThreadManager::spawn_new_thread() 3. Submit initial items via send_input() 4. Return new ThreadId}Multi-agent handler (tools/handlers/multi_agents.rs) spawns sub-agents from parent, waits for completion with timeout, returns output to parent.
ANSI Escape (codex-rs/ansi-escape/)
Section titled “ANSI Escape (codex-rs/ansi-escape/)”Converts ANSI escape sequences to ratatui styled text:
pub fn ansi_escape_line(s: &str) -> Line<'static>pub fn ansi_escape(s: &str) -> Text<'static>Uses ansi_to_tui crate. Expands tabs to 4 spaces. Handles parsing errors with logging.
TUI Widgets and Overlays (codex-rs/tui/)
Section titled “TUI Widgets and Overlays (codex-rs/tui/)”Widget Hierarchy
Section titled “Widget Hierarchy”| Widget | File | Purpose |
|---|---|---|
App | app.rs | Main application loop and event orchestration |
ChatWidget | chatwidget/ | Primary UI for agent conversation display |
BottomPane | bottom_pane/ | Input area, command palette, overlays |
ExecCell | exec_cell/ | Command execution and output rendering |
DiffRender | diff_render.rs | Visual diff display |
MarkdownRender | markdown_render.rs | Code block and text rendering |
FileSearch | file_search.rs | Integrated fuzzy search UI |
Overlays
Section titled “Overlays”Full-screen views managed by handle_tui_event() in App. Overlays replace the main view temporarily (e.g., file search, help, settings).
Feature Flags (codex-rs/core/src/features.rs)
Section titled “Feature Flags (codex-rs/core/src/features.rs)”50+ feature toggles with stage metadata (alpha/beta/stable). Examples include:
ApplyPatchFreeformfor freeform patch applicationCollabfor collaborative featuresJsReplfor JavaScript REPL tool- Feature flags controlled via
codex features list/enable/disableor-c features.<name>=true/false
Error Handling
Section titled “Error Handling”pub enum CodexErr { Fatal(String), UserCancelled, InternalAgentDied, SandboxErr(SandboxErr), ExecErr(ExecErr), ApprovalErr(String), // ... 20+ variants}
pub type CodexResult<T> = Result<T, CodexErr>;
pub enum FunctionCallError { RespondToModel(String), // Error to send back to model Rejected(String), // Tool rejected (user/policy)}Core Dependencies
Section titled “Core Dependencies”| Category | Crates |
|---|---|
| Async | tokio (multi-thread), async-channel, futures |
| Sandboxing | landlock, seccompiler (Linux), seatbelt (macOS) |
| TUI | ratatui, crossterm |
| Parsing | tree-sitter (bash), similar (diffs), askama (templates) |
| Serialization | serde, serde_json, serde_yaml, toml, toml_edit |
| Networking | reqwest, tokio-tungstenite (WebSocket), http |
| Security | keyring, sha1, sha2, base64 |
| Search | nucleo (fuzzy), bm25 (semantic), ignore (walk), regex-lite |
| File ops | notify (watcher), tempfile, zip |
| Identity | uuid (v4/v5), chrono, time |
| Utilities | which, wildmatch, shlex |
| Codegen | ts-rs (TypeScript), schemars (JSON Schema) |
Architectural Patterns
Section titled “Architectural Patterns”- Event-Driven UI: TUI state updates are almost entirely driven by events (internal or from the engine).
- Asynchronous Engine: The agent engine runs in separate tasks/threads, communicating via
async_channelbounded/unbounded channels. - Arc<Mutex/RwLock> Pattern: Session is
Arc<Session>shared across tasks, state behindArc<Mutex<SessionState>>, all tool contexts takeArc<Session>andArc<TurnContext>. - Hierarchical Config: Configuration loaded from multiple layers (system, project, user, CLI) with recursive TOML merge.
- Graceful Failover: If an agent thread dies unexpectedly, the TUI attempts to fail back to the primary thread.
- Progressive Disclosure (Skills): Skills listed in context, full content only loaded when triggered.
- Approval Caching:
ApprovalStore(HashMap<serialized_key, ReviewDecision>) withwith_cached_approval()checking cache first. - Sandbox Retry: Initial attempt with selected
SandboxType; on denial, retry withSandboxType::Noneusing cached approval. - Parallel Tool Execution:
ToolCallRuntimewith lock guard: read lock (shared) for parallel, write lock (exclusive) for serial. - Task-Based Turns: Each turn is a
SessionTaskspawned ontokio::spawnwithCancellationToken.
Key Modules and Files (Complete)
Section titled “Key Modules and Files (Complete)”| Path | Purpose |
|---|---|
codex-rs/cli/src/main.rs | Main entry point and subcommand parsing |
codex-rs/tui/src/lib.rs | TUI bootstrapper and terminal initialization |
codex-rs/tui/src/app.rs | Main application loop and event orchestration |
codex-rs/tui/src/chatwidget/ | Primary UI component for chat interface |
codex-rs/core/src/codex.rs | Codex struct, Session, submission_loop, TurnContext |
codex-rs/core/src/codex_thread.rs | CodexThread public wrapper around Codex |
codex-rs/core/src/tools/router.rs | ToolRouter dispatches tool calls to handlers |
codex-rs/core/src/tools/orchestrator.rs | ToolOrchestrator: approval, sandbox, run, retry |
codex-rs/core/src/tools/handlers/ | All built-in tool handler implementations |
codex-rs/core/src/sandboxing/mod.rs | Sandbox selection and CommandSpec to ExecRequest transform |
codex-rs/core/src/context_manager/history.rs | ContextManager for token budgeting and compaction |
codex-rs/core/src/compact.rs | Inline context compaction |
codex-rs/core/src/mcp_connection_manager.rs | McpConnectionManager for MCP server lifecycle |
codex-rs/core/src/skills/manager.rs | SkillsManager for TOML skill loading |
codex-rs/core/src/agent/control.rs | AgentControl for sub-agent spawning (depth limit 8) |
codex-rs/core/src/unified_exec/ | Interactive shell: PTY management + HeadTailBuffer |
codex-rs/core/src/project_doc.rs | AGENTS.md hierarchical loading |
codex-rs/core/src/environment_context.rs | LLM context serialization (XML) |
codex-rs/core/src/features.rs | Feature flags (50+ toggles) |
codex-rs/core/src/error.rs | CodexErr, CodexResult |
codex-rs/protocol/src/protocol.rs | Op submissions, EventMsg events |
codex-rs/protocol/src/models.rs | ResponseItem variants |
codex-rs/protocol/src/mcp.rs | MCP protocol types |
codex-rs/config/src/state.rs | ConfigLayerStack multi-layer config |
codex-rs/config/src/merge.rs | Recursive TOML merge |
codex-rs/state/src/log_db.rs | LogDbLayer tracing to SQLite |
codex-rs/state/src/runtime.rs | StateRuntime SQLite operations |
codex-rs/exec/src/main.rs | Non-interactive execution entry point |
codex-rs/hooks/src/types.rs | HookPayload, HookEvent, HookResult |
codex-rs/hooks/src/registry.rs | Hooks registry and dispatch |
codex-rs/file-search/src/lib.rs | Fuzzy file search engine (nucleo) |
codex-rs/linux-sandbox/src/linux_run_main.rs | Linux sandbox orchestrator |
codex-rs/linux-sandbox/src/bwrap.rs | Bubblewrap filesystem setup |
codex-rs/linux-sandbox/src/landlock.rs | Landlock + seccomp filtering |
codex-rs/exec-server/src/lib.rs | Exec policy evaluation |
codex-rs/exec-server/src/posix/escalate_server.rs | Privilege escalation server |
codex-rs/exec-server/src/posix/socket.rs | FD-passing socket I/O |
codex-rs/shell-command/src/bash.rs | Tree-sitter bash parsing |
codex-rs/apply-patch/src/lib.rs | Patch parsing and application |
codex-rs/rmcp-client/src/rmcp_client.rs | MCP client (stdio + HTTP) |
codex-rs/login/src/lib.rs | Auth flows (device code, PKCE) |
codex-rs/secrets/src/lib.rs | MCP OAuth credential storage |
codex-rs/keyring-store/src/lib.rs | Platform keyring abstraction |
codex-rs/network-proxy/src/lib.rs | HTTP+SOCKS5 proxy builder |
codex-rs/app-server-protocol/src/protocol/common.rs | IDE protocol types (v1/v2) |
codex-rs/ansi-escape/src/lib.rs | ANSI to ratatui conversion |
CLI Surface (Full Command Tree)
Section titled “CLI Surface (Full Command Tree)”Captured live from codex --help and all subcommands. The Codex CLI is parsed by clap in codex-rs/cli/src/main.rs.
Global Options (present on most commands)
Section titled “Global Options (present on most commands)”-c, --config <key=value>overrides any~/.codex/config.tomlkey at runtime using TOML dotted paths. E.g.-c model="gpt-5.2-codex"or-c 'sandbox_permissions=["disk-full-read-access"]'. Raw string fallback if TOML parse fails.--enable / --disable <FEATURE>toggles feature flags without editing config. Equivalent to-c features.<name>=true/false.-i, --image <FILE>...attaches one or more images to the initial prompt. Multimodal input.-m, --model <MODEL>sets model identifier.--ossis a convenience flag for local OSS provider (LM Studio or Ollama). Verifies server is running before starting.--local-provider lmstudio|ollamadisambiguates when using--oss.-p, --profile <CONFIG_PROFILE>selects named config profile fromconfig.toml.-s, --sandbox <SANDBOX_MODE>setsread-only|workspace-write|danger-full-access. Enforced at kernel level (Landlock on Linux, Seatbelt on macOS, restricted token on Windows).-a, --ask-for-approvalsetsuntrusted|on-failure|on-request|never. Controls when human approval gates shell execution.--full-autois an alias for-a on-request --sandbox workspace-write. Common CI/automation preset.--dangerously-bypass-approvals-and-sandboxdisables prompts and sandbox. For externally-sandboxed environments (CI containers).-C, --cd <DIR>sets agent working root. Does not change process CWD; tells the agent where to scope operations.--searchenables live web search via the native Responsesweb_searchtool.--add-dir <DIR>adds additional directories writable alongside primary workspace.--no-alt-screendisables alternate screen buffer; runs TUI inline. Required for Zellij and other multiplexers that follow strict xterm spec.
Top-Level Commands
Section titled “Top-Level Commands”| Command | Purpose |
|---|---|
codex [PROMPT] | Launch interactive TUI. Default. Prompt is optional. |
codex exec [PROMPT] | Non-interactive agent run (scripting/CI). |
codex review [PROMPT] | Code review non-interactively. |
codex resume [SESSION_ID] | Resume previous interactive session (picker or --last). |
codex fork [SESSION_ID] | Fork previous session (picker or --last). |
codex apply <TASK_ID> | Apply latest Codex agent diff as git apply to local working tree. |
codex login | Manage API credentials. |
codex logout | Remove stored credentials. |
codex mcp | MCP server management (experimental). |
codex mcp-server | Run Codex itself as an MCP server (stdio transport). |
codex app-server | App server for IDE integrations (experimental). |
codex sandbox | Run arbitrary commands inside the Codex sandbox (test/debug isolation). |
codex completion [SHELL] | Shell completion scripts (bash/elvish/fish/powershell/zsh). |
codex debug | Debugging tools. |
codex cloud | Codex Cloud task management (experimental). |
codex features | Inspect and toggle feature flags. |
codex exec (Non-Interactive Mode)
Section titled “codex exec (Non-Interactive Mode)”codex exec [PROMPT] [COMMAND] --skip-git-repo-check allow running outside a git repo --ephemeral don't persist session files to disk --output-schema <FILE> JSON Schema for structured final response --color always|never|auto colorize output --json emit events as JSONL (machine-readable) -o, --output-last-message write last agent message to a fileSubcommands:
codex exec resumeresumes a previous session non-interactively.codex exec reviewruns code review non-interactively.
The --json flag emits the same event stream the TUI consumes as JSONL. The --output-schema flag forces structured JSON output from the model via a JSON Schema constraint, revealing that Codex supports structured output mode.
codex review (Code Review Mode)
Section titled “codex review (Code Review Mode)”codex review [PROMPT] --uncommitted review staged + unstaged + untracked changes --base <BRANCH> review changes against a base branch --commit <SHA> review changes introduced by a specific commit --title <TITLE> commit title shown in review summaryStandalone review mode built into the CLI, not a tool call. Three distinct scopes: uncommitted changes, branch diff, or single commit.
codex resume / codex fork
Section titled “codex resume / codex fork”Both share the full global options plus:
--lastskips picker, uses most recent session.--alldisables CWD filtering, shows all sessions with CWD column.
Fork semantics: creates a new session branching from a prior session’s state. Distinct from resume (which continues in place).
codex mcp (MCP Management, Experimental)
Section titled “codex mcp (MCP Management, Experimental)”codex mcp listcodex mcp getcodex mcp addcodex mcp removecodex mcp login # OAuth for MCP serverscodex mcp logoutcodex mcp-server (Codex as MCP Server)
Section titled “codex mcp-server (Codex as MCP Server)”Runs Codex itself as an MCP server via stdio transport. Allows other tools to call Codex as a tool provider.
codex app-server (App Server / IDE Integration)
Section titled “codex app-server (App Server / IDE Integration)”codex app-server --listen <URL> stdio:// (default) | ws://IP:PORT --analytics-default-enabled opt-in for first-party integrations (e.g. VSCode extension)Subcommands:
codex app-server generate-tsgenerates TypeScript bindings for the app server protocol.codex app-server generate-json-schemagenerates JSON Schema for the app server protocol.
Reveals that Codex exposes a typed protocol for IDE integrations (VSCode extension confirmed by --analytics-default-enabled flag docs).
codex sandbox (Sandbox Testing)
Section titled “codex sandbox (Sandbox Testing)”codex sandbox macos (alias: seatbelt) # macOS Seatbeltcodex sandbox linux (alias: landlock) # Linux Landlock+seccompcodex sandbox windows # Windows restricted tokenAllows running arbitrary commands inside Codex’s own sandbox layer. Useful for verifying isolation behavior.
codex login
Section titled “codex login”codex login --with-api-key read API key from stdin --device-auth device flowSubcommand: codex login status shows current login state.
codex cloud (Codex Cloud, Experimental)
Section titled “codex cloud (Codex Cloud, Experimental)”codex cloud exec # submit new cloud task without TUIcodex cloud status # show status of cloud taskcodex cloud list # list cloud taskscodex cloud apply # apply cloud task diff locallycodex cloud diff # show unified diff for a cloud taskcodex apply <TASK_ID> at top level also applies cloud diffs as git apply.
codex features (Feature Flag Inspection)
Section titled “codex features (Feature Flag Inspection)”codex features list # list all known features with stage + effective statecodex features enable # enable in config.tomlcodex features disable # disable in config.tomlFeature flags have a “stage” (alpha/beta/stable) and can be toggled per-user without code changes. Exposes that Codex has a formal feature gate system.