Expand description
A typed Rust interface for the OpenAI Codex CLI protocol.
This crate provides type-safe bindings for communicating with the Codex CLI’s app-server via its JSON-RPC protocol. It handles message framing, request/response correlation, approval flows, and streaming notifications for multi-turn agent conversations.
§Quick Start
cargo add codex-codes§Using the Async Client (Recommended)
use codex_codes::{AsyncClient, ThreadStartParams, TurnStartParams, UserInput, ServerMessage};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Start the app-server (spawns `codex app-server --listen stdio://`)
let mut client = AsyncClient::start().await?;
// Create a thread (a conversation session)
let thread = client.thread_start(&ThreadStartParams::default()).await?;
// Send a turn (a user message that triggers an agent response)
client.turn_start(&TurnStartParams {
thread_id: thread.thread_id.clone(),
input: vec![UserInput::Text { text: "What is 2 + 2?".into() }],
model: None,
reasoning_effort: None,
sandbox_policy: None,
}).await?;
// Stream notifications until the turn completes
while let Some(msg) = client.next_message().await? {
match msg {
ServerMessage::Notification { method, params } => {
if method == "turn/completed" { break; }
}
ServerMessage::Request { id, .. } => {
// Approval request — auto-accept for this example
client.respond(id, &serde_json::json!({"decision": "accept"})).await?;
}
}
}
client.shutdown().await?;
Ok(())
}§Using the Sync Client
use codex_codes::{SyncClient, ThreadStartParams, TurnStartParams, UserInput, ServerMessage};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = SyncClient::start()?;
let thread = client.thread_start(&ThreadStartParams::default())?;
client.turn_start(&TurnStartParams {
thread_id: thread.thread_id.clone(),
input: vec![UserInput::Text { text: "What is 2 + 2?".into() }],
model: None,
reasoning_effort: None,
sandbox_policy: None,
})?;
for result in client.events() {
match result? {
ServerMessage::Notification { method, .. } => {
if method == "turn/completed" { break; }
}
_ => {}
}
}
Ok(())
}§Architecture
The crate is organized into several key modules:
client_async/client_sync— High-level clients that manage the app-server process, request/response correlation, and message bufferingprotocol— App-server v2 request params, response types, and notification bodies (thread/turn lifecycle, approvals, deltas)jsonrpc— Low-level JSON-RPC message types (request, response, error, notification) matching the app-server’s wire formatcli— Builder for spawningcodex app-server --listen stdio://error— Error types and result aliasesversion— Version compatibility checking against the installed CLI
§Protocol Overview
The Codex app-server communicates via newline-delimited JSON-RPC 2.0 over stdio
(without the standard "jsonrpc":"2.0" field). The conversation lifecycle is:
- Start a thread —
thread/startcreates a conversation session - Start a turn —
turn/startsends user input, triggering agent work - Stream notifications — The server emits
item/agentMessage/delta,item/commandExecution/outputDelta, etc. as the agent works - Handle approvals — The server may send requests like
item/commandExecution/requestApprovalthat require a response - Turn completes —
turn/completedsignals the agent is done - Repeat — Send another
turn/startfor follow-up questions
§Feature Flags
| Feature | Description | WASM-compatible |
|---|---|---|
types | Core message types and protocol structs only | Yes |
sync-client | Synchronous client with blocking I/O | No |
async-client | Asynchronous client using tokio | No |
All features are enabled by default. For WASM or type-sharing use cases:
[dependencies]
codex-codes = { version = "0.100", default-features = false, features = ["types"] }§Version Compatibility
The Codex CLI protocol is evolving. This crate automatically checks your installed CLI version and warns if it’s newer than tested. Current tested version: 0.104.0
Report compatibility issues at: https://github.com/meawoppl/rust-code-agent-sdks/issues
§Examples
See the examples/ directory for complete working examples:
async_client.rs— Single-turn async query with streaming deltassync_client.rs— Single-turn synchronous querybasic_repl.rs— Interactive REPL with multi-turn conversation and approval handling
§Parsing Raw Protocol Messages
use codex_codes::{ThreadEvent, ThreadItem, JsonRpcMessage};
// Parse exec-format JSONL events
let json = r#"{"type":"thread.started","thread_id":"th_abc"}"#;
let event: ThreadEvent = serde_json::from_str(json).unwrap();
// Parse app-server JSON-RPC messages
let rpc = r#"{"id":1,"result":{"threadId":"th_abc"}}"#;
let msg: JsonRpcMessage = serde_json::from_str(rpc).unwrap();Re-exports§
pub use error::Error;pub use error::Result;pub use jsonrpc::JsonRpcError;pub use jsonrpc::JsonRpcErrorData;pub use jsonrpc::JsonRpcMessage;pub use jsonrpc::JsonRpcNotification;pub use jsonrpc::JsonRpcRequest;pub use jsonrpc::JsonRpcResponse;pub use jsonrpc::RequestId;pub use protocol::AgentMessageDeltaNotification;pub use protocol::CmdOutputDeltaNotification;pub use protocol::CommandApprovalDecision;pub use protocol::CommandExecutionApprovalParams;pub use protocol::CommandExecutionApprovalResponse;pub use protocol::ErrorNotification;pub use protocol::FileChangeApprovalDecision;pub use protocol::FileChangeApprovalParams;pub use protocol::FileChangeApprovalResponse;pub use protocol::FileChangeOutputDeltaNotification;pub use protocol::ItemCompletedNotification;pub use protocol::ItemStartedNotification;pub use protocol::ReasoningDeltaNotification;pub use protocol::ServerMessage;pub use protocol::ThreadArchiveParams;pub use protocol::ThreadArchiveResponse;pub use protocol::ThreadStartParams;pub use protocol::ThreadStartResponse;pub use protocol::ThreadStartedNotification;pub use protocol::ThreadStatus;pub use protocol::ThreadStatusChangedNotification;pub use protocol::ThreadTokenUsageUpdatedNotification;pub use protocol::TokenUsage;pub use protocol::Turn;pub use protocol::TurnCompletedNotification;pub use protocol::TurnError;pub use protocol::TurnInterruptParams;pub use protocol::TurnInterruptResponse;pub use protocol::TurnStartParams;pub use protocol::TurnStartResponse;pub use protocol::TurnStartedNotification;pub use protocol::TurnStatus;pub use protocol::UserInput;pub use cli::AppServerBuilder;pub use client_sync::EventIterator;pub use client_sync::SyncClient;pub use client_async::AsyncClient;pub use client_async::EventStream;
Modules§
- cli
- Builder for launching the Codex app-server process.
- client_
async - Asynchronous multi-turn client for the Codex app-server.
- client_
sync - Synchronous multi-turn client for the Codex app-server.
- error
- Error types for the codex-codes crate.
- jsonrpc
- JSON-RPC message types for the Codex app-server protocol.
- protocol
- App-server v2 protocol types for the Codex CLI.
- version
- Version checking utilities for Codex CLI compatibility.
Structs§
- Agent
Message Item - An agent message item containing text output.
- Command
Execution Item - A command execution item — a shell command the agent ran.
- Error
Item - An error item.
- File
Change Item - A file change item representing one or more file modifications.
- File
Update Change - A single file update within a file change item.
- Item
Completed Event - Event indicating an item has completed.
- Item
Started Event - Event indicating an item has started processing.
- Item
Updated Event - Event indicating an item has been updated.
- McpTool
Call Error - Error from an MCP tool call.
- McpTool
Call Item - An MCP tool call item.
- McpTool
Call Result - Result of an MCP tool call.
- Reasoning
Item - A reasoning item containing the model’s chain-of-thought.
- Thread
Error - Error information from a thread.
- Thread
Error Event - A thread-level error event.
- Thread
Options - Per-thread options controlling model, sandbox, and behavior.
- Thread
Started Event - Event indicating a thread has started.
- Todo
Item - A single todo entry within a todo list.
- Todo
List Item - A todo list item.
- Turn
Completed Event - Event indicating a turn has completed successfully.
- Turn
Failed Event - Event indicating a turn has failed.
- Turn
Started Event - Event indicating a turn has started.
- Usage
- Token usage statistics for a completed turn.
- WebSearch
Item - A web search item.
Enums§
- Approval
Mode - Approval mode for tool execution.
- Command
Execution Status - Status of a command execution within a
CommandExecutionItem. - McpTool
Call Status - Status of an MCP tool call.
- Model
Reasoning Effort - Model reasoning effort level.
- Patch
Apply Status - Status of a patch apply operation.
- Patch
Change Kind - Kind of patch change applied to a file.
- Sandbox
Mode - Sandbox mode controlling file system access.
- Thread
Event - All possible events emitted during a Codex exec-format thread execution.
- Thread
Item - All possible thread item types emitted by the Codex CLI.
- WebSearch
Mode - Web search mode.