codex plugin.
For setup and routing decisions, start with
Codex harness.
Plugin config surface
All Codex harness settings live underplugins.entries.codex.config.
Supervision
Native session discovery lists non-archived Codex sessions from the Gateway computer and opted-in paired nodes by default. Disable only that catalog with:supervision separately controls agent-facing tools:
Endpoint entries accept these fields:
The Codex Sessions page uses the plugin’s supervision App Server and shows
only non-archived sessions. Without explicit
appServer connection settings,
that connection is managed user-home stdio. Stored or idle local rows can create
a model-locked Chat with bounded user and assistant history through the last
terminal persisted source turn. Its private binding keeps the snapshot fork,
canonical appServer-source branch, history injection, and later turns on that
connection. The first canonical start uses the pair returned by the fork. Later
resumes omit OpenClaw model and provider overrides so Codex restores the
canonical thread’s persisted pair; a separate native change can update that
pair, but the outer model and fallback chain never replace it. Stored and idle
rows can be archived after no-other-runner confirmation, unless another active
OpenClaw binding owns the exact target or one of its non-archived spawned
descendants. OpenClaw follows Codex’s descendant pagination and fails closed on
enumeration errors, cycles, or safety-limit exhaustion. Confirmation still
covers unknown native clients and the status-to-archive race. A supervised
model-locked Chat cannot be deleted while it protects the native binding.
Active sources cannot create a branch or be archived, but an existing supervised
Chat can still be opened. Every paired-node row stays read-only; the node
transport does not yet provide the streaming lifecycle needed by the harness.
appServer.homeScope: "user" alone changes which Codex home a managed harness
process uses; it does not publish the fleet catalog. Enabling supervision does
not change the harness default. Instead, the separate supervision connection
defaults to managed user-home stdio when no explicit appServer
connection settings exist. Explicit settings are honored for that connection.
Pending and committed supervised bindings retain that connection for every turn;
disabled supervision or connection/lifecycle drift fails closed instead of
falling back to the agent-home harness. The default connection shares stored
sessions with native Codex clients, not their process-local activity state.
Legacy plugins.entries.codex-supervisor settings are retired. Run
openclaw doctor --fix to migrate the old entry, endpoint definitions, policy
flags, and plugin allow/deny references into this block. Explicit canonical
codex.config.supervision values win conflicts.
App-server transport
For ordinary harness turns, OpenClaw starts the managed Codex binary shipped with the official plugin (currently@openai/codex 0.144.3):
codex plugin instead of
whichever separate Codex CLI happens to be installed locally. Set
appServer.command only when you intentionally want a different executable.
Ordinary managed turns with the default isolated agent home prefer this pinned
package even when a macOS desktop bundle is installed. When
Computer Use is enabled, or when homeScope is
"user" and can load native Computer Use state, managed startup instead prefers
the desktop app binary that owns the required macOS permissions. The same
desktop-first rule applies when an isolated agent home’s effective Codex config
enables native Computer Use. If no desktop app bundle is installed, OpenClaw
falls back to the pinned package binary.
Executable handoff and native-config fencing coordinate clients inside one
running Gateway process. Restart the Gateway after another process changes the
native Codex plugin config.
Supervision resolves a separate connection. With no explicit
appServer connection settings, it uses managed stdio with homeScope: "user";
the ordinary harness remains managed stdio with homeScope: "agent". Explicit
connection settings are honored by both paths. Set homeScope: "user"
explicitly when the ordinary harness should share $CODEX_HOME (or ~/.codex)
with native clients. A private supervised binding uses the supervision
connection regardless of the ordinary harness default. Independent App Server
processes retain separate live status and approval state.
For an already-running app-server, use WebSocket transport:
appServer fields:
appServer.networkProxy is explicit because it changes the Codex sandbox
contract. When enabled, OpenClaw also sets features.network_proxy.enabled and
default_permissions in the Codex thread config so the generated permission
profile can start Codex-managed networking. OpenClaw generates a
collision-resistant openclaw-network-<fingerprint> profile name from the
profile body by default; use profileName only when a stable local name is
required.
danger-full-access, enabling
networkProxy uses workspace-style filesystem access for the generated
permission profile instead. Codex-managed network enforcement is sandboxed
networking, so a full-access profile would not protect outbound traffic.
The plugin blocks older or unversioned app-server handshakes: Codex app-server
must report stable version 0.143.0 or newer.
OpenClaw treats non-loopback WebSocket app-server URLs as remote and requires
identity-bearing WebSocket auth through appServer.authToken or an
Authorization header. appServer.authToken and each appServer.headers.*
value can be a SecretInput; the secrets runtime resolves SecretRefs and env
shorthand before OpenClaw builds app-server start options, and unresolved
structured SecretRefs fail before any token or header is sent. When native
Codex plugins are configured, OpenClaw uses the connected app-server’s plugin
control plane to install or refresh those plugins and then refreshes app
inventory so plugin-owned apps are visible to the Codex thread. app/list is
still the authoritative inventory and metadata source, but OpenClaw policy
decides whether thread/start sends config.apps[appId].enabled = true for a
listed accessible app even if Codex currently marks it disabled. Unknown or
missing app ids remain fail-closed; this path only activates marketplace
plugins via plugin/install and refreshes inventory. Only connect OpenClaw to
remote app-servers that are trusted to accept OpenClaw-managed plugin installs
and app inventory refreshes.
Approval and sandbox modes
Local stdio app-server sessions default to YOLO mode:approvalPolicy: "never", approvalsReviewer: "user", and
sandbox: "danger-full-access". This trusted local operator posture lets
unattended OpenClaw turns and heartbeats make progress without native approval
prompts that nobody is around to answer.
If Codex’s local system requirements file disallows implicit YOLO approval,
reviewer, or sandbox values, OpenClaw treats the implicit default as guardian
instead and selects allowed guardian permissions. tools.exec.mode: "auto"
also forces guardian-reviewed Codex approvals and does not preserve unsafe
legacy approvalPolicy: "never" or sandbox: "danger-full-access" overrides;
set tools.exec.mode: "full" for an intentional no-approval posture.
Hostname-matching [[remote_sandbox_config]] entries in the same requirements
file are honored for the sandbox default decision.
Set appServer.mode: "guardian" for Codex guardian-reviewed approvals:
guardian preset expands to approvalPolicy: "on-request",
approvalsReviewer: "auto_review", and sandbox: "workspace-write" when those
values are allowed. Individual policy fields override mode. The older
guardian_subagent reviewer value is still accepted as a compatibility alias,
but new configs should use auto_review.
When an OpenClaw sandbox is active, the local Codex app-server process still
runs on the Gateway host. OpenClaw therefore disables Codex native Code Mode,
user MCP servers, and app-backed plugin execution for that turn instead of
treating Codex host-side sandboxing as equivalent to the OpenClaw sandbox
backend. Shell access is exposed through OpenClaw sandbox-backed dynamic tools
such as sandbox_exec and sandbox_process when the normal exec/process tools
are available.
On Docker-backed OpenClaw sandbox hosts (
agents.defaults.sandbox.mode set to
a Docker backend), openclaw doctor probes whether the host allows the
unprivileged user (and, when Docker sandbox network egress is disabled,
network) namespaces that nested Codex bwrap needs for workspace-write
shell execution inside the sandbox container. A failed probe usually surfaces
as bwrap: setting up uid map: Permission denied or
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted on
Ubuntu/AppArmor hosts. Fix the reported host namespace policy for the OpenClaw
service user and restart the gateway; prefer a scoped AppArmor profile for the
service process over the host-wide
kernel.apparmor_restrict_unprivileged_userns=0 fallback, and do not grant
broader Docker container privileges just to satisfy nested bwrap.Sandboxed native execution
The stable default is fail-closed: active OpenClaw sandboxing disables native Codex execution surfaces that would otherwise run from the Codex app-server host. UseappServer.experimental.sandboxExecServer: true only when you want
to try Codex’s remote environment support with OpenClaw’s sandbox backend.
This preview path works with every supported Codex app-server version.
Auth and environment isolation
In the default per-agent home, auth is selected in this order:- An explicit OpenClaw Codex auth profile for the agent.
- The app-server’s existing account in that agent’s Codex home.
- For local stdio app-server launches only,
CODEX_API_KEY, thenOPENAI_API_KEY, when no app-server account is present and OpenAI auth is still required.
CODEX_API_KEY and OPENAI_API_KEY from
the spawned Codex child process. That keeps Gateway-level API keys available
for embeddings or direct OpenAI models without making native Codex app-server
turns bill through the API by accident.
Explicit Codex API-key profiles and local stdio env-key fallback use
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.
Stdio app-server launches inherit OpenClaw’s process environment by default.
OpenClaw owns the Codex app-server account bridge and sets CODEX_HOME to a
per-agent directory under that agent’s OpenClaw state. That keeps Codex
config, accounts, plugin cache/data, and thread state scoped to the OpenClaw
agent instead of leaking in from the operator’s personal ~/.codex home.
Set appServer.homeScope: "user" to share native Codex state with Codex
Desktop and the CLI. This local user-home mode supports managed stdio and
explicit Unix transport. It uses $CODEX_HOME when set and ~/.codex
otherwise, including native auth, config, plugins, and threads.
OpenClaw skips its auth-profile bridge for the app-server. Verified owner
turns can use codex_threads to list (with an optional search filter),
read, fork, rename, archive, and unarchive those threads. Fork a thread before
continuing it in OpenClaw; independent Codex processes do not coordinate
concurrent writers for the same thread.
That homeScope opt-in applies to ordinary harness sessions. A Chat created
through Codex Sessions uses its private supervision connection instead, which
preserves the native connection’s auth and provider configuration for the
canonical branch and future resumes.
In a model-locked supervised Chat, codex_threads cannot attach a different
fork or archive the Chat’s bound native thread. List and metadata-only read
remain available. Raw transcript reads require allowRawTranscripts; when it
is disabled, list search is also rejected because native search can match
transcript previews. Rename, unarchive, detached fork, and archive of an
unrelated thread not owned by another OpenClaw Chat require
allowWriteControls. Neither option bypasses a locked binding.
OpenClaw does not rewrite HOME for normal local app-server launches.
Codex-run subprocesses such as openclaw, gh, git, cloud CLIs, and shell
commands see the normal process home and can find user-home config and
tokens. Codex may also discover $HOME/.agents/skills and
$HOME/.agents/plugins/marketplace.json; that .agents discovery is
intentionally shared with the operator home and is separate from isolated
~/.codex state.
In the default agent scope, OpenClaw plugins and OpenClaw skill snapshots
still flow through OpenClaw’s own plugin registry and skill loader; personal
Codex ~/.codex assets do not. If you have useful Codex CLI skills or
plugins from a Codex home that should become part of an isolated OpenClaw
agent, inventory them explicitly:
appServer.clearEnv:
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.
Dynamic tools
Codex dynamic tools default tosearchable loading, exposed under the
openclaw namespace with deferLoading: true. OpenClaw normally does not
expose dynamic tools that duplicate Codex-native workspace operations or
Codex’s own tool-search surface:
readwriteeditapply_patchexecprocessupdate_plantool_calltool_describetool_searchtool_search_code
exec and process tools as the shell
fallback. Runtime allowlists and codexDynamicToolsExclude still apply.
Most remaining OpenClaw integration tools, such as messaging, media, cron,
browser, nodes, gateway, heartbeat_respond, and web_search, are available
through Codex tool search under that namespace. This keeps the initial model
context smaller. A small set of tools stay directly callable regardless of
codexDynamicToolsLoading, because Codex tool search can be unavailable or
resolve a connector-only universe: agents_list, sessions_spawn, and
sessions_yield. Developer instructions still steer normal Codex subagents
toward native spawn_agent for Codex-native subagent work, while
sessions_spawn remains available for explicit OpenClaw or ACP delegation.
Message-tool-only source replies also stay direct, since that is a
turn-control contract.
Tools marked catalogMode: "direct-only", including the OpenClaw computer
tool, are grouped under openclaw_direct. OpenClaw adds that namespace to
Codex’s code_mode.direct_only_tool_namespaces list without replacing
operator-supplied entries. Codex therefore exposes those tools as
DirectModelOnly in normal and code-mode-only threads instead of routing them
through nested Code Mode tools.* calls. This boundary is required for
image-bearing results: nested Code Mode serialization flattens image output to
text, which would discard the screenshot needed for the next computer action.
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.
Timeouts
OpenClaw-owned dynamic tool calls are bounded independently fromappServer.requestTimeoutMs. Each Codex item/tool/call request uses the
first available timeout in this order:
- A positive per-call
timeoutMsargument. - For
image_generate,agents.defaults.imageGenerationModel.timeoutMs. - For
image_generatewithout a configured timeout, the 120 second image-generation default. - For the media-understanding
imagetool,tools.media.image.timeoutSecondsconverted to milliseconds, or the 60 second media default. For image understanding, this applies to the request itself and is not reduced by earlier preparation work. - For the
messagetool, a fixed 120 second default. - The 90 second dynamic-tool default.
item/tool/call budget. Provider-specific
request timeouts run inside that call and keep their own timeout semantics.
Dynamic tool budgets are capped at 600000 ms. 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.
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 post-tool budget also extends
the progress watchdog for the silent synthesis window before Codex emits the
next current-turn event. 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. 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.
Model discovery
By default, the Codex plugin asks the app-server for available models. Model availability is owned by Codex app-server, so the list can change when OpenClaw upgrades the bundled@openai/codex version or when a deployment
points appServer.command at a different Codex binary. Availability can also
be account-scoped. Use /codex models on a running gateway to see the live
catalog for that harness and account.
If discovery fails or times out, OpenClaw uses a bundled fallback catalog:
The current bundled harness is
@openai/codex 0.144.3. A model/list probe
against that bundled app-server returned these public picker rows:The app-server catalog can report
ultra; OpenClaw reasoning controls currently
expose levels through max.Live picker rows are account-scoped and can change with the account, Codex
catalog, or bundled version; run /codex models for the current list rather
than relying on any point-in-time table. Hidden models can also appear in the
app-server catalog for internal or specialized flows without being normal
model-picker choices.plugins.entries.codex.config.discovery:
Workspace bootstrap files
Codex handlesAGENTS.md itself through native project-doc discovery.
OpenClaw does not write synthetic Codex project-doc files or depend on Codex
fallback filenames for persona files, because Codex fallbacks only apply when
AGENTS.md is missing.
For OpenClaw workspace parity, the Codex harness forwards the other
bootstrap files as developer instructions, but not identically:
TOOLS.mdis forwarded as inherited Codex developer instructions, so native Codex subagents spawned during the turn also see it.SOUL.md,IDENTITY.md, andUSER.mdare forwarded as turn-scoped collaboration instructions. Native Codex subagents do not inherit them, which keeps subagent turns from picking up the parent agent’s persona and user profile.- The compact loaded OpenClaw skills list is also forwarded as turn-scoped collaboration developer instructions, so native Codex subagents do not inherit it either.
HEARTBEAT.mdcontent is not injected; heartbeat turns get a collaboration-mode pointer to read the file when it exists and is non-empty.MEMORY.mdcontent from the configured agent workspace is not pasted into native Codex turn input when memory tools are available for that workspace; when it exists, the harness adds a small workspace-memory pointer to turn-scoped collaboration developer instructions and Codex should usememory_searchormemory_getwhen durable memory is relevant. If tools are disabled, memory search is unavailable, or the active workspace differs from the agent memory workspace,MEMORY.mduses the normal bounded turn-context path instead.BOOTSTRAP.md, when present, is forwarded as OpenClaw turn input reference context.
Environment overrides
Environment overrides remain available for local testing:OPENCLAW_CODEX_APP_SERVER_BINOPENCLAW_CODEX_APP_SERVER_ARGSOPENCLAW_CODEX_APP_SERVER_MODE=yolo|guardianOPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICYOPENCLAW_CODEX_APP_SERVER_SANDBOX
OPENCLAW_CODEX_APP_SERVER_BIN bypasses the managed binary when
appServer.command is unset.
OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1 was removed. Use
plugins.entries.codex.config.appServer.mode: "guardian" instead, or
OPENCLAW_CODEX_APP_SERVER_MODE=guardian for one-off local testing. Config is
preferred for repeatable deployments because it keeps the plugin behavior in
the same reviewed file as the rest of the Codex harness setup.