# API
```rust
use std::path::Path;
use serde_json::Value;
pub const MODEL: &str;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NotificationKind {
Continue,
Usage,
TurnCompleted,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Error { /* private fields */ }
impl std::fmt::Display for Error;
impl std::error::Error for Error;
pub fn app_server_command(
executable: &Path,
working_directory: &Path,
) -> tokio::process::Command;
pub fn initialize_params(version: &str) -> Value;
pub fn thread_start_params(
working_directory: &Path,
tool_name: String,
tool_description: String,
input_schema: Value,
) -> Value;
pub fn turn_start_params(thread_id: &str, input: String) -> Value;
pub fn tool_success_result() -> Value;
pub fn classify_notification(
method: &str,
params: &Value,
thread_id: &str,
turn_id: &str,
) -> std::result::Result<NotificationKind, Error>;
```
All operations perform no I/O, retain no mutable state, and may proceed independently. `app_server_command` only constructs a command with the Codex app-server arguments, current directory, disabled capabilities, and removed API-key environment variables; the caller decides whether to spawn it.
The request builders preserve supplied tool metadata, schema, and input in their corresponding JSON values. `turn_start_params` places the input unchanged in its sole text item.
`classify_notification` accepts the documented events plus otherwise unrecognized `thread/`, `turn/`, and `item/` methods when their required scope is valid; an included item is also validated. It identifies token-usage and completed-turn events and rejects rerouting, disabled capabilities, methods outside the accepted families, mismatched identifiers, malformed turn or item objects, unsupported item types, missing token usage, and non-completed turns. Error text is diagnostic, not a stable matching interface.
Builder work and peak allocation are linear in the supplied strings and JSON trees. Classification work is linear in the method length and inspected JSON path depth and allocates only on error. The reference canary `cargo test --release --test protocol local_canary` classifies 100,000 representative 1 KiB notifications in under one second on stable Rust, Linux x86-64, four 3.0 GHz-or-faster cores, and 8 GiB RAM; debug builds use five seconds.