This document provides an overview of the user-facing interfaces that allow interaction with the Codex agent system. It covers the three primary interface modes (TUI, exec, app-server), their architectural relationships, and how they connect to the core agent implementation. For detailed implementation of specific interfaces, see:
For the underlying core agent system that these interfaces connect to, see Core Agent System.
The Codex CLI provides multiple user-facing interfaces that all funnel through the same core agent implementation (codex-core), but differ in interaction patterns and event processing.
Interface Modes:
| Mode | Entry Point | Use Case | Interactive | Event Processing |
|---|---|---|---|---|
| TUI | codex (no subcommand) | Primary interactive chat | Yes | ChatWidget + BottomPane |
| Exec | codex exec | Scripting, CI/CD | No | EventProcessorWithHumanOutput or JSONL |
| App Server | codex app-server | IDE extensions (VS Code) | Via client | JSON-RPC v2 protocol |
| MCP Server | codex mcp serve | External MCP clients | Via client | MCP protocol |
All modes spawn a codex_core::Codex instance, submit Op messages, and consume Event streams, but differ in how they present events to users and handle input.
Interface Layer Architecture
Sources: codex-rs/cli/src/main.rs1-800 codex-rs/tui/src/lib.rs131-400 codex-rs/exec/src/lib.rs1-800 codex-rs/core/src/codex.rs272-467 codex-rs/app-server/src/codex_message_processor.rs1-200
The TUI is the primary interactive interface, launched when running codex with no subcommand. It provides a full-screen terminal chat UI with streaming output, real-time tool execution feedback, and rich input handling.
Core Components:
App (tui/src/app.rs): Top-level event loop that coordinates TUI rendering, input events, and agent communicationChatWidget (tui/src/chatwidget.rs): Main conversation surface that consumes protocol events and maintains transcript stateBottomPane (tui/src/bottom_pane/mod.rs): Input layer containing ChatComposer for text editing and popup views for interactionsHistoryCell (tui/src/history_cell.rs): Trait-based abstraction for different transcript entry types (user messages, agent responses, tool calls, etc.)Event Flow in TUI:
Sources: codex-rs/tui/src/app.rs1-1000 codex-rs/tui/src/chatwidget.rs1-500 codex-rs/tui/src/bottom_pane/mod.rs1-300
The TUI maintains two layers of state:
HistoryCell entries stored in AppChatWidget that updates during streamingThe transcript overlay (Ctrl+T) renders committed cells plus a cached "live tail" from the active cell, with cache invalidation based on active_cell_revision (tui/src/chatwidget.rs521-529).
Input Handling:
The BottomPane routes keys to either the ChatComposer (for text editing) or the active popup view (for selection lists, approvals, etc.). The ChatComposer maintains a TextArea with support for:
Sources: codex-rs/tui/src/bottom_pane/chat_composer.rs1-200 codex-rs/tui/src/bottom_pane/mod.rs1-100
For detailed TUI implementation, see Terminal User Interface.
Exec mode (codex exec) provides a non-interactive, scriptable interface for one-shot agent invocations. It auto-submits a prompt, processes the agent's work, and exits with the final output.
Entry Point and Event Processing:
Sources: codex-rs/exec/src/lib.rs1-800 codex-rs/exec/src/event_processor_with_human_output.rs1-300 codex-rs/exec/src/event_processor_with_jsonl_output.rs1-200
Event Processors:
Exec mode implements two event processing strategies:
EventProcessorWithHumanOutput (exec/src/event_processor_with_human_output.rs): Default mode that writes structured output to stderr and only the final message to stdoutEventProcessorWithJsonlOutput (exec/src/event_processor_with_jsonl_output.rs): JSONL mode (--json) that emits one JSON event per line to stdoutBoth processors auto-cancel elicitations (approval requests) since there is no interactive user to respond.
Key Differences from TUI:
| Aspect | TUI | Exec |
|---|---|---|
| Interaction | Interactive (user can approve/steer) | Non-interactive (auto-cancels elicitations) |
| Output | Real-time streaming in terminal UI | Final output on stdout |
| History | Maintained across session | Single-turn execution |
| Approvals | User prompted via overlay | Auto-cancelled or auto-approved with --full-auto |
Sources: codex-rs/exec/src/lib.rs1-800 codex-rs/exec/src/event_processor.rs1-300
For detailed exec mode implementation, see Headless Execution Mode.
The CLI entry point (cli/src/main.rs) implements a multitool pattern where the binary name (codex, codex-exec, etc.) or subcommand determines behavior.
Multitool Dispatch Structure:
Sources: codex-rs/cli/src/main.rs1-800
Arg0 Dispatch:
The arg0_dispatch_or_else() function (codex-arg0/src/lib.rs) enables symlink-based invocation:
codex-exec, dispatches to exec modecodex-app-server, dispatches to app serverMultitoolCli with explicit subcommandsConfig Overrides and Feature Toggles:
The CLI layer handles configuration overrides (-c key=value) and feature flag application before spawning interface implementations. This includes:
--model, --oss)--sandbox-mode, --approval-policy, --full-auto)--search)--cwd)Sources: codex-rs/cli/src/main.rs100-500 codex-rs/tui/src/lib.rs131-300
For detailed CLI implementation, see CLI Entry Points and Multitool Dispatch.
The app server (codex app-server) implements a JSON-RPC 2.0 protocol over stdio or WebSocket, enabling rich IDE integrations like the VS Code extension.
Protocol Architecture:
Sources: codex-rs/app-server/src/codex_message_processor.rs1-500 codex-rs/app-server/src/bespoke_event_handling.rs1-300 codex-rs/app-server/src/thread_status.rs1-200
Request-Response Pattern:
The app server implements a bidirectional protocol where:
ClientRequest messages (with RequestId) invoke operationsServerNotification messages broadcast state changesClientResponse messages answer server-initiated requests (approvals, input)Core Request Categories:
| Category | Example Methods | Purpose |
|---|---|---|
thread/* | thread/start, thread/resume, thread/fork, thread/archive | Thread lifecycle management |
turn/* | turn/start, turn/steer, turn/interrupt | Turn operations within a thread |
account/* | account/login, account/logout, account/get | Authentication and account management |
config/* | config/user/get, config/user/set | Configuration reading and writing |
mcp/* | mcp/server/oauth/login, mcp/server/refresh | MCP server management and authentication |
Event Translation:
The bespoke_event_handling module (app-server/src/bespoke_event_handling.rs) translates between core Event messages and protocol-v2 notifications. Key state machines:
ThreadWatchManager: Tracks thread-level status (idle, active, waiting) and emits thread/statusChanged notificationsThreadStateManager: Maintains per-turn ephemeral state for approvals, elicitations, and streaming itemsProtocol Versioning:
The app server supports two protocol versions:
Protocol v2 is defined in app-server-protocol/src/protocol/v2.rs with TypeScript type generation.
Sources: codex-rs/app-server/src/codex_message_processor.rs1-1000 codex-rs/app-server/src/bespoke_event_handling.rs1-1500 codex-rs/app-server-protocol/src/protocol/v2.rs1-500
For detailed app server implementation, see App Server and IDE Integration.
All interface modes support session resumption (continuing a previous conversation) and forking (creating a new thread that branches from an existing one).
Thread Identification:
Threads are identified by:
Resumption Flow:
Sources: codex-rs/core/src/rollout/mod.rs1-500 codex-rs/core/src/thread_manager.rs1-800 codex-rs/tui/src/resume_picker.rs1-300
Forking:
Forking creates a new thread that inherits conversation history up to a specific turn. Implementations:
thread/fork request with optional messages to include (app-server/src/codex_message_processor.rs2000-2200)Forked threads reference their parent via forked_from_id in the session metadata, enabling "Thread forked from X" history cells.
Sources: codex-rs/core/src/thread_manager.rs400-600 codex-rs/tui/src/chatwidget.rs2000-2100
| Feature | TUI | Exec | App Server |
|---|---|---|---|
| Interaction Model | Synchronous (user in loop) | Asynchronous (fire and forget) | Bidirectional (request/response + notifications) |
| Approval Handling | User-prompted overlay | Auto-cancelled (or --full-auto) | Client-prompted via ServerRequest |
| Streaming Output | Real-time character-by-character | Buffered until completion | Per-item notifications |
| History Display | Transcript with HistoryCell trait | Final output only | Client-side rendering |
| Session Persistence | Full rollout with extended history | Limited rollout (no extended events) | Configurable per-thread |
| Config Editing | In-app pickers and overlays | CLI flags only | config/* API methods |
| Thread Switching | Resume picker (Ctrl+R) | --resume flag or resume command | thread/resume request |
| Multi-Threading | Single active thread | Single thread per invocation | Multiple concurrent threads |
Sources: codex-rs/tui/src/app.rs1-1000 codex-rs/exec/src/lib.rs1-800 codex-rs/app-server/src/codex_message_processor.rs1-2000
Refresh this wiki