Skip to main content

Crate codex_codes

Crate codex_codes 

Source
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
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 buffering
  • protocol — 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 format
  • cli — Builder for spawning codex app-server --listen stdio://
  • error — Error types and result aliases
  • version — 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:

  1. Start a threadthread/start creates a conversation session
  2. Start a turnturn/start sends user input, triggering agent work
  3. Stream notifications — The server emits item/agentMessage/delta, item/commandExecution/outputDelta, etc. as the agent works
  4. Handle approvals — The server may send requests like item/commandExecution/requestApproval that require a response
  5. Turn completesturn/completed signals the agent is done
  6. Repeat — Send another turn/start for follow-up questions

§Feature Flags

FeatureDescriptionWASM-compatible
typesCore message types and protocol structs onlyYes
sync-clientSynchronous client with blocking I/ONo
async-clientAsynchronous client using tokioNo

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 deltas
  • sync_client.rs — Single-turn synchronous query
  • basic_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§

AgentMessageItem
An agent message item containing text output.
CommandExecutionItem
A command execution item — a shell command the agent ran.
ErrorItem
An error item.
FileChangeItem
A file change item representing one or more file modifications.
FileUpdateChange
A single file update within a file change item.
ItemCompletedEvent
Event indicating an item has completed.
ItemStartedEvent
Event indicating an item has started processing.
ItemUpdatedEvent
Event indicating an item has been updated.
McpToolCallError
Error from an MCP tool call.
McpToolCallItem
An MCP tool call item.
McpToolCallResult
Result of an MCP tool call.
ReasoningItem
A reasoning item containing the model’s chain-of-thought.
ThreadError
Error information from a thread.
ThreadErrorEvent
A thread-level error event.
ThreadOptions
Per-thread options controlling model, sandbox, and behavior.
ThreadStartedEvent
Event indicating a thread has started.
TodoItem
A single todo entry within a todo list.
TodoListItem
A todo list item.
TurnCompletedEvent
Event indicating a turn has completed successfully.
TurnFailedEvent
Event indicating a turn has failed.
TurnStartedEvent
Event indicating a turn has started.
Usage
Token usage statistics for a completed turn.
WebSearchItem
A web search item.

Enums§

ApprovalMode
Approval mode for tool execution.
CommandExecutionStatus
Status of a command execution within a CommandExecutionItem.
McpToolCallStatus
Status of an MCP tool call.
ModelReasoningEffort
Model reasoning effort level.
PatchApplyStatus
Status of a patch apply operation.
PatchChangeKind
Kind of patch change applied to a file.
SandboxMode
Sandbox mode controlling file system access.
ThreadEvent
All possible events emitted during a Codex exec-format thread execution.
ThreadItem
All possible thread item types emitted by the Codex CLI.
WebSearchMode
Web search mode.