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-codesSee examples/async_client.rs and examples/sync_client.rs for runnable
versions of the usage patterns below. The high-level shape:
let mut client = AsyncClient::start().await?;
let thread = client
.thread_start(&serde_json::from_value(serde_json::json!({}))?)
.await?;
client.turn_start(&TurnStartParams {
thread_id: thread.thread.id.clone(),
input: vec![UserInput::Text {
text: "What is 2 + 2?".into(),
text_elements: None,
}],
// All other fields default to None — populate when overriding
// model / approval / sandbox / etc. for this turn.
..serde_json::from_value(serde_json::json!({"threadId": thread.thread.id, "input": []}))?
}).await?;§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:
- Initialize —
initialize+initializedhandshake (handled automatically bystart()) - 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.128", 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.130.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 io::events::ItemCompletedEvent;pub use io::events::ItemStartedEvent;pub use io::events::ItemUpdatedEvent;pub use io::events::ThreadError;pub use io::events::ThreadErrorEvent;pub use io::events::ThreadEvent;pub use io::events::ThreadStartedEvent;pub use io::events::TurnCompletedEvent;pub use io::events::TurnFailedEvent;pub use io::events::TurnStartedEvent;pub use io::events::Usage;pub use error::Error;pub use error::ParseError;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 messages::Notification;pub use messages::ServerMessage;pub use messages::ServerRequest;pub use cli::AppServerBuilder;pub use client_sync::EventIterator;pub use client_sync::SyncClient;pub use client_async::AsyncClient;pub use client_async::EventStream;pub use protocol::*;
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.
- io
- jsonrpc
- JSON-RPC message types for the Codex app-server protocol.
- messages
- Typed dispatch for app-server notifications and server-to-client requests.
- protocol
- App-server protocol types for the Codex CLI.
- protocol_
generated - version
- Version checking utilities for Codex CLI compatibility.