Codex Harness Plugin: Run Embedded Agent Turns Through Codex App-Server

This page explains how the official codex plugin routes embedded OpenAI agent turns through the Codex app-server. It is intended for developers using OpenClaw who need to configure Codex for agent session management.

Read this when

  • You want to use the official Codex app-server harness
  • You need Codex harness config examples
  • You want Codex-only deployments to fail instead of falling back to OpenClaw

The official codex plugin routes embedded OpenAI agent turns through the Codex app-server instead of the default OpenClaw harness. Codex manages the low-level agent session: native thread resumption, native tool continuation, native compaction, and app-server execution. OpenClaw continues to own chat channels, session files, model selection, OpenClaw dynamic tools, approvals, media delivery, and the visible transcript mirror.

Use standard OpenAI model references like openai/gpt-5.6-sol. Avoid configuring legacy Codex GPT references; place OpenAI agent authentication order under auth.order.openai. Legacy Codex auth profile IDs and legacy Codex auth order entries are corrected by openclaw doctor --fix.

When the provider/model runtime policy is unset or set to auto, the openai/* prefix alone never activates this harness. OpenAI may implicitly select Codex only for an exact official HTTPS Platform Responses or ChatGPT Responses route without an authored request override. Refer to OpenAI implicit agent runtime. If Codex owns authentication before Platform versus ChatGPT routing is determined, OpenClaw still requires every candidate route to declare Codex compatibility. Native auth ownership alone never bypasses that route check.

When no OpenClaw sandbox is active, OpenClaw launches Codex app-server threads with Codex native code mode enabled (code-mode-only remains off by default), so native workspace and code capabilities stay available alongside OpenClaw dynamic tools routed through the app-server item/tool/call bridge. An active OpenClaw sandbox or restricted tool policy disables native code mode entirely unless you opt into the experimental sandbox exec-server path.

With the default tools.exec.host: "auto" and no active OpenClaw sandbox, Codex also receives node_exec and node_process tools for commands on paired nodes. The native shell remains on the Codex app-server host and workspace (Gateway-local for the default stdio deployment); node_exec selects a node by name or ID and keeps OpenClaw's node approval policy in force. If a finite runtime allowlist disables native Code Mode and leaves the turn without an execution environment, OpenClaw keeps its policy-filtered exec and process tools available instead for direct, unsandboxed execution.

This Codex-native feature 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, and runtime split, start with Agent runtimes: openai/gpt-5.6-sol is the model reference, codex is the runtime, and Telegram, Discord, Slack, or another channel is the communication surface.

Requirements

  • The official @openclaw/codex plugin is installed. Include codex in plugins.allow if your configuration uses an allowlist.
  • A stable Codex app-server from 0.143.0 through 0.145.0. The plugin manages a compatible binary by default, so a codex command on PATH does not affect normal startup.
  • Codex authentication through 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 authentication precedence, environment isolation, custom app-server commands, model discovery, and the full configuration 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 select an OpenAI agent model:

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

If your configuration uses plugins.allow, add codex there too:

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

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

Share threads with Codex Desktop and CLI

The default appServer.homeScope: "agent" isolates each OpenClaw agent from the operator's native Codex state. To let an owner inspect and manage the same native threads shown by Codex Desktop and the Codex CLI, opt into the user Codex home:

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

User-home mode supports a local managed stdio process or the shared Unix-socket transport. It uses $CODEX_HOME when set and ~/.codex otherwise, including that home's native Codex authentication, configuration, plugins, and thread store. OpenClaw does not inject an OpenClaw auth profile into this app-server.

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 stays 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 control the fleet catalog. Native session discovery is enabled while the plugin is active; set sessionCatalog.enabled: false to remove it from the OpenClaw sidebar without disabling Codex. The catalog uses 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
Activate the harnessplugins.entries.codex.enabled: trueOpenClaw config
Suppress native Codex session detectionplugins.entries.codex.config.sessionCatalog.enabled: falseCodex plugin config
Preserve an allowlisted plugin installationInclude codex in plugins.allowOpenClaw config
Let eligible OpenAI turns implicitly use CodexExact official HTTPS Responses/ChatGPT route, no authored request override, runtime unset/autoOpenAI provider/model config
Authenticate via ChatGPT/Codex OAuthopenclaw models auth login --provider openaiCLI auth profile
Add API-key fallback for Codex operationsopenai:* API-key profile listed after subscription auth in auth.order.openaiCLI auth profile + OpenClaw config
Fail closed when Codex is unreachableProvider or model agentRuntime.id: "codex"OpenClaw model/provider config
Route traffic through the direct OpenAI APIProvider or model agentRuntime.id: "openclaw" with normal OpenAI authOpenClaw model/provider config
Adjust app-server behaviorplugins.entries.codex.config.appServer.*Codex plugin config
Enable native Codex plugin applicationsplugins.entries.codex.config.codexPlugins.*Codex plugin config
Enable Codex Computer Useplugins.entries.codex.config.computerUse.*Codex plugin config

Use auth.order.openai for the subscription-first/API-key-backup ordering. Existing legacy Codex auth profile IDs and legacy Codex auth order are doctor-only legacy state; do not create new legacy Codex GPT references.

{
  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 selects credentials, not the runtime. Changing auth order does not make a custom, Completions, HTTP, or request-overridden route Codex-compatible.

Compaction

Do not set compaction.model or compaction.provider on Codex-backed agents. 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.

Lossless remains supported 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 need pre-prompt assembly; generic CLI backends, including codex-cli, do not provide that host capability.

For Codex-backed agents, /compact starts 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. Reserving the full output allowance leaves a derived 922000 token input budget. Requests above 272000 input tokens use OpenAI's higher long-context pricing.

Start from a complete Codex model catalog compatible with the installed Codex version. For each direct GPT-5.5 or GPT-5.6 entry that should use long context, 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 about 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-terra"
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. 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: "openai/gpt-5.6-terra",
      models: {
        "openai/gpt-5.6-terra": { agentRuntime: { id: "codex" } },
      },
    },
  },
}

Replace openai:api-key with the actual API-key profile id if needed. The agent-scoped app-server receives only that prepared key; the operator's native ~/.codex ChatGPT login, plugins, connectors, and thread store remain untouched. Codex app-server 0.144.6 does not attach a command-auth custom provider's bearer on app-server turns, so use the injected API-key path above rather than homeScope: "user" for this route.

After changing the catalog or app-server arguments, restart the Gateway and start a fresh chat. 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.

Warning

Long context is deliberately opt-in. OpenAI bills the entire request at 2× input and 1.5× output rates once input exceeds 272000 tokens. The API remains authoritative for access, actual limits, and billing. See OpenAI model limits and API pricing.

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

Verify Codex runtime

Use /status in the chat where you expect Codex. A Codex-backed OpenAI agent turn shows:

Runtime: OpenAI Codex

Then check Codex app-server state:

/codex status
/codex models
/codex binding

/codex binding displays the attached native thread along with current model configuration details. /codex status shows app-server connectivity status, account information, rate limits, MCP servers, and skills. /codex models presents the live Codex app-server catalog specific to the harness and account. If /status produces unexpected results, refer to Troubleshooting.

Routing and model selection

Maintain separation between provider references and runtime policy:

  • Use openai/gpt-* for canonical OpenAI model selection. The prefix by itself never triggers Codex selection.
  • When runtime is not set or equals auto, Codex can only be selected implicitly through an exact official HTTPS Platform Responses or ChatGPT Responses route that has no authored request override.
  • Avoid legacy Codex GPT references in configuration; run openclaw doctor --fix to fix legacy references and stale session route pins.
  • agentRuntime.id: "codex" enforces Codex as a fail-closed requirement for a compatible route. It cannot make an incompatible effective route compatible.
  • agentRuntime.id: "openclaw" opts a provider or model into the embedded OpenClaw runtime when that is the intended behavior.
  • /codex ... manages native Codex app-server conversations from chat.
  • ACP/acpx represents a separate external harness path. Use it only when the user requests ACP/acpx or an external harness adapter.
User intentUse
Attach the current chat/codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]
Resume an existing Codex thread/codex resume <thread-id>
List or filter Codex threads/codex threads [filter]
Read or update the bound thread's native goal/codex goal [status|set <objective>|pause|resume|block|complete|clear]
List native Codex plugins/codex plugins list
Enable or disable a configured native Codex plugin/codex plugins enable <name>, /codex plugins disable <name>
Resume a stored Codex CLI session as a paired-node turn/codex sessions --host <node> [filter], then /codex resume <session-id> --host <node> --bind here
View non-archived Codex sessions across computersEnable Codex supervision and open Codex Sessions
Change the bound thread's model, fast-mode, or permissions/codex model <model>, /codex fast [on|off|status], /codex permissions [default|yolo|status]
Stop or steer the active turn/codex stop, /codex steer <text>
Detach the current binding/codex detach (alias /codex unbind)
Send Codex feedback only/codex diagnostics [note]
Start an ACP/acpx taskACP/acpx session commands, not /codex
Use caseConfigureVerifyNotes
Eligible OpenAI route with native Codex runtimeExact official HTTPS Responses/ChatGPT route with no authored request override, plus enabled codex plugin/status shows Runtime: OpenAI CodexImplicit path when runtime is unset/auto
Fail closed if Codex is unavailableProvider or model agentRuntime.id: "codex"Turn fails instead of embedded fallbackUse for Codex-only deployments
Direct 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 adheres to the same prefix separation. Apply openai/gpt-* for the standard OpenAI route and codex/gpt-* only when image understanding must go through a bounded Codex app-server turn. Doctor converts legacy Codex GPT references to openai/gpt-*.

Deployment patterns

Basic Codex deployment

Apply the quickstart configuration for an OpenAI model whose effective official HTTPS route qualifies for implicit Codex selection:

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

Mixed provider deployment

Keep Claude as the default agent and introduce a named Codex agent:

{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    defaults: {
      model: "anthropic/claude-opus-4-6",
    },
    list: [
      {
        id: "main",
        default: true,
        model: "anthropic/claude-opus-4-6",
      },
      {
        id: "codex",
        name: "Codex",
        model: "openai/gpt-5.6-sol",
      },
    ],
  },
}

The main agent follows its normal provider path. The codex agent uses the Codex app-server when its effective OpenAI route remains compatible; add explicit model-scoped agentRuntime.id: "codex" when this 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,
      },
    },
  },
}

When Codex is 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 considers WebSocket transport 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}",
          },
        },
      },
    },
  },
}

Local stdio app-server sessions start with the trusted local operator posture by default: approvalPolicy: "never", approvalsReviewer: "user", and sandbox: "danger-full-access". If local Codex requirements do not permit that implicit YOLO posture, OpenClaw picks allowed guardian permissions instead. When an OpenClaw sandbox is active for the session, OpenClaw turns off Codex native Code Mode, user MCP servers, and app-backed plugin execution for that turn, rather than relying on Codex host-side sandboxing. Shell access then uses OpenClaw sandbox-backed dynamic tools like 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 approvalPolicy: "on-request", approvalsReviewer: "auto_review", and sandbox: "workspace-write" when local requirements permit those values. In tools.exec.mode: "auto", OpenClaw does not preserve legacy unsafe Codex approvalPolicy: "never" or sandbox: "danger-full-access" overrides; use tools.exec.mode: "full" for an intentional no-approval Codex posture. The legacy plugins.entries.codex.config.appServer.mode: "guardian" preset still functions, but tools.exec.mode: "auto" is the normalized OpenClaw surface.

For the mode-level comparison with host exec approvals and ACPX permissions, see Permission modes. For every app-server field, auth order, environment isolation, and timeout behavior, see Codex harness reference.

Commands and diagnostics

The codex plugin registers /codex as a slash command on any channel that supports OpenClaw text commands.

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

Common forms:

  • /codex status checks app-server connectivity, models, account, rate limits, MCP servers, and skills.
  • /codex models lists live Codex app-server models.
  • /codex threads [filter] lists recent Codex app-server threads.
  • /codex goal reads or updates the attached thread's native Codex goal. Codex automatic goal continuation stays disabled; OpenClaw does not own autonomous follow-on turns yet.
  • /codex resume <thread-id> attaches 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) detaches the current binding.
  • /codex binding describes the current binding.
  • /codex stop stops the active turn; /codex steer <text> steers it.
  • /codex model <model>, /codex fast [on|off|status], and /codex permissions [default|yolo|status] change per-conversation state.
  • /codex compact asks Codex app-server to compact the attached thread.
  • /codex review starts Codex native review for the attached thread.
  • /codex diagnostics [note] asks before sending Codex feedback for the attached thread.
  • /codex account shows account and rate-limit status.
  • /codex mcp lists Codex app-server MCP server status.
  • /codex skills lists Codex app-server skills.
  • /codex plugins list, /codex plugins enable <name>, and /codex plugins disable <name> manage configured native Codex plugins.
  • /codex computer-use [status|install] manages Codex Computer Use.
  • /codex help lists the full command tree.

For most support reports, start with /diagnostics [note] in the conversation where the bug happened. It creates one Gateway diagnostics report and, for Codex harness sessions, asks for approval to send the relevant Codex feedback bundle. See Diagnostics export for the privacy model and group chat behavior. Use /codex diagnostics [note] only when you specifically want the Codex feedback upload for the currently attached thread without the full Gateway diagnostics bundle.

Inspect Codex threads locally

The fastest way to inspect a bad Codex run is often to open the native Codex thread directly:

codex resume <thread-id>

Get the thread id from the completed /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 selected in this order:

  1. Ordered OpenAI authentication profiles for the agent, ideally located under auth.order.openai. Execute openclaw doctor --fix to migrate outdated legacy Codex auth profile IDs and their ordering.
  2. The app-server's current account within that agent's designated Codex home directory.
  3. Solely for local stdio app-server startups, apply CODEX_API_KEY, then OPENAI_API_KEY, when no app-server account exists and OpenAI authentication is still necessary.

Upon detecting a ChatGPT subscription-style Codex auth profile, OpenClaw strips CODEX_API_KEY and OPENAI_API_KEY from the Codex child process it spawns. This ensures Gateway-level API keys stay available for embeddings or direct OpenAI model calls without inadvertently billing native Codex app-server turns through the API. Explicit Codex API-key profiles and the local stdio env-key fallback rely on app-server login rather than inherited child-process environment variables. WebSocket app-server connections do not receive Gateway environment API-key fallback; use an explicit auth profile or the remote app-server's own account.

When a subscription profile reaches a Codex usage limit, OpenClaw logs the reset time reported by Codex and attempts the next ordered auth profile for that same Codex run. Once the reset time elapses, the subscription profile becomes available again without altering the selected openai/gpt-* model or Codex runtime.

If native Codex plugins are configured, OpenClaw installs or updates those plugins through the connected app-server before making plugin-owned apps available to the Codex thread. app/list remains the authoritative source for app IDs, accessibility, and metadata, but OpenClaw controls the per-thread enablement decision: when policy permits a listed accessible app, OpenClaw sends thread/start.config.apps[appId].enabled = true even if app/list currently marks that app as disabled. This process does not create app installations for unknown IDs; OpenClaw only activates marketplace plugins with plugin/install and then refreshes the inventory.

Environment isolation

For local stdio app-server launches, OpenClaw assigns CODEX_HOME to a per-agent directory so Codex configuration, authentication and account files, plugin cache and 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 locate user-home configuration 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 requires 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 remains pointed at the selected agent or user scope, and HOME stays inherited so subprocesses can use normal user-home state.

Codex dynamic tools default to searchable loading. OpenClaw normally does not expose dynamic tools that duplicate Codex-native workspace operations: read, write, edit, apply_patch, exec, process, update_plan, get_goal, create_goal, update_goal, tool_call, tool_describe, tool_search, and tool_search_code. Goal operations remain native to Codex, so OpenClaw does not project a second goal store into Codex turns. Most remaining OpenClaw integration tools, such as messaging, media, cron, browser, nodes, gateway, and heartbeat_respond, are accessible through Codex tool search under the openclaw namespace, keeping the initial model context smaller. The restricted-turn shell fallback is the exception for exec and process when a finite allowlist disables native Code Mode; runtime allowlists and codexDynamicToolsExclude still apply.

Tools marked catalogMode: "direct-only", including the OpenClaw computer tool, use the openclaw_direct namespace instead. Codex treats that namespace as DirectModelOnly, so those tools stay directly model-visible in normal and code-mode-only threads rather than crossing nested Code Mode tools.* calls.

Web search uses Codex's hosted web_search tool by default when search is enabled and no managed provider is selected. Native hosted search and OpenClaw's managed web_search dynamic tool are mutually exclusive so managed search cannot bypass native domain restrictions. OpenClaw uses the managed tool when hosted search is unavailable, explicitly disabled, or replaced by a selected managed provider. OpenClaw keeps Codex's standalone web.run extension disabled because production app-server traffic rejects its user-defined web namespace. tools.web.search.enabled: false disables both paths, as do tool-disabled LLM-only runs. Codex treats "cached" as a preference and resolves it to live external access for unrestricted app-server turns. Automatic managed fallback fails closed when native allowedDomains are set so the allowlist cannot be bypassed. Persistent effective search-policy changes rotate the bound Codex thread before the next turn; transient per-turn restrictions use a temporary restricted thread and preserve the existing binding for later resume.

sessions_yield, sessions_spawn, and message-tool-only source replies remain direct because they act as turn control or delegation contracts. Guidance continues to favor Codex's built-in spawn_agent as the main Codex subagent surface, while explicit OpenClaw or ACP delegation stays directly invocable through sessions_spawn. In Codex Code Mode, generic OpenClaw dynamic tool results appear as JSON text rather than JavaScript objects, so parse any JSON-like results before accessing fields. Codex also serializes nested dynamic calls; submit several sessions_spawn calls in a bounded loop instead of expecting Promise.all to run them in parallel. Already accepted children can still overlap while later calls are submitted. Check Swarm for the full pattern.
Heartbeat collaboration instructions direct Codex to look for heartbeat_respond before ending a heartbeat turn when the tool is not yet loaded.

Only set codexDynamicToolsLoading: "direct" when connecting to a custom Codex app server that cannot search deferred dynamic tools, or when debugging the complete tool payload.

Config fields

Supported top-level Codex plugin fields:

FieldDefaultMeaning
codexDynamicToolsLoading"searchable"Use "direct" to place OpenClaw dynamic tools directly into the initial Codex tool context.
codexDynamicToolsExclude[]Extra OpenClaw dynamic tool names to exclude from Codex app server turns.
codexPluginsdisabledNative Codex plugin or 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" launches Codex; an explicit "unix" attaches to the local control socket; "websocket" links to url.
homeScope"agent""agent" separates ordinary harness state per OpenClaw agent. "user" is an explicit opt-in that shares the native $CODEX_HOME or ~/.codex, uses native auth, and enables owner-only thread management. User scope supports local stdio or Unix transport. For the separate supervision connection, an unset value resolves to "user" for stdio or Unix and "agent" for WebSocket.
commandmanaged Codex binaryExecutable for stdio transport. Leave unset to use the managed binary; set it only for an explicit override.
args["app-server", "--listen", "stdio://"]Arguments for stdio transport.
urlunsetWebSocket App Server URL or unix:// URL. An empty explicit Unix path selects the canonical user-home control socket.
authTokenunsetBearer token for WebSocket transport. Accepts a literal string or SecretInput such as ${CODEX_APP_SERVER_TOKEN}.
headers{}Extra WebSocket headers. Header values accept literal strings or SecretInput values, for example x-codex-client-session-token: "${CODEX_CLIENT_SESSION_TOKEN}".
clearEnv[]Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. OpenClaw keeps the selected CODEX_HOME and inherited HOME for local launches.
codeModeOnlyfalseOpt into Codex's code-mode-only tool surface. Ordinary OpenClaw dynamic tools remain available through nested tools.* calls; openclaw_direct tools stay directly model-visible.
remoteWorkspaceRootunsetRemote Codex app-server workspace root. When set, OpenClaw infers the local workspace root from the resolved OpenClaw workspace, preserves the current cwd suffix under this remote root, and sends only the final app-server cwd to Codex. If the cwd is outside the resolved OpenClaw workspace root, OpenClaw fails closed instead of sending a gateway-local path to the remote app-server.
requestTimeoutMs60000Timeout for app-server control-plane calls.
turnCompletionIdleTimeoutMs60000Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for turn/completed.
turnAssistantCompletionIdleTimeoutMs10000Quiet window after a final/non-commentary assistant item or pre-tool raw assistant completion arms the assistant-output release while OpenClaw still waits for turn/completed. Raising it gives Codex more time to emit turn/completed before OpenClaw interrupts and releases the session lane.
postToolRawAssistantCompletionIdleTimeoutMs300000Completion-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. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget.
mode"yolo" unless local Codex requirements disallow YOLOPreset for YOLO or guardian-reviewed execution. Local stdio requirements that omit danger-full-access, never approval, or the user reviewer make the implicit default guardian.
approvalPolicy"never" or an allowed guardian approval policyNative Codex approval policy sent to thread start/resume/turn. Guardian defaults prefer "on-request" when allowed.
sandbox"danger-full-access" or an allowed guardian sandboxNative Codex sandbox mode sent to thread start/resume. Guardian defaults prefer "workspace-write" when allowed, otherwise "read-only". When an OpenClaw sandbox is active, danger-full-access turns use Codex workspace-write with network access derived from the OpenClaw sandbox egress setting.
approvalsReviewer"user" or a permitted guardian reviewerWith "auto_review", Codex can examine native approval prompts when allowed; otherwise, fall back to guardian_subagent or user. The older alias guardian_subagent is still supported.
serviceTiernot setSpecifies an optional service tier for the Codex app server. "priority" activates fast-mode routing, "flex" requests flexible processing, null removes the override, and the legacy value "fast" is treated as "priority".
networkProxydisabledEnables Codex permissions-profile networking for app-server commands. OpenClaw defines the chosen permissions.<profile>.network configuration and picks it using default_permissions instead of transmitting sandbox.
experimental.sandboxExecServerfalseAn opt-in preview that registers a sandbox-backed Codex environment with the supported Codex app server, allowing native Codex execution within the active OpenClaw sandbox.

appServer.networkProxy is made explicit because it modifies the Codex sandbox contract. When turned on, OpenClaw also sets features.network_proxy.enabled and default_permissions in the Codex thread configuration so the generated permission profile can initiate Codex managed networking. By default, OpenClaw generates a collision-resistant openclaw-network-<fingerprint> profile name from the profile body; use profileName only when a stable local name is necessary.

{
  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 normal app-server runtime would be danger-full-access, enabling networkProxy applies workspace-style filesystem access for the generated permission profile: Codex managed network enforcement is sandboxed networking, so a full-access profile would not protect outbound traffic. Domain entries use allow or deny; Unix socket entries use Codex's allow or none values.

Dynamic tool call timeouts

OpenClaw-owned dynamic tool calls have their own limits separate from appServer.requestTimeoutMs: Codex item/tool/call requests default to a 90 second OpenClaw watchdog. A positive per-call timeoutMs argument adjusts that specific tool budget, with a maximum of 600000 ms. The image_generate tool uses agents.defaults.mediaModels.image.timeoutMs when the tool call lacks its own timeout, otherwise it falls back to a 120 second image-generation default. The media-understanding image tool uses the selected image-capable tools.media.models[] entry's timeoutSeconds or its 60 second media default; for image understanding, that timeout applies to the request itself and is not reduced by earlier preparation work. On timeout, OpenClaw aborts the tool signal where supported and returns a failed dynamic-tool response to Codex so the turn can continue instead of leaving the session in processing. This watchdog is the outer dynamic item/tool/call budget; provider-specific request timeouts run inside that call and keep their own timeout semantics.

After Codex accepts a turn, and after OpenClaw responds to a turn-scoped app-server request, the harness expects Codex to make current-turn progress and eventually finish the native turn with turn/completed. If the app-server goes quiet for appServer.turnCompletionIdleTimeoutMs, OpenClaw best-effort interrupts the Codex turn, records a diagnostic timeout, and releases 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 proven the turn is still alive.

Tool handoffs use a longer post-tool idle budget: after OpenClaw returns an item/tool/call response, after native tool items such as commandExecution complete, after raw custom_tool_call_output completions, and after post-tool raw assistant progress, raw reasoning completions, or reasoning progress. The guard uses appServer.postToolRawAssistantCompletionIdleTimeoutMs when configured and defaults to five minutes otherwise; that same budget also extends 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 releasing 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

  • OPENCLAW_CODEX_APP_SERVER_BIN bypasses the managed binary when appServer.command is not set.
  • 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 has been removed. Switch to plugins.entries.codex.config.appServer.mode: "guardian" instead, or OPENCLAW_CODEX_APP_SERVER_MODE=guardian for one-off local testing. Configuration is recommended for repeatable deployments because it keeps the plugin behavior in the same reviewed file as the rest of the Codex harness setup.

Native Codex plugins

The Codex plugin runs natively within the same thread as the OpenClaw harness turn, leveraging the app and plugin capabilities of the Codex app-server directly. OpenClaw does not convert Codex plugins into synthetic codex_plugin_* OpenClaw dynamic tools.

codexPlugins only applies to sessions using the native Codex harness. It does not impact built-in harness runs, standard OpenAI provider sessions, ACP conversation bindings, or any other harness type.

A minimal migrated configuration looks like this:

{
  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 configuration is determined when OpenClaw initiates a Codex harness session or refreshes an expired Codex thread binding; it is not recalculated for each turn. After modifying codexPlugins, run /new, /reset, or restart the gateway so subsequent Codex harness sessions begin with the updated app set.

For details on migration eligibility, app inventory, destructive action policy, elicitations, and native plugin diagnostics, refer to Native Codex plugins.

Access to OpenAI-side apps and plugins depends on the signed-in Codex account and, for Business and Enterprise/Edu workspaces, workspace app controls. See Using Codex with your ChatGPT plan for OpenAI's overview of account and workspace controls.

Computer Use

Computer Use has its own setup documentation: Codex Computer Use.

In brief: OpenClaw does not bundle the desktop-control application or perform desktop actions directly. It prepares the Codex app-server, confirms that the computer-use MCP server is available, and then allows Codex to handle native MCP tool calls during Codex-mode turns.

Runtime boundaries

The Codex harness modifies only the low-level embedded agent executor.

  • OpenClaw dynamic tools are fully supported. Codex requests that OpenClaw execute these tools, so OpenClaw stays in the execution path.
  • Codex-native shell, patch, MCP, and native app tools are managed by Codex. OpenClaw can monitor or block specific native events through the supported relay, but it does not modify native tool arguments.
  • Codex handles native compaction. OpenClaw maintains a transcript mirror for channel history, search, /new, /reset, and future model or harness switching, but does not substitute Codex compaction with an OpenClaw or context-engine summarizer.
  • Media generation, media understanding, TTS, approvals, and messaging-tool output continue through the corresponding OpenClaw provider and model settings.
  • tool_result_persist applies to OpenClaw-owned transcript tool results, not to 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 does not appear as a standard /model provider: this is expected for new configurations. Choose an openai/gpt-* model, activate plugins.entries.codex.enabled, and verify whether plugins.allow excludes codex.

OpenClaw uses the built-in harness instead of Codex: confirm the effective route is an exact official HTTPS Platform Responses or ChatGPT Responses route, has no authored request override, and the Codex plugin is installed and enabled. The openai/gpt-* prefix alone is insufficient. For strict proof during 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: gather 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 typically 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: execute 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 a stable Codex app-server from 0.143.0 through the bundled 0.145.0. Prereleases, build-suffixed versions, and newer unvalidated releases are rejected because OpenClaw validates generated schemas against the bundled app-server version.

/codex status cannot connect: verify 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: first distinguish the two processes. 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. 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 limits native child threads for the bundled Codex default multi-agent backend. If you explicitly enable Codex multi-agent v2, use features.multi_agent_v2.max_concurrent_threads_per_session=3 instead; the v2 limit includes the root thread and cannot be combined with agents.max_threads. For more Codex headroom, increase the host, container, or cgroup memory allocation. An OS hard limit can terminate Codex rather than backpressure it.

Model discovery is slow: lower plugins.entries.codex.config.discovery.timeoutMs or disable discovery. See Codex harness reference.

WebSocket transport fails immediately: check appServer.url, authToken, headers, and that the remote app-server speaks the same Codex app-server protocol version. Codex WebSocket transport remains experimental and unsupported; prefer managed stdio or the local Unix control socket.

Native shell or patch tools are blocked with Native hook relay unavailable: the Codex thread is still trying to use a native hook relay id that OpenClaw no longer has registered. This is a native Codex hook transport problem, not an ACP backend, provider, GitHub, or shell-command failure. Start a fresh session in the affected chat with /new or /reset, then retry a harmless command. If that works once but the next native tool call fails again, treat /new as a temporary workaround only: copy the prompt into a fresh session after restarting the Codex app-server or OpenClaw Gateway so old threads are dropped and native hook registrations are recreated.

Excessive short-lived hook processes from Codex tool calls: configure plugins.entries.codex.config.appServer.loopDetectionPreToolUseRelay: false and then reboot the gateway. This deactivates only the Codex PreToolUse subprocess responsible for OpenClaw loop detection along with its no-policy marker. The necessary before_tool_call and trusted-tool policy relays stay active.

Built-in harness used by a non-Codex model: this is the default unless a provider or model runtime policy directs it elsewhere. In auto mode, plain non-OpenAI provider references continue on their usual provider path.

Computer Use installed but tools fail to execute: run /codex computer-use status from a new session. When a tool returns Native hook relay unavailable, apply the native hook relay recovery described above. Refer to Codex Computer Use.