Codex Harness: Run OpenClaw Agent Turns via Codex App-Server

This page explains how the official Codex plugin shifts embedded OpenAI agent turns to Codex app-server execution, covering remote workspaces, security, and media handling. It is for developers integrating Codex with OpenClaw.

Read this when

  • You want to use the official Codex app-server harness
  • You need Codex harness config examples
  • You need explicit Codex runtime policy and fallback rules

The official codex plugin shifts embedded OpenAI agent turns to Codex app-server execution rather than the default OpenClaw harness. Codex takes charge of the underlying agent session, covering native thread resume, native tool continuation, native compaction, and app-server execution. OpenClaw continues to manage chat channels, session files, model selection, OpenClaw dynamic tools, approvals, media delivery, and the mirrored transcript display.

Remote Codex app-servers don't have to share a machine with the Gateway. Configure remoteWorkspaceRoot to verify remote workspace attachment paths. OpenClaw moves authoritative attachment bytes over the established app-server connection through a fixed, shell-free command/exec reader. That reader blocks symlinks, applies file and response size caps before any allocation, and stages immutable Gateway-managed media prior to channel delivery, with no shared or synchronized filesystem needed. Codex images get materialized straight from typed app-server events; images that only carry saved paths go through that same bounded remote reader. Uploads rely on the Gateway's configured channel identity and request timeout at all times.

Use canonical OpenAI model refs like openai/gpt-5.6-sol. Skip legacy Codex GPT refs; place OpenAI agent auth order under auth.order.openai. The openclaw doctor --fix mechanism repairs legacy Codex auth profile ids and legacy Codex auth order entries.

When provider/model runtime policy is unset or set to auto, the openai/* prefix alone won't select this harness. OpenAI can pick Codex implicitly only for an exact official HTTPS Platform Responses or ChatGPT Responses route with no authored provider request override. Valid model-scoped params.fastMode / params.fast_mode values and valid cutoff keys act as typed agent-runtime controls, so they neither count as authored provider request params nor select a runtime on their own. See OpenAI implicit agent runtime. If Codex claims auth before Platform versus ChatGPT routing is determined, OpenClaw still demands that every candidate route declare Codex compatibility. Native auth ownership by itself never skips that route check.

With no OpenClaw sandbox active, OpenClaw launches Codex app-server threads with Codex native code mode enabled (code-mode-only stays off by default), so native workspace/code capabilities remain usable alongside OpenClaw dynamic tools routed through the app-server item/tool/call bridge. A standard OpenClaw sandbox or restricted tool policy turns off native code mode unless you opt into the experimental sandbox exec-server path. Paired-device remote-exec instead relies on its placement-owned environment without that experimental flag.

Eligible native-shell turns also keep gateway_exec and gateway_process as a separate OpenClaw execution path. Reach for gateway_exec only when a command requires OpenClaw-managed Gateway environment access, including Secret Store agent-readable environment values or protected egress sentinels. It stays pinned to the Gateway host and obeys OpenClaw exec policy. gateway_process leverages the existing per-session OpenClaw process scope for background follow-up. For ordinary local work, prefer Codex native shell.

Under the default tools.exec.host: "auto" with no active OpenClaw sandbox, Codex also gets node_exec for commands on paired nodes. Native shell stays on the Codex app-server host and workspace (Gateway-local for the default stdio deployment); node_exec picks a node by name or id, keeps OpenClaw's node approval policy active, and blocks until the remote command finishes. Remote-node background follow-up isn't supported. When a finite runtime allowlist disables native Code Mode and leaves the turn with no execution environment, OpenClaw keeps its policy-filtered exec and process tools available for direct, unsandboxed execution instead.

When tools.exec.host: "node" or /exec host=node makes the node the session default, OpenClaw hides the Codex-native shell and presents node_exec as the shell path. That prevents the configured execution host from silently dropping back to the app-server or Gateway machine.

gateway_exec stays hidden when an active OpenClaw sandbox, a node-default execution policy, memory-flush restrictions, tool allow/deny policy, or codexDynamicToolsExclude would turn Gateway host access into a bypass. Secret Store environment values never reach the Codex app-server process, native shell, sandbox exec-server, ACP children, sandbox exec, or node exec.

This Codex-native capability is distinct from OpenClaw Code Mode, an opt-in QuickJS-WASI runtime for generic OpenClaw runs with a different exec input shape. For the broader model/provider/runtime split, start with Agent runtimes: openai/gpt-5.6-sol names the model, codex names the runtime, and Telegram, Discord, Slack, or another channel serves as the communication surface.

Requirements

  • The official @openclaw/codex plugin installed. Add codex to plugins.allow if your config relies on an allowlist.
  • Codex app-server 0.147.0 or later. The plugin ships and manages the exact @openai/codex 0.148.0 artifact, so a codex command on PATH won't affect normal startup. Explicit custom, remote, and macOS desktop-owned app-servers must report valid SemVer at or above the supported minimum. Versions newer than the managed artifact start with a warning; acceptance allows an attempt but doesn't prove readiness or capability.
  • Node.js on the remote Codex app-server host when remoteWorkspaceRoot is set and cross-machine workspace attachments must be transferred.
  • Codex auth via openclaw models auth login --provider openai, an app-server account already present in the agent's Codex home, or an explicit Codex API-key auth profile.

For auth precedence, environment isolation, custom app-server commands, model discovery, and the full config field list, see Codex harness reference.

Quickstart

Install the official plugin, then sign in with Codex OAuth:

openclaw plugins install @openclaw/codex
openclaw models auth login --provider openai

Enable the codex plugin and pick an OpenAI agent model:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
}

If your config uses plugins.allow, add codex there as well:

{
  plugins: {
    allow: ["codex"],
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}

Restart the gateway after changing plugin config. If a chat already has a session, run /new or /reset first so the next turn resolves the harness from current config.

Run Codex on a paired device

Codex sessions can put native command, filesystem, capability-discovery, and HTTP execution on an eligible paired device while the Codex app-server, model inference, provider authentication, and session transcript remain on the Gateway. This is session-wide remote-exec placement, not node_exec or tools.exec.host: "node".

Install and enable the Codex plugin in both the Gateway's configuration and the paired node's own local configuration. If either machine uses plugins.allow, include codex in that machine's allowlist. On the Gateway, explicitly allow the high-risk node command:

{
  gateway: {
    nodes: {
      commands: {
        allow: ["codex.exec-server.stdio.v1"],
      },
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}

The paired node has to expose session hosting and advertise the codex.exec-server capability along with the codex.exec-server.stdio.v1 command. When the plugin alters an existing node's command surface, reconnect that node, check openclaw nodes pending, and confirm the revised pairing using openclaw nodes approve <requestId>. The persistent command allowlist does not take the place of the standard node invocation approval: deny launches no Codex process, and allow-once permits a single exec-server start.

Codex spins up its node exec-server directly instead of launching an OpenClaw worker, so a paired host stays valid even when every worker slot is taken. The command still needs to be practically callable: declaring it without the approved pairing surface and Gateway allowlist does not suffice.

Approval opens access to any process or file reachable by the node's OS account. The verified placement workspace defines the working directory and reconciliation scope, but it does not sandbox or restrict that access. Pair only devices you trust, and when isolation matters, run the node under a distinct least-privilege OS account.

Pick the paired device through the Control UI Place picker, or explicitly dispatch an existing managed-worktree session:

openclaw gateway call sessions.dispatch \
  --params '{"key":"agent:main:device-work","deviceId":"<paired-device-id>"}'

Within the placement workspace, the node launches the same managed, pinned Codex binary with codex exec-server --listen stdio. The Gateway passes complete Codex JSON-RPC messages over the existing authenticated, approval-gated duplex node channel, capping each message at 64 MiB. No OpenClaw worker child is started, no reverse tunnel is opened, and provider, cloud, or GitHub credentials are not copied to the device. Authenticated remote HTTP is not available: before forwarding anything to the node, the Gateway rejects requests that carry bearer/OAuth authorization, cookies, API keys, or other sensitive authentication headers. Put authenticated HTTP on the Gateway, or point to an endpoint that deliberately requires no credentials. The node process uses a fresh private HOME and CODEX_HOME that get removed after the attempt, and both its launch environment and the requested child-process environments are sanitized. Completed filesystem changes reconcile back into the Gateway-owned managed worktree.

Ending the Codex attempt visibly and terminating its remote exec-server process happens when you disconnect the node, close the app-server connection, cancel the turn, or retire the plugin. Every paired-device attempt gets its own isolated Gateway app-server client, so remote environment registrations do not pile up across attempts. Reconnecting the same paired device allows a fresh attempt, but it never picks up the disconnected stdio connection or its processes. Standard Codex turns work, yet /btw side questions are not yet wired to paired-device placement and fail with an actionable explanation. Refer to Cloud workers and paired-device placement and Node command policy.

Share threads with Codex Desktop and CLI

The default appServer.homeScope: "agent" keeps each OpenClaw agent separate from the operator's native Codex state. To let an owner view and manage the same native threads that Codex Desktop and the Codex CLI display, opt into the user Codex home:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            homeScope: "user",
          },
        },
      },
    },
  },
}

User-home mode works with a local managed stdio process or the shared Unix-socket transport. It relies on $CODEX_HOME when set and ~/.codex otherwise, including that home's native Codex auth, config, plugins, and thread store. OpenClaw does not inject an OpenClaw auth profile into this app-server, even when the agent's model route holds a stored OpenAI profile. The native account gets verified against the route instead, in both directions:

  • A subscription route demands that the native home be signed in to ChatGPT. If a turn reports missing subscription credentials, run codex login in that home.
  • A Platform (API-key) route rejects a native home signed in with a ChatGPT subscription, so an API-billed route never silently spends the plan. Sign that home in with codex login --with-api-key, or switch to homeScope: "agent" and let OpenClaw inject the key it already holds.

A stored OpenAI profile is acceptable alongside homeScope: "user"; OpenClaw keeps it for agent-scoped connections and simply does not pass it to the native home. Use openclaw models auth list --provider openai to review stored profiles and openclaw models auth logout <profileId> --yes to delete one you no longer want.

Owner turns gain the codex_threads tool: list, search, read, fork, rename, archive, and restore native threads. Fork a thread to continue it in OpenClaw; the fork attaches to the current OpenClaw session and remains visible to other native Codex clients. Archiving requires explicit confirmation that the thread is closed elsewhere. When supervision is also enabled, transcript fields and mutations require the matching supervision.allowRawTranscripts or supervision.allowWriteControls opt-in.

Do not resume or write the same thread concurrently through independent managed stdio App Servers. Codex coordinates live writers inside one App Server, not across separate processes. Forking is the safe coexistence path for ordinary user-home stdio sessions.

appServer.homeScope: "user" alone does not govern the fleet catalog. Native session discovery is active while the plugin is running; set sessionCatalog.enabled: false to remove it from the OpenClaw sidebar without disabling Codex. The catalog relies on a separate supervision connection; without explicit appServer connection settings, that connection defaults to managed user-home stdio while the ordinary harness stays agent-scoped. Explicit appServer settings are honored by both paths. Set homeScope: "user" explicitly, as above, when the ordinary harness should also share native state.

Supervise Codex sessions

The same codex plugin can list non-archived Codex sessions from the Gateway computer and opted-in paired nodes. A stored or idle Gateway-local session can create a model-locked Chat that mirrors its bounded persisted user and assistant history. Its private binding uses the supervision connection for the native snapshot, canonical branch, and later turns while ordinary Codex sessions remain agent-scoped. The first canonical start uses exactly the model and provider that Codex returns for the snapshot fork. Later resumes leave selection to Codex's native configuration; the outer OpenClaw model and fallback chain never replace it. Stored and idle rows can be archived after explicit no-other-runner confirmation. Active sources cannot create a branch or be archived; an existing supervised Chat can still be opened. Paired-node sessions remain metadata-only.

See Supervise Codex sessions for setup, branching rules, paired-node limits, metadata exposure, and troubleshooting.

Configuration

NeedSetWhere
Enable the harnessplugins.entries.codex.enabled: trueOpenClaw config
Hide native Codex session discoveryplugins.entries.codex.config.sessionCatalog.enabled: falseCodex plugin config
Include additional local Codex stores (stdio only)plugins.entries.codex.config.sessionCatalog.homesCodex plugin config
Keep an allowlisted plugin installInclude codex in plugins.allowOpenClaw config
Allow eligible OpenAI turns to use Codex implicitlyExact official HTTPS Responses/ChatGPT route, no authored provider request override, runtime unset/autoOpenAI provider/model config
Sign in with ChatGPT/Codex OAuthopenclaw models auth login --provider openaiCLI auth profile
Add API-key backup for Codex runsopenai:* API-key profile listed after subscription auth in auth.order.openaiCLI auth profile + OpenClaw config
Fail closed when Codex is unavailableProvider or model agentRuntime.id: "codex"OpenClaw model/provider config
Use direct OpenAI API trafficProvider or model agentRuntime.id: "openclaw" with normal OpenAI authOpenClaw model/provider config
Tune app-server behaviorplugins.entries.codex.config.appServer.*Codex plugin config
Enable native Codex plugin appsplugins.entries.codex.config.codexPlugins.*Codex plugin config
Enable Codex Computer Useplugins.entries.codex.config.computerUse.*Codex plugin config

Prefer auth.order.openai for subscription-first/API-key-backup ordering. Existing legacy Codex auth profile ids and legacy Codex auth order are doctor-only legacy state; do not write new legacy Codex GPT refs.

{
  auth: {
    order: {
      openai: ["openai:user@example.com", "openai:api-key-backup"],
    },
  },
}

For a Codex-compatible effective route, both profiles above remain candidates for the same Codex run. Profile order chooses credentials, not the runtime. Changing auth order does not make a custom, Completions, HTTP, or request-overridden route Codex-compatible. Valid model-scoped Fast-mode and cutoff controls are runtime controls, not request overrides.

Restricted turns and ring zero

Restrictions from OpenClaw apply to individual Codex turns rather than locking an entire session into a special mode. Because of this, a session that already exists can execute a single constrained turn and then resume its regular Codex conversation on the next unconstrained turn. When the restriction is only temporary, OpenClaw keeps the standard thread binding intact and spins up a temporary constrained thread only when needed.

A standard policy-restricted turn is triggered whenever an explicit OpenClaw tool policy cannot be translated safely to Codex's built-in tool interface. Typical causes are:

  • a finite tools.allow list or a per-run allowlist maintained internally
  • disableTools or a sender/group policy that denies every tool
  • a tools.deny entry containing a wildcard, a tool group, an unknown name, or a name absent from the Codex harness's audited safe-deny set
  • any applicable tool policy tied to an agent, provider, group, sender, sandbox, subagent, inherited, scheduled, or runtime scope that carries one of those restrictions

Merely narrowing the default tool profile does not activate this mode. A deny list composed only of audited OpenClaw-owned tools can likewise remain on the standard native surface; the harness applies those denials without turning off unrelated Codex features. The generic harness contract is described in Native tool-policy enforcement, and the current Codex rules are covered in Codex harness reference.

When a turn is policy-restricted in the ordinary sense, OpenClaw turns off Codex's native Code Mode, drops environment selections, disables and verifies both inherited and configured MCP servers, turns off native hook relays, and passes OpenClaw dynamic tools through the effective policy. The bounded workspace AGENTS.md snapshot still arrives at the model as thread-level developer instructions, since project instructions function as context rather than tool authority.

Ring zero operates at a higher level and is distinct. It represents the host-owned OpenClaw system agent reserved for setup and repair tasks. The host engages it through the single openclaw tool; ordinary agent configuration cannot move a chat into ring zero. Ring-zero turns keep only that host-scoped tool, swap ambient Codex instructions for host-authored setup instructions, disable native tools and MCP servers, and hide workspace project documents, including the AGENTS.md developer-instruction carrier.

Other narrow internal modes also hide project documents: lightweight bootstrap turns, message-only source replies, and tool-disabled internal turns. They share some isolation settings with policy-restricted turns but are not equivalent to ring zero.

Project instructions

Codex discovers AGENTS.md files through its native project-document mechanism. For normal app-server threads, OpenClaw increases Codex's aggregate root-to-working-directory budget from the upstream 32 KiB default to a bounded 128 KiB so later scoped instructions are not silently dropped. Ordinary conversation tool-policy restrictions keep that budget intact because project instructions are context, not tool authority. Their isolated native environment cannot access workspace files, so OpenClaw provides the bounded workspace AGENTS.md snapshot as thread-level developer instructions. Lightweight, ring-zero, message-only, and tool-disabled internal turns instead set the native project-document budget to zero.

This byte budget is separate from the character-based workspace bootstrap limits set through agents.defaults.bootstrapMaxChars and agents.defaults.bootstrapTotalMaxChars.

/context marks native project documents as unverified because app-server exposes their source paths but not the retained byte counts needed to determine whether any individual file was fully loaded or truncated.

Compaction

Avoid setting compaction.model or compaction.provider on agents backed by Codex. Codex compacts through its native app-server thread state, so OpenClaw ignores those local summarizer overrides at runtime, and openclaw doctor --fix removes them when the agent uses Codex.

An authored models.providers.*.models[].contextTokens cap is passed to Codex thread start and resume as model_context_window. Codex clamps the value to the model's native maximum and derives automatic compaction from the capped window. When the model entry lacks an authored cap, OpenClaw sends no override.

Lossless remains available as a context engine for assembly, ingestion, and maintenance around Codex turns, configured through plugins.slots.contextEngine: "lossless-claw" and plugins.entries.lossless-claw.config.summaryModel, not through agents.defaults.compaction.provider. openclaw doctor --fix migrates the old compaction.provider: "lossless-claw" shape to the Lossless context-engine slot when Codex is the active runtime, but native Codex still owns compaction. The native app-server harness supports context engines that require pre-prompt assembly; generic CLI backends, including codex-cli, do not offer that host capability.

For Codex-backed agents, /compact initiates native Codex app-server compaction on the bound thread and waits for its terminal result. The shared agents.defaults.compaction.timeoutSeconds budget applies; on timeout, OpenClaw asks Codex to interrupt the native turn and keeps the per-thread fence until termination is confirmed. It never falls back to a context engine or public OpenAI summarizer. If the native Codex thread binding is missing or stale, the command fails closed instead of silently switching compaction backends.

Direct API long context

Codex subscription and direct OpenAI API traffic are separate contracts. The live ChatGPT/Codex catalog commonly exposes a 272000 token model window, while OpenAI documents a 1050000 token Platform API window and 128000 maximum output for GPT-5.5 and GPT-5.6. Both runtime translations use the same safe arithmetic:

1050000 total - 128000 maximum output = 922000 safe active input
automatic compaction threshold = 700000 active tokens

The native Codex translation is not a Responses parameter set. Codex owns the native thread's context and compaction, so do not add responsesServerCompaction or responsesCompactThreshold to a Codex-backed model.

Start from a complete Codex model catalog compatible with the installed Codex version. For the exact gpt-5.6-sol entry, preserve the rest of the descriptor and set:

{
  "context_window": 922000,
  "max_context_window": 922000,
  "auto_compact_token_limit": 700000
}

Codex applies its normal 95% effective-window reserve to the 922000 catalog value, so it reports exactly 875900 usable tokens. Compacting at 700000 leaves 175900 tokens before that effective guard and 222000 before the provider-safe input allowance. This larger margin is deliberate: Codex checks already-recorded context before adding the next user message and context updates, so the threshold must cover one large incoming turn as well as tools, instructions, serialization, and the compaction turn itself.

For standalone Codex CLI or Desktop use, a command-auth custom provider can read the API key from a system keychain or secret manager while the normal ChatGPT login remains available for connectors:

model = "gpt-5.6-sol"
model_provider = "openai_api_direct"
model_context_window = 922000
model_auto_compact_token_limit = 700000
model_auto_compact_token_limit_scope = "total"
model_catalog_json = "/absolute/path/to/models-api-1m.json"

[model_providers.openai_api_direct]
name = "OpenAI API direct"
base_url = "https://api.openai.com/v1"
wire_api = "responses"
requires_openai_auth = false

[model_providers.openai_api_direct.auth]
command = "/absolute/path/to/read-openai-inference-key"
timeout_ms = 5000
refresh_interval_ms = 300000

The auth helper must print only the key to stdout. Do not put it in TOML.

For the OpenClaw Codex app-server harness, keep the default agent-scoped Codex home and let OpenClaw inject an openai API-key profile. Create the profile by the normal OpenAI API-key auth flow, put its actual id first in auth.order.openai, and pass the catalog and context limits as native Codex app-server arguments:

{
  auth: {
    order: {
      openai: ["openai:api-key"],
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            args: [
              "app-server",
              "--listen",
              "stdio://",
              "-c",
              'model_catalog_json="/absolute/path/to/models-api-1m.json"',
              "-c",
              "model_context_window=922000",
              "-c",
              "model_auto_compact_token_limit=700000",
              "-c",
              "model_auto_compact_token_limit_scope=total",
            ],
          },
        },
      },
    },
  },
  agents: {
    defaults: {
      model: { primary: "openai/gpt-5.6-sol" },
      models: {
        "openai/gpt-5.6-sol": {
          agentRuntime: { id: "codex" },
          params: { fastMode: true },
        },
      },
    },
  },
}

Replace openai:api-key with the actual API-key profile id. The agent-scoped app-server receives only that prepared key; the operator's native ~/.codex ChatGPT login, plugins, connectors, and thread store remain untouched. Use the injected agent-scoped API-key path above for this route rather than relying on homeScope: "user" to provide the intended credential.

The model catalog, model_context_window, total-scope automatic compaction limit, exact openai/gpt-5.6-sol route, and API-key profile order form one configuration unit. Apply them together. OpenClaw can keep embedded and native long-context choices at the same time only when their model refs or agent configurations are distinguishable; one model entry cannot carry both runtime-owned compaction strategies.

After changing the catalog or app-server arguments, restart the Gateway and native Codex app-server, then start a fresh chat. Run /model default -s when an existing session has a model or runtime override. Existing native threads preserve their recorded provider and model settings. Verify the runtime with /status and /codex status, then send a harmless direct API turn before starting a long session.

A process-owned isolated Gateway and app-server pair validated this exact openai/gpt-5.6-sol API-key configuration. Codex observed an effective window of 875900. Active context expanded from 197032 to 377386, 561957, and 750745 tokens without any manual compaction; the following small turn triggered automatic compaction down to 75980 active tokens, with a minimum post-compaction snapshot of 68375. Compaction finished in 2810 ms and recorded a count of one. A durable marker survived both compaction and restart, a deterministic long response yielded 5442 output tokens, and OpenClaw forwarded priority to the Codex app-server tier on every call. That request evidence does not establish which upstream tier handled each call. The entire suite completed in 401.37 seconds. These figures are observations, not service-level commitments.

Warning

Long context is intentionally opt-in. Once input goes beyond 272000 tokens, OpenAI charges the full request at 2× input and cache rates and 1.5× output rates. Fast-mode pricing varies by model; GPT-5.6 Sol API Fast mode (formerly Priority processing) currently adds another 2× over Standard, making this recipe 4× short-context Standard input-side pricing and 3× short-context Standard output pricing. OpenClaw presently sends the wire value service_tier: "priority". ChatGPT/Codex-credit Fast mode is distinct: GPT-5.6 and GPT-5.5 currently use 2.5× Standard credits, while this API-key Codex path relies on API token pricing. The API is the authority for access, actual limits, and billing. See OpenAI model limits, Fast mode, API pricing, and Codex speed.

The remainder of this page addresses deployment shape, fail-closed routing, guardian approval policy, native Codex plugins, and Computer Use. For complete option lists, defaults, enums, discovery, environment isolation, timeouts, and app-server transport fields, consult the Codex harness reference.

Verify Codex runtime

Place /status in the chat where you expect Codex. A Codex-backed OpenAI agent turn appears as:

Runtime: OpenAI Codex

Then inspect Codex app-server state:

/codex status
/codex models
/codex binding

After installing or updating OpenClaw, explicitly confirm the managed package binary before cutover:

openclaw doctor --lint --only codex/managed-app-server --json

For a working Codex route through the managed stdio app-server, this default-disabled check locates the platform-native executable and demands the exact Codex version pinned by OpenClaw. It does not run custom, remote, or macOS desktop-owned app-servers.

/status shows the resolved OpenClaw Fast policy (on, off, or auto) and the chosen runtime. It does not show the upstream service tier actually honored or returned for a completed request. /codex binding shows the attached native thread and current model settings. /codex status shows app-server connectivity, account, rate limits, MCP servers, and skills. Neither Codex command is provider-response telemetry. /codex models lists the live Codex app-server catalog for the harness and account. If /status is unexpected, see Troubleshooting.

Routing and model selection

Maintain separation between provider refs and runtime policy:

  • Pick openai/gpt-* for canonical OpenAI model selection. The prefix alone never selects Codex.
  • When runtime is unset or auto, only an exact official HTTPS Platform Responses or ChatGPT Responses route with no authored provider request override may implicitly select Codex. Valid model-scoped Fast-mode and cutoff controls do not count as authored request params.
  • Avoid legacy Codex GPT refs in config; run openclaw doctor --fix to repair legacy refs and stale session route pins.
  • agentRuntime.id: "codex" turns Codex into a fail-closed requirement for a compatible route. It does not make an incompatible effective route compatible.
  • agentRuntime.id: "openclaw" opts a provider or model into the embedded OpenClaw runtime when that is deliberate.
  • /codex ... manages native Codex app-server conversations from chat.
  • ACP/acpx is a separate external harness path. Use it only when the user requests ACP/acpx or an external harness adapter.
User intentUse
Bind the active conversation/codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]
Pick up a prior Codex thread/codex resume <thread-id>
Enumerate or narrow down Codex threads/codex threads [filter]
Inspect or modify the native goal tied to the bound thread/codex goal [status|set <objective>|pause|resume|block|complete|clear]
Show native Codex plugins/codex plugins list
Search native Codex marketplace plugins/codex plugins available
Set up and grant access to a native Codex plugin/codex plugins install <plugin>@<marketplace>
Turn a configured native Codex plugin on or off/codex plugins enable <name>, /codex plugins disable <name>
Restore a saved Codex CLI session as a paired-node turn/codex sessions --host <node> [filter], then /codex resume <session-id> --host <node> --bind here
See non-archived Codex sessions from any machineEnable Codex supervision and open Codex Sessions
Switch the bound thread's model, fast-mode, or permissions/codex model <model>, /codex fast [on|off|status], /codex permissions [default|yolo|status]
Shrink the active Codex session/codex compact
Halt or redirect the current turn/codex stop, /codex steer <text>
Release the current binding/codex detach (alias /codex unbind)
Forward Codex feedback exclusively/codex diagnostics [note]
Launch an ACP/acpx taskACP/acpx session commands, not /codex
Use caseConfigureVerifyNotes
OpenAI route that qualifies with native Codex runtimeExact official HTTPS Responses/ChatGPT route with no authored provider request override, plus enabled codex plugin/status shows Runtime: OpenAI CodexValid Fast runtime controls do not disqualify this path
Fail closed when Codex is missingProvider or model agentRuntime.id: "codex"Turn fails instead of embedded fallbackUse for Codex-only deployments
Send OpenAI API-key traffic through OpenClawProvider or model agentRuntime.id: "openclaw" and normal OpenAI auth/status shows OpenClaw runtimeUse only when OpenClaw is intentional
Legacy configlegacy Codex GPT refsopenclaw doctor --fix rewrites itDo not write new config this way
ACP/acpx Codex adapterACP sessions_spawn({ runtime: "acp" })ACP task/session statusSeparate from native Codex harness

agents.defaults.imageModel applies the same prefix split. For the standard OpenAI path, go with openai/gpt-*; reserve codex/gpt-* for cases where image comprehension must run through a bounded Codex app-server turn. Doctor converts legacy Codex GPT refs into openai/gpt-*.

Deployment patterns

Basic Codex deployment

Start from the quickstart config with an OpenAI model whose effective official HTTPS route can implicitly select Codex:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
}

Mixed provider deployment

Set up a Claude main agent, then register a named Codex agent:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    ownership: "explicit",
    defaults: {
      model: "anthropic/claude-opus-4-6",
    },
    entries: {
      main: {
        model: "anthropic/claude-opus-4-6",
      },
      codex: {
        name: "Codex",
        model: "openai/gpt-5.6-sol",
      },
    },
  },
}

This explicit fleet has no default agent; target main or codex with a session, --agent, or binding. The main agent uses its normal provider path. The codex agent uses Codex app-server when its effective OpenAI route remains compatible; add explicit model-scoped agentRuntime.id: "codex" when that should be a fail-closed requirement.

Fail-closed Codex deployment

An eligible exact official HTTPS OpenAI route can resolve to Codex when the bundled plugin is available. Add explicit runtime policy for a written fail-closed rule:

{
  models: {
    providers: {
      openai: {
        agentRuntime: {
          id: "codex",
        },
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}

With Codex forced, OpenClaw fails early if the effective route is not declared Codex-compatible, the plugin is disabled, the app-server is too old, or the app-server cannot start.

App-server policy

By default, the plugin starts OpenClaw's managed Codex binary locally with stdio transport. Set appServer.command only to intentionally run a different executable. Codex classifies WebSocket transport as experimental and unsupported; use it only for non-production testing against an app-server already running elsewhere:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            transport: "websocket",
            url: "ws://gateway-host:39175",
            authToken: "${CODEX_APP_SERVER_TOKEN}",
          },
        },
      },
    },
  },
}

WebSocket transport proactively establishes the app-server connection at gateway startup and limits the opening handshake to 10 seconds. An idle connection sends a WebSocket ping every 20 seconds and allows 20 seconds for its matching pong. A healthy app-server message or pong resets the missed-heartbeat count; five consecutive missed pongs close the connection. Transient failures reconnect automatically with bounded, jittered exponential backoff. Authentication failures and unsupported app-server versions stop reconnecting and report that operator action is required. Ping and pong frames are transport-level health checks: they do not start a Codex turn or invoke a model. Local stdio and Unix transports do not perform these remote connection checks.

Local stdio app-server sessions default to the trusted local operator posture: approvalPolicy: "never", approvalsReviewer: "user", and sandbox: "danger-full-access". If local Codex requirements disallow that implicit YOLO posture, OpenClaw selects allowed guardian permissions instead. When an OpenClaw sandbox is active for the session, OpenClaw disables Codex native Code Mode, user MCP servers, and app-backed plugin execution for that turn instead of relying on Codex host-side sandboxing. Shell access instead goes through OpenClaw sandbox-backed dynamic tools such as sandbox_exec and sandbox_process when the normal exec/process tools are available.

Use normalized OpenClaw exec mode for Codex native auto-review before sandbox escapes or extra permissions:

{
  tools: {
    exec: {
      mode: "auto",
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}

For Codex app-server sessions, tools.exec.mode: "auto" corresponds to Codex Guardian-reviewed approvals, typically resolving to approvalPolicy: "on-request", approvalsReviewer: "auto_review", and sandbox: "workspace-write" when local requirements permit those settings. Within tools.exec.mode: "auto", OpenClaw drops legacy unsafe Codex approvalPolicy: "never" or sandbox: "danger-full-access" overrides; to intentionally adopt a no-approval Codex posture, use tools.exec.mode: "full". The older plugins.entries.codex.config.appServer.mode: "guardian" preset remains functional, though tools.exec.mode: "auto" serves as the standardized OpenClaw interface.

Refer to Permission modes for the mode-level comparison against host exec approvals and ACPX permissions. For details on every app-server field, auth order, environment isolation, and timeout behavior, consult the Codex harness reference.

Native approval audit evidence

When tools.exec.mode: "ask" is active alongside the Codex user reviewer, native command and file prompts go through OpenClaw's two-phase operator approval flow. Only decisions preservable by the native request appear in the prompt. A command allowing one execution without session trust, for instance, offers allow-once and deny; byte-bound script approvals likewise stay one-shot. File prompts accommodate both one-shot and session approval.

Terminal operator decisions rely on the Gateway's authoritative approval row and its precise execution binding. With execution identity collection enabled, examine the admitted run using openclaw audit --run <run-id> --explain. The resulting receipt may indicate allow-once, allow-always, denial, no-route, expiry, or cancellation, all without exposing command text, patch content, paths, or native request ids.

Codex auto-review, full-access policy, and native hook or OpenClaw policy decisions never generate an operator approval row. Missing or stale native turn context gets rejected prior to routing. Consequently, these scenarios yield no enforced operator-approval receipt, and audit inspection cannot reconstruct one from later tool events.

Commands and diagnostics

The codex plugin registers /codex as a slash command across any channel supporting OpenClaw text commands.

Native execution and control demand an owner or an operator.admin Gateway client: binding or resuming threads, sending or stopping turns, adjusting model, fast-mode, or permission state, compacting or reviewing, and detaching a binding. Other authorized senders retain read-only access to help, account, model, thread, native goal, MCP server, skill, and binding inspection commands.

Common forms:

  • /codex status verifies app-server connectivity, models, account, rate limits, MCP servers, and skills.
  • /codex models enumerates active Codex app-server models.
  • /codex threads [filter] lists recent Codex app-server threads.
  • /codex goal reads or modifies the attached thread's native Codex goal. Codex automatic goal continuation stays disabled; OpenClaw does not yet own autonomous follow-on turns.
  • /codex resume <thread-id> links the current OpenClaw session to an existing Codex thread.
  • /codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>] attaches the current chat.
  • /codex detach (or /codex unbind) removes the current binding.
  • /codex binding details the current binding.
  • /codex stop halts the active turn; /codex steer <text> redirects it.
  • /codex model <model>, /codex fast [on|off|status], and /codex permissions [default|yolo|status] modify per-conversation state.
  • /codex compact executes the same completion and session-accounting pipeline as /compact, then indicates whether Codex compacted the session and the resulting token count. If compaction is skipped or fails, the reply includes the reason.
  • /codex review initiates Codex native review for the attached thread.
  • /codex diagnostics [note] seeks confirmation before sending Codex feedback for the attached thread.
  • /codex account displays account and rate-limit status.
  • /codex mcp shows Codex app-server MCP server status.
  • /codex skills lists Codex app-server skills.
  • /codex plugins list shows configured native plugins; /codex plugins available discovers Codex marketplace plugins in the bound workspace.
  • /codex plugins install <plugin>@<marketplace> installs and authorizes one discovered plugin. /codex plugins enable <name> and /codex plugins disable <name> update its persisted policy. Mutations require an owner or operator.admin gateway client.
  • /codex computer-use [status|install] manages Codex Computer Use.
  • /codex help lists the full command tree.

Shared Fast mode and Codex fast mode

/fast governs the shared OpenClaw policy. A directive-only /fast off persists off in the OpenClaw session and sends null on affected Codex harness turns to clear the OpenClaw-owned service-tier override. /fast default removes only that session layer, so lower-precedence shared defaults may still resolve to on, off, or auto.

/codex fast instead modifies the native Codex conversation preference that is bound to the current thread. /codex fast off saves flex for subsequent conversation-bound native turns; it does not serve as a substitute for /fast off, nor does it alter the shared OpenClaw session policy. When a shared Fast-mode run control reaches a Codex harness turn, it takes precedence over plugins.entries.codex.config.appServer.serviceTier and any binding preference relevant to that turn: Fast on transmits priority, Fast off transmits null, and auto makes a per-model-call decision. The configured or bound native tier applies solely when no shared run control is present.

/codex fast status and /codex binding reflect native preference status, not the upstream tier that handled a completed provider request.

For most support cases, begin with /diagnostics [note] in the conversation where the issue occurred. It generates a single Gateway diagnostics report and, for Codex harness sessions, requests permission to send the pertinent Codex feedback bundle. Refer to Diagnostics export for the privacy model and group chat behavior. Use /codex diagnostics [note] only when you specifically need the Codex feedback upload for the currently attached thread without the complete Gateway diagnostics bundle.

Inspect Codex threads locally

A quick way to examine a problematic Codex run is often to open the native Codex thread directly:

codex resume <thread-id>

Obtain the thread id from the finished /diagnostics reply, /codex binding, or /codex threads [filter].

For upload mechanics and runtime-level diagnostics boundaries, see Codex harness runtime.

Auth order

In the default per-agent home, auth is chosen in this sequence:

  1. Ordered OpenAI auth profiles for the agent, preferably under auth.order.openai. Execute openclaw doctor --fix to migrate older legacy Codex auth profile ids and legacy Codex auth order.
  2. The app-server's existing account in that agent's Codex home.
  3. For local stdio app-server launches only, CODEX_API_KEY, then OPENAI_API_KEY, when no app-server account exists and OpenAI auth remains necessary.

When OpenClaw detects a ChatGPT subscription-style Codex auth profile, it strips CODEX_API_KEY and OPENAI_API_KEY from the spawned Codex child process. This keeps Gateway-level API keys available for embeddings or direct OpenAI models without inadvertently billing native Codex app-server turns through the API. Explicit Codex API-key profiles and local stdio env-key fallback rely on app-server login instead of inherited child-process env. WebSocket app-server connections do not receive Gateway env API-key fallback; use an explicit auth profile or the remote app-server's own account.

If a subscription profile encounters a Codex usage limit, OpenClaw records the reset time when Codex reports one and attempts the next ordered auth profile for the same Codex run. Once the reset time passes, the subscription profile becomes eligible again without altering the selected openai/gpt-* model or Codex runtime.

When native Codex plugins are configured, OpenClaw reads and caches a single runtime-and-workspace-scoped plugin/installed snapshot. That one snapshot covers configured plugins from Codex-discovered marketplaces, including disabled plugin ownership. plugin/read resolves only explicitly configured plugin details. /codex plugins available queries plugin/list with the bound workspace, while /codex plugins install <plugin>@<marketplace> is the owner- or administrator-authorized installation path. Routine thread setup retains existing explicitly configured curated-plugin recovery.

app/installed supplies the installed app runtime snapshot, and app/read supplies authenticated app metadata in batches of at most 100 app IDs. OpenClaw force-refreshes a cold snapshot once and consolidates successful curated installations into one app-inventory refresh. Ordinary cached reads do not force a connector refresh for every thread.

An authorized app can initially appear disabled or non-callable because Codex has not yet applied the target thread's restrictive app configuration. OpenClaw provisionally admits only explicitly allowed, ownership-proven apps, starts the thread with _default.enabled = false, and reads app/installed once with that thread's ID and forceRefresh: false. An app is exposed only after Codex confirms it is enabled and callable for the actual thread. Missing metadata, revoked auth, managed restrictions, workspace policy, and unavailable tools remain fail-closed.

The check runs before OpenClaw starts a turn or commits a thread binding. A failed persistent provisional thread is deleted; an ephemeral thread is unsubscribed. If cleanup cannot be confirmed, OpenClaw retires the app-server connection instead of reusing an unsafe thread.

Account-wide app access never overrides an explicitly disabled configured workspace plugin. When app/read omits that plugin's ownership, OpenClaw uses the plugin/installed snapshot and reads only the exact configured plugin's details to keep its apps denied. This check never installs, enables, or authenticates the plugin.

OpenClaw does not install unknown apps or let the model authorize new plugin installs. Owner-approved plugin installation refreshes the target runtime inventory. Missing inventory methods, authentication errors, transport failures, and connector refresh failures fail closed.

Environment isolation

For local stdio app-server launches, OpenClaw sets CODEX_HOME to a per-agent directory so Codex config, auth/account files, plugin cache/data, and native thread state do not read or write the operator's personal ~/.codex by default. OpenClaw preserves the normal process HOME; Codex-run subprocesses can still find user-home config and tokens, and Codex may discover shared $HOME/.agents/skills and $HOME/.agents/plugins/marketplace.json entries. With appServer.homeScope: "user", OpenClaw instead uses the native user Codex home and its existing account without injecting an OpenClaw auth profile.

If a deployment needs additional environment isolation, add those variables to appServer.clearEnv:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            clearEnv: ["CODEX_API_KEY", "OPENAI_API_KEY"],
          },
        },
      },
    },
  },
}

appServer.clearEnv only affects the spawned Codex app-server child process. OpenClaw removes CODEX_HOME and HOME from this list during local launch normalization: CODEX_HOME stays pointed at the selected agent or user scope, and HOME stays inherited so subprocesses can use normal user-home state.

Verified local setup turns also attest the selected Codex launcher and package. Inherited NODE_OPTIONS may contain bounded resource, warning, DNS result order, network-family autoselection, environment-proxy, and CA-source options because those settings cannot preload code or change module resolution. For example, --dns-result-order=ipv4first --no-network-family-autoselection is allowed. Malformed or unknown options and code-loading options such as --require or --import fail closed. If an inherited option is not needed by Codex, remove NODE_OPTIONS with appServer.clearEnv.

Codex dynamic tools load lazily by default via searchable. OpenClaw withholds dynamic tools that mirror Codex's own workspace capabilities, specifically read, write, edit, apply_patch, exec, process, get_goal, create_goal, update_goal, tool_call, tool_describe, tool_search, and tool_search_code. Goal operations remain exclusive to Codex, so OpenClaw avoids introducing a duplicate goal store into Codex turns. Most other OpenClaw integration tools, covering messaging, media, cron, browser, nodes, gateway, progress_card, and heartbeat_respond, surface via Codex tool search under the openclaw namespace, which keeps the initial model context lean. The restricted-turn shell fallback is the sole exception for exec and process when a finite allowlist turns off native Code Mode; runtime allowlists and codexDynamicToolsExclude continue to hold.

When native shell stays active and Gateway access qualifies under policy, OpenClaw instead publishes the separate gateway_exec and gateway_process names, preventing any mix-up between native shell and the OpenClaw-managed environment path.

Tools tagged catalogMode: "direct-only", including the OpenClaw computer tool, sit in the openclaw_direct namespace. Codex interprets that namespace as DirectModelOnly, so these tools remain directly visible to the model in both normal and code-mode-only threads, without traversing nested Code Mode tools.* calls.

Web search defaults to Codex's hosted web_search tool when search is enabled and no managed provider is selected. Native hosted search and OpenClaw's managed web_search dynamic tool cannot coexist, so managed search cannot get around native domain restrictions. OpenClaw switches to the managed tool when hosted search is unavailable, explicitly turned off, or superseded by a chosen managed provider. OpenClaw keeps Codex's standalone web.run extension off because production app-server traffic rejects its user-defined web namespace. tools.web.search.enabled: false shuts down both paths, as do tool-disabled LLM-only runs. Codex treats "cached" as a preference and maps it to live external access for unrestricted app-server turns. Automatic managed fallback fails closed when native allowedDomains are configured, so the allowlist cannot be circumvented. Persistent effective search-policy changes rotate the bound Codex thread before the next turn; transient per-turn restrictions use a temporary restricted thread and keep the existing binding for later resume.

sessions_yield, sessions_spawn, and message-tool-only source replies stay direct because they are turn-control or delegation contracts. Guidance still favors Codex's native spawn_agent as the primary Codex subagent surface, while explicit OpenClaw or ACP delegation remains directly callable through sessions_spawn. In Codex Code Mode, generic OpenClaw dynamic-tool results come back as JSON text rather than JavaScript objects, so parse JSON-looking results before reading fields. Codex also serializes nested dynamic calls; submit several sessions_spawn calls in a bounded loop rather than expecting Promise.all to launch them concurrently. Already-accepted children can still overlap while later calls are submitted. See Swarm for a complete pattern.

Heartbeat collaboration instructions tell Codex to search for heartbeat_respond before ending a heartbeat turn when the tool is not already loaded.

Set codexDynamicToolsLoading: "direct" only when connecting to a custom Codex app-server that cannot search deferred dynamic tools or when debugging the full tool payload.

Config fields

Supported top-level Codex plugin fields:

FieldDefaultMeaning
codexDynamicToolsLoading"searchable"Use "direct" to put OpenClaw dynamic tools directly in the initial Codex tool context.
codexDynamicToolsExclude[]Additional OpenClaw dynamic tool names to omit from Codex app-server turns.
codexPluginsdisabledNative Codex plugin/app support for migrated source-installed curated plugins.
sessionCatalogenabledSidebar discovery for native Codex sessions on this Gateway and eligible paired nodes.
supervisiondisabledAgent-facing native-session transcript and write-control policy.

Supported appServer fields:

FieldDefaultMeaning
transport"stdio""stdio" is what launches Codex; setting "unix" explicitly links to the local control socket, while "websocket" establishes a connection to url.
homeScope"agent"Per OpenClaw agent, "agent" keeps ordinary harness state separate. Opting in via "user" shares the native $CODEX_HOME or ~/.codex, relies on native authentication, and restricts thread management to the owner. With user scope, local stdio or Unix transport is supported. For the dedicated supervision connection, leaving the value empty defaults to "user" for stdio or Unix and to "agent" when using WebSocket.
commandmanaged Codex binaryThe executable used for stdio transport. When left unset, the managed binary is chosen; assign a value only to override explicitly.
args["app-server", "--listen", "stdio://"]Arguments passed for stdio transport.
urlunsetThe WebSocket App Server URL, or a unix:// URL. An explicitly empty Unix path points to the canonical control socket in the user's home directory.
authTokenunsetBearer token applied to WebSocket transport. It can be a plain string or a SecretInput such as ${CODEX_APP_SERVER_TOKEN}.
headers{}Additional WebSocket headers. Values for these headers may be literal strings or SecretInput entries, for instance x-codex-client-session-token: "${CODEX_CLIENT_SESSION_TOKEN}".
clearEnv[]Environment variable names stripped from the spawned stdio app-server process after OpenClaw constructs its inherited environment. For local launches, OpenClaw preserves the chosen CODEX_HOME along with the inherited HOME.
codeModeOnlyfalseEnables Codex's code-mode-only tool surface. Nested tools.* calls still expose the usual OpenClaw dynamic tools; openclaw_direct tools remain directly visible to the model.
remoteWorkspaceRootunsetWorkspace root for a remote Codex app server. OpenClaw maps the local cwd into this root and passes authoritative remote attachments through an output-capped, no-shell command/exec reader. Paths that leave either workspace, symbolic links, files over the size limit, and unbounded attachment batches all fail closed; uploads keep the configured channel identity and the app-server request timeout.
requestTimeoutMs60000Timeout governing app-server control-plane calls.
turnCompletionIdleTimeoutMs60000The quiet period after Codex accepts a turn, or after a turn-scoped app-server request, while OpenClaw waits for turn/completed.
turnAssistantCompletionIdleTimeoutMs10000Once a final or non-commentary assistant item, or a pre-tool raw assistant completion, arms the assistant-output release, this quiet window applies while OpenClaw still waits for turn/completed. Increasing it gives Codex more room to produce turn/completed before OpenClaw interrupts and frees the session lane.
postToolRawAssistantCompletionIdleTimeoutMs300000A completion-idle and progress guard used after a tool handoff, native tool completion, post-tool raw assistant progress, raw reasoning completion, or reasoning progress while OpenClaw waits for turn/completed. Choose this for trusted or heavy workloads where post-tool synthesis can legitimately remain quiet longer than the final assistant release budget.
mode"yolo" unless local Codex requirements disallow YOLOPreset governing YOLO or guardian-reviewed execution. When local stdio requirements omit danger-full-access, never approval, or the user reviewer, the implicit default becomes guardian.
approvalPolicy"never" or an allowed guardian approval policyThe native Codex approval policy sent to thread start, resume, or turn. Guardian defaults prefer "on-request" when permitted.
sandbox"danger-full-access" or an allowed guardian sandboxNative Codex sandbox mode sent to thread start or resume. Guardian defaults prefer "workspace-write" when allowed, otherwise "read-only". With an active OpenClaw sandbox, danger-full-access turns rely on Codex workspace-write, deriving network access from the OpenClaw sandbox egress setting.
approvalsReviewer"user" or an allowed guardian reviewerWhen permitted, "auto_review" enables Codex to review native approval prompts; otherwise fall back to guardian_subagent or user. guardian_subagent continues to serve as a legacy alias.
serviceTierunsetThis setting matters only for the native Codex app-server. Any non-empty value passes through untouched for forward compatibility; the documented options are "priority" and "flex". Setting null removes the override, and the older "fast" gets normalized to "priority". It is neither the shared Fast-mode control nor a direct embedded OpenAI parameter. A shared Fast run control takes precedence with priority or null, or picks per model call in auto mode.
networkProxydisabledNetworking for app-server commands can be routed through the Codex permissions profile as an opt-in. OpenClaw designates the chosen permissions.<profile>.network configuration and picks it via default_permissions rather than dispatching sandbox.
experimental.sandboxExecServerfalseA preview opt-in that registers an OpenClaw sandbox-backed Codex environment with the supported Codex app-server, letting native Codex execution run inside the active OpenClaw sandbox.

appServer.networkProxy is made explicit because it alters the Codex sandbox contract. With it enabled, OpenClaw also injects features.network_proxy.enabled and default_permissions into the Codex thread config so the resulting permission profile can launch Codex managed networking. By default, OpenClaw derives a collision-resistant openclaw-network-<fingerprint> profile name from the profile body; resort to profileName only when a stable local name is mandatory.

{
  plugins: {
    entries: {
      codex: {
        config: {
          appServer: {
            sandbox: "workspace-write",
            networkProxy: {
              enabled: true,
              domains: {
                "api.openai.com": "allow",
                "blocked.example.com": "deny",
              },
              unixSockets: {
                "/tmp/proxy.sock": "allow",
                "/tmp/blocked.sock": "none",
              },
              allowUpstreamProxy: true,
              proxyUrl: "http://127.0.0.1:3128",
            },
          },
        },
      },
    },
  },
}

If the standard app-server runtime would be danger-full-access, turning on networkProxy grants workspace-style filesystem access to the generated permission profile: since Codex managed network enforcement relies on sandboxed networking, a full-access profile would leave outbound traffic unprotected. Domain entries rely on allow or deny; Unix socket entries use Codex's allow or none values.

Image loader ownership

For image-capable models with Codex native tools active, Codex takes charge of view_image and OpenClaw disables its duplicate loader. The native Codex schema accepts one local filesystem path. For text-only models, or when the native tool surface is off, OpenClaw provides view_image with its path/paths schema and delegated vision route. Callers must follow the schema advertised for the active run.

Dynamic tool call timeouts

OpenClaw-owned dynamic tool calls are bounded separately from appServer.requestTimeoutMs: Codex item/tool/call requests get a 90 second OpenClaw watchdog by default. A positive per-call timeoutMs argument adjusts that specific tool budget, with a ceiling of 600000 ms. The image_generate tool falls back to agents.defaults.mediaModels.image.timeoutMs when the tool call omits its own timeout, or a 120 second image-generation default otherwise. The media-understanding view_image tool relies on the selected image-capable tools.media.models[] entry's timeoutSeconds or its 60 second media default; for image understanding, that timeout covers the request itself and is not shortened by earlier preparation work. On timeout, OpenClaw aborts the tool signal where supported and sends a failed dynamic-tool response back to Codex so the turn can proceed instead of stranding the session in processing. This watchdog serves as the outer dynamic item/tool/call budget; provider-specific request timeouts operate inside that call and preserve their own timeout semantics.

Once Codex accepts a turn, and once OpenClaw answers a turn-scoped app-server request, the harness expects Codex to keep making current-turn progress and eventually wrap up the native turn with turn/completed. If the app-server stays silent for appServer.turnCompletionIdleTimeoutMs, OpenClaw best-effort interrupts the Codex turn, logs a diagnostic timeout, and frees the OpenClaw session lane so follow-up chat messages are not queued behind a stale native turn. Most non-terminal notifications for the same turn disarm that short watchdog because Codex has shown the turn is still active.

Tool handoffs operate under a longer post-tool idle budget: after OpenClaw returns an item/tool/call response, after native tool items such as commandExecution finish, after raw custom_tool_call_output completions, and after post-tool raw assistant progress, raw reasoning completions, or reasoning progress. The guard applies appServer.postToolRawAssistantCompletionIdleTimeoutMs when configured and defaults to five minutes otherwise; that same budget also stretches the progress watchdog for the silent synthesis window before Codex emits the next current-turn event. Global app-server notifications, such as rate-limit updates, do not reset turn-idle progress. Reasoning completions, commentary agentMessage completions, and pre-tool raw reasoning or assistant progress can be followed by an automatic final reply, so they use the post-progress reply guard instead of freeing the session lane immediately.

Only final/non-commentary completed agentMessage items and pre-tool raw assistant completions arm the assistant-output release: if Codex then goes quiet without turn/completed, OpenClaw best-effort interrupts the native turn and releases the session lane. If another turn watch wins that release race, OpenClaw still accepts the completed final assistant item once no native request, item, or dynamic tool completion remains active and the assistant-output release still belongs to the latest completed item, with no later item completion. This can preserve the final answer after completed tool work without replaying the turn. Partial assistant deltas, stale earlier replies, and empty later completions do not qualify.

Replay-safe stdio app-server failures, including turn-completion idle timeouts without assistant, tool, active-item, or side-effect evidence, are retried once on a fresh app-server attempt. Unsafe timeouts still retire the stuck app-server client and release the OpenClaw session lane; they also clear the stale native thread binding instead of being replayed automatically. Completion-watch timeouts surface Codex-specific timeout text: replay-safe cases say the response may be incomplete, while unsafe cases tell the user to verify current state before retrying. Public timeout diagnostics include structural fields such as the last app-server notification method, raw assistant response item id/type/role, active request/item counts, and armed watch state; when the last notification is a raw assistant response item, they also include a bounded assistant text preview. They do not include raw prompt or tool content.

Local testing env overrides

  • When appServer.command is not set, OPENCLAW_CODEX_APP_SERVER_BIN skips the managed binary.
  • OPENCLAW_CODEX_APP_SERVER_ARGS
  • OPENCLAW_CODEX_APP_SERVER_MODE=yolo|guardian
  • OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY
  • OPENCLAW_CODEX_APP_SERVER_SANDBOX

OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1 is no longer available. Switch to plugins.entries.codex.config.appServer.mode: "guardian", or reach for OPENCLAW_CODEX_APP_SERVER_MODE=guardian when you only need a quick local test. For deployments that must be repeatable, config is the better route, since it keeps the plugin's behavior in the same reviewed file as the rest of the Codex harness setup.

Native Codex plugins

Native Codex plugin support taps into the app and plugin features of Codex app-server's own environment, running in the same Codex thread as the OpenClaw harness turn. OpenClaw never turns Codex plugins into synthetic codex_plugin_* OpenClaw dynamic tools.

codexPlugins only matters for sessions that pick the native Codex harness. Built-in harness runs, standard OpenAI provider sessions, ACP conversation bindings, and other harnesses are all unaffected.

Minimal migrated config:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          codexPlugins: {
            enabled: true,
            allow_destructive_actions: true,
            plugins: {
              "google-calendar": {
                enabled: true,
                marketplaceName: "openai-curated",
                pluginName: "google-calendar",
              },
            },
          },
        },
      },
    },
  },
}

Thread app config gets computed when OpenClaw starts a Codex harness session or refreshes an outdated Codex thread binding; it is not recalculated for every turn. After you change codexPlugins, run /new, /reset, or reboot the gateway so future Codex harness sessions pick up the new app set.

For migration eligibility, app inventory, destructive action policy, elicit, and native plugin diagnostics, check Native Codex plugins.

The signed-in Codex account governs OpenAI-side app and plugin access, and for Business and Enterprise/Edu workspaces, workspace app controls also apply. See Using Codex with your ChatGPT plan for OpenAI's overview of account and workspace controls.

Computer Use

Computer Use has a dedicated setup guide: Codex Computer Use.

In short: OpenClaw does not bundle the desktop-control app or run desktop actions itself. It gets Codex app-server ready, confirms the computer-use MCP server is reachable, and then hands native MCP tool calls over to Codex during Codex-mode turns.

Runtime boundaries

Only the low-level embedded agent executor is touched by the Codex harness.

  • OpenClaw dynamic tools still work. Codex asks OpenClaw to run those tools, so OpenClaw stays in the execution path.
  • Codex owns its native shell, patch, MCP, and native app tools. OpenClaw can watch or block specific native events through the supported relay, but it never rewrites native tool arguments.
  • gateway_exec and gateway_process are dynamic tools owned by OpenClaw. They intentionally re-enter Gateway exec preparation for agent-readable Secret Store environment and protected egress; those values never reach Codex native shell.
  • Native compaction belongs to Codex. OpenClaw keeps a transcript mirror for channel history, search, /new, /reset, and future model or harness switching, but it does not swap in an OpenClaw or context-engine summarizer for Codex compaction.
  • Media generation, media understanding, TTS, approvals, and messaging-tool output keep flowing through the matching OpenClaw provider/model settings.
  • tool_result_persist applies to OpenClaw-owned transcript tool results, not Codex-native tool result records.

For hook layers, supported V1 surfaces, native permission handling, queue steering, Codex feedback upload mechanics, and compaction details, see Codex harness runtime.

Troubleshooting

Codex is not a normal /model provider: that is expected for new configs. Pick an openai/gpt-* model, turn on plugins.entries.codex.enabled, and verify whether plugins.allow excludes codex.

OpenClaw picks the built-in harness over Codex: make sure the effective route is an exact official HTTPS Platform Responses or ChatGPT Responses route, has no authored provider request override, and that the Codex plugin is installed and enabled. The openai/gpt-* prefix alone is not sufficient. For strict proof while testing, set provider or model agentRuntime.id: "codex"; forced Codex fails rather than falling back when the route or harness is incompatible.

OpenAI Codex runtime falls back to the API-key path: grab a redacted gateway excerpt showing the model, runtime, selected provider, and failure. Ask affected collaborators to run this read-only command on their OpenClaw host:

(
  pattern='openai/gpt-5\.[45]|openai[-]codex|agentRuntime(\.id)?|harnessRuntime|Runtime: OpenAI Codex|legacy OpenAI Codex prefix|resolveSelectedOpenAIRuntimeProvider|candidateProvider[": ]+openai|status[": ]+401|Incorrect API key|No API key|api-key path|API-key path|OAuth'

  if ls /tmp/openclaw/openclaw-*.log >/dev/null 2>&1; then
    grep -E -i -n "$pattern" /tmp/openclaw/openclaw-*.log 2>/dev/null || true
  else
    journalctl --user -u openclaw-gateway --since today --no-pager 2>/dev/null \
      | grep -E -i "$pattern" || true
  fi
) | sed -E \
    -e 's/(Authorization: Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
    -e 's/(Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
    -e 's/(api[_ -]?key[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
    -e 's/(OPENAI_API_KEY[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
    -e 's/sk-[A-Za-z0-9_-]{12,}/sk-[REDACTED]/g' \
    -e 's/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/[EMAIL-REDACTED]/g' \
  | tail -200

Useful excerpts usually include openai/gpt-5.6-sol or openai/gpt-5.6-luna, Runtime: OpenAI Codex, agentRuntime.id or harnessRuntime, candidateProvider: "openai", and a 401, Incorrect API key, or No API key result. A corrected run should show the OpenAI OAuth path instead of a plain OpenAI API-key failure.

Legacy Codex model refs config remains: run openclaw doctor --fix. Doctor rewrites legacy model refs to openai/*, removes stale session and whole-agent runtime pins, and preserves existing auth-profile overrides.

The app-server is rejected: use Codex 0.147.0 or newer. OpenClaw rejects older, malformed, and unversioned servers. Same-version prereleases such as 0.147.0-alpha.2 remain below the stable minimum; build metadata such as 0.147.0+desktop does not affect precedence. A newer external version is permitted to initialize rather than treated as proof of compatibility, so startup and capability operations can still fail with their normal diagnostics.

/codex status cannot connect: check that the codex plugin is enabled, that plugins.allow includes it when an allowlist is configured, and that any custom appServer.command, url, authToken, or headers are valid.

The Codex app-server uses too much memory: distinguish the two processes first. OpenClaw runs the local Codex app-server as a separate Rust child. NODE_OPTIONS=--max-old-space-size=... changes only the Gateway's Node.js V8 heap; it does not cap or enlarge Codex. Managed Gateway installs already choose an adaptive V8 heap, and raising it can leave less host memory for Codex. Use Gateway memory troubleshooting for Gateway pressure, and inspect host or container memory for the Codex child.

The bundled Codex has no heap or RSS limit and no configurable idle-unload delay. After the last client unsubscribes, an inactive thread can remain loaded for up to 30 minutes. OpenClaw independently keeps up to 64 idle conversation threads subscribed on each Codex app-server for 30 minutes after their last activity. This preserves warm sessions and session-scoped approvals when several conversations alternate. Active turns and parents with unfinished native subagents are protected from idle eviction; session reset or deletion releases its own thread immediately. Idle-limit eviction unsubscribes the least recently used conversation, after which Codex applies its separate unloading delay and a later resumed session can require approvals again.

On constrained hosts, reduce native Codex subagent fan-out before increasing the Gateway heap:

{
  plugins: {
    entries: {
      codex: {
        config: {
          appServer: {
            args: ["-c", "agents.max_threads=3", "app-server", "--listen", "stdio://"],
          },
        },
      },
    },
  },
}

That setting caps the number of native child threads available to the bundled Codex default multi-agent backend. When you explicitly turn on Codex multi-agent v2, switch to features.multi_agent_v2.max_concurrent_threads_per_session=3 instead; the v2 limit counts the root thread as well and does not work alongside agents.max_threads. To give Codex more breathing room, raise the memory allocation at the host, container, or cgroup level. A hard OS limit can kill Codex outright rather than let it slow down under pressure.

Model discovery takes too long: reduce plugins.entries.codex.config.discovery.timeoutMs or switch discovery off. Refer to the Codex harness reference.

WebSocket transport fails right away: verify appServer.url, authToken, headers, and confirm the remote app-server matches the same Codex app-server protocol version. Codex WebSocket transport is still experimental and unsupported; stick with managed stdio or the local Unix control socket instead.

Native shell or patch tools get blocked with Native hook relay unavailable: the Codex thread is still attempting to use a native hook relay id that OpenClaw no longer has on record. This stems from a native Codex hook transport issue, not an ACP backend, provider, GitHub, or shell-command problem. Open a fresh session in the affected chat using /new or /reset, then try a harmless command again. If that works once but the next native tool call fails again, treat /new as a stopgap only: paste the prompt into a new session after restarting the Codex app-server or OpenClaw Gateway so stale threads get discarded and native hook registrations get rebuilt.

Codex tool calls spawn too many short-lived hook processes: configure plugins.entries.codex.config.appServer.loopDetectionPreToolUseRelay: false and restart the gateway. This turns off only the Codex PreToolUse subprocess that handles OpenClaw loop detection and its no-policy marker. Required before_tool_call and trusted-tool policy relays stay active.

A non-Codex model ends up on the built-in harness: that is expected unless provider or model runtime policy routes it elsewhere. Plain non-OpenAI provider refs keep their usual provider path in auto mode.

Computer Use is installed but tools never run: inspect /codex computer-use status from a fresh session. If a tool returns Native hook relay unavailable, apply the native hook relay recovery described above. See Codex Computer Use.

10,737 words · updated Aug 25, 2026