Skip to content

Codex App Remote Capability Matrix

Codex App connects to a remote host via the normal Codex Remote SSH app-server flow, while agent turns are routed to Claude Code. Default runtime is the Claude Agent SDK sidecar; runtime selection is pluggable. Status legend: Supported, Experimental, Stub, Unsupported, N/A.

Core

AreaStatusNotes
Remote transportSupportedSSH starts codex app-server --listen unix:// + proxy; the shim reports a Codex-compatible version/user agent.
Thread lifecycleSupportedstart/resume/fork/archive/list/read + turn listing, backed by SQLite + Claude session ids.
Normal chatSupportedturn/start streams Claude text/reasoning into Codex agentMessage/reasoning items.
Steering / interruptSupportedturn/steer and turn/interrupt route to the active Claude client.
Token usageSupportedSDK ResultMessage usage → TokenUsageBreakdown, pushed as thread/tokenUsage/updated (cumulative + last turn).

Runtime selection

BackendStatusNotes
Selection mechanismSupportedCLAUDE_CODEX_RUNTIME_TYPE picks native codex passthrough (shim) or adapter runtimes. Switch with claude-codex-mode on the host and reconnect.
agent-sdk-sidecar (default)SupportedIn-process Claude Agent SDK; full tool/permission/reasoning events.
agent-http / ChannelsExperimentalConsumes POST /message, `GET /messages
agentapiExperimentalSame HTTP/SSE client against coder/agentapi; terminal-derived text only, no structured tool events.
claude-pExperimentalclaude-p --output-format json --input-file ... per turn; final transcript result only, not streaming, no turn/steer.

Models & turns

AreaStatusNotes
Model mappingSupportedNative Claude aliases pass through; unknown Codex/OpenAI ids fall back to the default model. App model/effort selections are remembered and echoed via config/read.
Reasoning effortBest effortCodex efforts normalized, mappable via CLAUDE_CODEX_EFFORT_ALIASES; older SDKs may ignore unsupported options.
Structured title/summary turnsSupported (fallback)Codex internal model ids (e.g. gpt-5.4-mini) map to CLAUDE_CODEX_SUMMARY_MODEL (default haiku) when an outputSchema is present; falls back to schema-shaped JSON if Claude emits plain text.
SDK option compatibilitySupportedWhen an older SDK rejects an option, the sidecar drops it one at a time (least essential first) and emits an info notice.

Tools, approvals & events

AreaStatusNotes
Claude Code toolsSupportedNot restricted by default; set CLAUDE_CODEX_ALLOWED_TOOLS to restrict.
Approval policy / sandboxSupportedApp's approvalPolicy + sandbox persist on the thread and map to Claude permission_mode. "Full access" drops the can_use_tool callback; read-only restricts tools to read/search.
Bash approvalSupportedcan_use_tool → Codex item/commandExecution/requestApproval. Bypassed when approvalPolicy=never / Full access.
File edit approvalSupportedEdit/Write/MultiEdit → Codex fileChange items with approval + diff updates.
Bash outputSupportedForwarded as command output on completion (SDK has no incremental tool-output streaming).
Generic Claude toolsSupportedNon-command/file tools → mcpToolCall items under the claude-code pseudo server.
Subagent (Task)SupportedTask spawns an ephemeral child thread and emits Codex's native 3-stage timeline (spawnAgentwaitcloseAgent); inner events are hidden, the final result lands as one agentMessage on the child thread.
Ephemeral / threadSourceSupportedephemeral: true threads (title-gen, memory-consolidation, subagents) persist but are excluded from thread/list unless includeEphemeral: true. threadSource round-trips.
Claude side eventsSupportedrate_limit / hook / subagent / compaction events summarized into structured notice lines.
Review modeSupported (text)review/start creates an in-progress review turn and routes the prompt through Claude. No native guardian finding items.
Context compactionSupported (summary)thread/compact/start routes the summary prompt and emits contextCompaction items. No native persisted rollout compaction.

Utilities

AreaStatusNotes
MCP config/status/toolsSupportedReads Claude MCP config, passes servers into turns, calls stdio/HTTP tools directly. mcpServerStatus/list enumerates real tools/resources/resourceTemplates per server (10s cache, graceful empty fallback on spawn/timeout).
Turn-item pagingSupportedthread/turns/list honors itemsViewsummary (default: first userMessage + final agentMessage), full, and notLoaded — instead of always shipping every item.
Skills & hooksSupportedskills/list reads .claude/skills/*/SKILL.md (user+repo scope); hooks/list reads settings.json hooks, mapping Claude events to Codex HookEventName (unmappable events dropped).
Fuzzy file searchSupportedOne-shot fuzzyFileSearch plus the stateful session API (sessionStart/Update/Stop) that streams fuzzyFileSearch/sessionUpdated results and a final sessionCompleted.
Filesystem RPCsSupportedfs/readFile, write, metadata, list, remove, copy, watch/unwatch (Codex v2-shaped).
Command/process RPCsSupportedcommand/exec and process/spawn implemented.

Not applicable / unsupported

AreaStatusNotes
Realtime audioUnsupportedNo Claude audio channel; methods ack so capability probe doesn't error; listVoices returns empty.
Plugins/marketplace/appsN/ANo Codex plugin marketplace; methods return empty schema-shaped responses. (Claude skills/hooks are surfaced — see Utilities.)
Account/rate limits/authN/AClaude manages its own auth; account/OpenAI-auth panels report null/empty.
External agent importStubexternalAgentConfig/detect and import return empty.
Windows sandboxUnsupportedTarget deployment is Linux/macOS; methods return not configured.

Protocol version

The adapter advertises codex app-server protocol v2 @ 0.142.3 (via codex --version and the initialize userAgent; override with CLAUDE_CODEX_COMPAT_VERSION). The 0.130 → 0.142 delta is additive and backward-compatible: new optional request methods (thread/search, thread/delete, account/usage/read, plugin/*, remoteControl/*, environment/add, …) plus widened enums (ReasoningEffort → free-form string, new AuthMode / WebSearchMode variants). The new methods are OpenAI-account / plugin / remote-control surfaces with no Claude Code equivalent; unimplemented methods return a JSON-RPC error, which Codex App treats as "unsupported" for these optional features. Regenerate the reference schema under generated/ with npm run generate:schema (needs a matching codex on PATH).

Because the adapter now reports the same version as a real codex, it appends a distinguishing suffix: codex --version prints codex-cli 0.142.3 (claude-codex) and the initialize userAgent carries claude-codex in its originator field. The version number stays first so the App's semver probe still parses it. Set CLAUDE_CODEX_VERSION_SUFFIX="" to behave exactly like upstream codex.

Wire conformance

  • turn/start response and the turn/started / turn/completed notifications ship items: [] with itemsView: "notLoaded", matching the real app-server (bespoke_event_handling.rs clears items; turn_processor.rs returns an empty turn). The timeline is driven by the item/* event stream; loaded items are only returned by history reads (thread/read, thread/turns/list).
  • The user message is recorded in turn history but, like the real app-server, is not surfaced as a userMessage item/* event during a turn (including turn/steer). review/start's response carries the synthesized userMessage (itemsView notLoaded); enteredReviewMode arrives via item/started. Uploaded images are surfaced live as imageView item/* events.
  • MCP boot status uses mcpServer/startupStatus/updated with a valid McpServerStartupState; mcpServerStatus/list returns conformant McpServerStatus objects ({ name, tools, resources, resourceTemplates, authStatus }).
  • Lifecycle turn envelopes carry only schema fields — internal api/cost/turn metrics are not serialized onto the wire (token metrics flow through thread/tokenUsage/updated).
  • turn/plan/updated is reserved for the update_plan/TodoWrite checklist tool and ships the spec shape { explanation, plan: [{ step, status }] } (status ∈ pending/inProgress/completed); the checklist tool is not also surfaced as a timeline item. Plan-mode prose stays on the separate plan ThreadItem + item/plan/delta channel.

Robustness notes

  • Unix socket paths are validated against the platform sun_path limit (~104 macOS / ~108 Linux); a deep CODEX_HOME falls back to a short hashed path under the system temp dir.
  • git diff / file-listing failures are written to the debug log (distinguishing "not a git repository" from real errors) rather than swallowed.
  • Per-thread in-memory state (command approvals, token usage, goals, elicitation counts) is released when a thread is archived.

Next targets

  1. Parse Claude review text into first-class Codex review finding items.
  2. Persist compaction summaries in a dedicated store, not just UI items.
  3. Run the capability probe over SSH against a named host.
  4. Flesh out plugin/skill/app surfaces if Codex App starts relying on them.

Released under the MIT License.