Exec Tool: Shell Commands, Stdin Modes, and TTY Support
Learn how to use the Exec tool to run shell commands within your workspace, including stdin modes, TTY support, and foreground/background execution. Essential for developers automating tasks with Neura Market.
Read this when
- Using or modifying the exec tool
- Debugging stdin or TTY behavior
Execute shell commands within the workspace. exec is a shell surface that mutates state: commands can create, edit, or delete files wherever the chosen host or sandbox filesystem allows. Disabling OpenClaw filesystem tools like write, edit, or apply_patch does not make exec read-only.
Foreground and background execution are supported through process. When process is not permitted, exec runs synchronously and disregards yieldMs/background. Background sessions are scoped per agent; process can only see sessions from the same agent.
Parameters
-
command(string, required), The shell command to execute. -
workdir(string, default: cwd), Sets the working directory for the command. -
env(object), Environment variable overrides as key/value pairs, merged on top of the inherited environment. -
yieldMs(number, default: 10000), Automatically backgrounds the command after this delay in milliseconds. -
background(boolean, default: false), Backgrounds the command right away instead of waiting foryieldMs. -
timeout(number, default: tools.exec.timeoutSeconds), Overrides the configured exec timeout for this call in seconds. Applies to foreground, background,yieldMs, gateway, sandbox, and nodesystem.runexecution.timeout: 0disables the exec process timeout for that call. -
pty(boolean, default: false), Runs inside a pseudo-terminal when one is available. Useful for TTY-only CLIs, coding agents, and terminal UIs. -
host(auto' | 'sandbox' | 'gateway' | 'node, default: auto), Determines the execution location.autoresolves tosandboxwhen a sandbox runtime is active, and togatewayotherwise. -
security(deny' | 'allowlist' | 'full), Ignored for normal tool calls.gateway/nodesecurity is derived fromtools.exec.modeand the host approvals file; elevated mode can enforce full access only when the operator explicitly grants elevated access. -
ask(off' | 'on-miss' | 'always), The baseline ask mode comes fromtools.exec.modeand host approvals. For channel-origin model calls, per-callaskis ignored when the effective host ask isoff; otherwise it can only increase to a stricter mode. -
node(string), Node id or name whenhost=node. -
elevated(boolean, default: false), Requests elevated mode to escape the sandbox onto the configured host path.security=fullis forced only when elevated resolves tofull.
Notes:
- The only accepted values for
hostareauto,sandbox,gateway, ornode. It does not function as a hostname selector; anything that looks like a hostname is refused before execution begins. - Per-invocation
host=nodeis permitted fromauto; per-invocationhost=gatewayis permitted only when no sandbox runtime is active. - Without additional configuration,
host=autostill works out of the box: when no sandbox is present it defaults togateway; when a sandbox is active it remains inside that sandbox. elevatedbreaks out of the sandbox onto the configured host path:gatewayby default, ornodewhentools.exec.host=nodeis set (or the session default ishost=node). It is available only when elevated access is enabled for the current session or provider.- The host approvals file governs
gatewayandnodeapprovals. nodeneeds a paired node, either a companion app or a headless node host. When multiple nodes exist, pick one by settingexec.nodeortools.exec.node.exec host=nodeis the sole shell-execution path for nodes; the oldnodes.runwrapper has been removed.- On non-Windows hosts, exec uses
SHELLwhen that variable is defined; ifSHELLisfish, it first triesbash(orsh) fromPATHto avoid bashisms that break fish, then falls back toSHELLif neither is found. - On Windows hosts, exec looks for PowerShell 7 (
pwsh) by checking Program Files, ProgramW6432, then PATH, and falls back to Windows PowerShell 5.1. - On non-Windows gateway hosts, bash and zsh exec commands use a startup snapshot. OpenClaw captures sourceable aliases, functions, and a small safe environment set from shell startup files into
$OPENCLAW_STATE_DIR/cache/shell-snapshots/, then sources that snapshot before each exec command. Variables that look secret are excluded; sandbox and node exec do not use this snapshot. To disable this snapshot path, setOPENCLAW_EXEC_SHELL_SNAPSHOT=0in the Gateway process environment. - Host execution (
gatewayornode) rejectsenv.PATHand loader overrides (LD_*orDYLD_*) to prevent binary hijacking or injected code. - OpenClaw sets
OPENCLAW_SHELL=execin the spawned command environment (including PTY and sandbox execution) so that shell or profile rules can detect the exec-tool context. - For channel-origin runs, OpenClaw also exposes a narrow sender and chat identity JSON payload in
OPENCLAW_CHANNEL_CONTEXTwhen the channel provided those identifiers. execcannot runopenclaw channels loginor/approveshell commands:openclaw channels loginis an interactive channel-auth flow, and/approvemust go through the approval command handler, not a shell. Run channel login in a terminal on the gateway host, or use a channel-specific login agent tool if one exists (for examplewhatsapp_login).- Important: sandboxing is off by default. When sandboxing is off, implicit
host=autoresolves togateway. Explicithost=sandboxstill fails closed instead of silently running on the gateway host. Either enable sandboxing or usehost=gatewaywith approvals. - Script preflight checks (for common Python and Node shell-syntax mistakes) inspect only files inside the effective
workdirboundary. If a script path resolves outsideworkdir, preflight is skipped for that file. Preflight is also skipped entirely whenhost=gatewayis set and the effective policy issecurity=fullwithask=off. - For long-running work that starts now, start it once and rely on automatic completion wake when it is enabled and the command produces output or fails. Use
processfor logs, status, input, or intervention; do not emulate scheduling with sleep loops, timeout loops, or repeated polling. - Agent-started background commands appear in the Web, iOS, and Android background-task views until they finish. The task ledger is finalized before the completion heartbeat wakes the agent again.
- For work that should happen later or on a schedule, use cron instead of
execsleep or delay patterns.
Config
| Key | Default | Notes |
|---|---|---|
tools.exec.timeoutSeconds | 1800 | The default timeout for each command, measured in seconds. A per-call timeout takes precedence; setting a per-call timeout: 0 removes the exec process timeout entirely. |
tools.exec.host | auto | Evaluates to sandbox when a sandbox runtime is present, otherwise to gateway. |
tools.exec.mode | host-derived | The primary policy setting. Refer to Modes below. |
tools.exec.reviewer.model | configured agent primary | An optional provider or model override used for mode=auto review. |
tools.exec.reviewer.timeoutMs | 30000 | Time limit per stage for reviewer model setup and completion before falling back to a human. |
tools.exec.node | unset | |
tools.exec.notifyOnExit | true | If enabled, backgrounded exec sessions queue a system event and ask for a heartbeat once they exit. |
tools.exec.approvalRunningNoticeMs | 10000 | Emit a single "running" notification when an approval-gated exec exceeds this duration (0 turns it off). |
tools.exec.strictInlineEval | false | Consult Inline eval. |
tools.exec.commandHighlighting | false | When active, approval prompts can highlight parser-derived command spans within the command text. Set globally or per agent; it does not alter approval policy. |
tools.exec.pathPrepend | unset | Directories to add at the front of PATH for exec runs (gateway and sandbox only). |
tools.exec.safeBins | unset | Stdin-only safe binaries that do not require an explicit allowlist entry. See Safe bins. |
tools.exec.safeBinTrustedDirs | /bin, /usr/bin | Additional directories explicitly trusted during safeBins path checks. PATH entries are never auto-trusted. |
tools.exec.safeBinProfiles | unset | Optional custom argv policy per safe bin (minPositional, maxPositional, allowedValueFlags, deniedFlags). |
For gateway and node (mode=full), no-approval host exec is the default. This behavior comes from the host-policy defaults, not from host=auto. To enable approvals or allowlist behavior, configure tools.exec.mode and tighten the host approvals file; see Exec approvals. To force gateway or node routing regardless of sandbox state, set tools.exec.host or use /exec host=....
Example:
{
tools: {
exec: {
pathPrepend: ["~/bin", "/opt/oss/bin"],
},
},
}
Modes
tools.exec.mode serves as the canonical persisted policy knob. Runtime security and approval behavior are derived from it.
| Mode | security | ask | Behavior |
|---|---|---|---|
deny | deny | off | Exec requests are blocked. |
allowlist | allowlist | off | Only commands on the allowlist or safe-bin list execute; no prompts appear for anything else. |
ask | allowlist | on-miss | Commands matching the allowlist run directly; anything not on it triggers a human prompt. |
auto | allowlist | on-miss | Allowlisted and safe-bin commands execute directly; all others pass through OpenClaw's native auto reviewer before a human is asked. |
full | full | off | No approval step is enforced. |
Regardless of the persisted mode, /exec ask=always always prompts a human on a per-session basis.
Auto-review approval applies to a single use only. On the gateway, OpenClaw provides the reviewer with the resolved executable path and locks execution to that same path. Commands that cannot be distilled into a single enforceable execution plan, like heredocs, shell expansions, or unsupported wrapper quoting, fall back to human approval, even if the model would otherwise permit them.
Codex app-server command approvals that are not already decided by explicit runtime or native policy use the human approval route. OpenClaw does not run its configured exec reviewer for these requests because Codex does not expose an enforceable resolved executable that can bind the review decision to the command Codex runs.
Inline eval (strictInlineEval)
When tools.exec.strictInlineEval is set to true, inline interpreter-eval forms require reviewer or explicit approval: python -c, node -e, ruby -e, perl -e, php -r, lua -e, osascript -e, and similar forms across other supported interpreters and command carriers (awk, find -exec, make, sed, xargs, and more). In mode=auto, the normal exec approval path may let the native auto reviewer allow a clearly low-risk one-off command; direct node-host system.run calls still require an explicit approval because they cannot hand the command to a human approval route. If the reviewer asks, the request goes to a human. allow-always can still persist benign interpreter/script invocations, but inline-eval forms do not become durable allow rules.
PATH handling
host=gateway: merges your login-shellPATHinto the exec environment.env.PATHoverrides are rejected for host execution. The daemon itself still runs with a minimalPATH:- macOS:
/opt/homebrew/bin,/usr/local/bin,/usr/bin,/bin - Linux:
/usr/local/bin,/usr/bin,/bin - To prevent user shell configuration (like
~/.zshenvor/etc/zshenv) from overriding priority paths during startup,tools.exec.pathPrependentries are securely prepended to the finalPATHinside the shell command right before execution.
- macOS:
host=sandbox: runssh -lc(login shell) inside the container, so/etc/profilemay resetPATH. OpenClaw prependsenv.PATHafter profile sourcing via an internal env var (no shell interpolation);tools.exec.pathPrependapplies here too.host=node: only non-blocked env overrides you pass are sent to the node.env.PATHoverrides are rejected for host execution and ignored by node hosts. If you need additional PATH entries on a node, configure the node host service environment (systemd/launchd) or install tools in standard locations.
Per-agent node binding (use the keyed agent ID in config):
openclaw config get agents.entries
openclaw config set 'agents.entries.main.tools.exec.node' "node-id-or-name"
Control UI: the Devices page includes a small "Exec node binding" panel for the same settings.
Session overrides (/exec)
Use /exec to define per-session defaults for host, security, ask, and node. Call /exec without any arguments to display the current values.
Example:
/exec host=auto security=allowlist ask=on-miss node=mac-1
/exec applies only to authorized senders via channel allowlists, pairing, and access groups. Access-group enforcement is always active. This updates session state exclusively and does not modify configuration. Authorized external channel senders can establish these session defaults. Internal gateway and webchat clients require operator.admin to make them permanent.
To completely disable exec, deny it through tool policy (tools.deny: ["exec"] or per-agent). Host approvals still take effect unless you explicitly configure security=full and ask=off.
Exec approvals (companion app / node host)
Sandboxed agents can demand per-request approval before exec executes on the gateway or node host. Refer to Exec approvals for the policy, allowlist, and UI workflow.
When human approval is necessary, node-host and non-native gateway flows immediately return status: "approval-pending" along with an approval id. Native chat and Web UI gateway flows can instead wait inline and deliver the final command result after approval. An approval-pending result indicates the command has not started, so foreground fallback warnings appear only if the approved command actually runs inline. Approved asynchronous runs emit command progress and completion system events (Exec running / Exec finished); denied or timed-out approvals are terminal and do not send a denial system event to wake the agent session.
On channels that offer native approval cards or buttons, the agent should prioritize that native UI first and include a manual /approve command only when the tool result explicitly states that chat approvals are unavailable or manual approval is the only option.
Allowlist + safe bins
Manual allowlist enforcement matches resolved binary path globs and bare command-name globs. Bare names match only commands invoked through PATH, so rg can match /opt/homebrew/bin/rg when the command is rg, but not ./rg or /tmp/rg.
When security=allowlist, shell commands are auto-allowed only if every pipeline segment is allowlisted or qualifies as a safe bin. Chaining (;, &&, ||) and redirections are rejected in allowlist mode unless every top-level segment satisfies the allowlist (including safe bins). Redirections remain unsupported. Durable allow-always trust does not bypass this rule: a chained command still requires every top-level segment to match.
autoAllowSkills is a separate convenience path within exec approvals, distinct from manual path allowlist entries. For strict explicit trust, keep autoAllowSkills disabled.
Use the two controls for different purposes:
tools.exec.safeBins: small, stdin-only stream filters.tools.exec.safeBinTrustedDirs: explicit extra trusted directories for safe-bin executable paths.tools.exec.safeBinProfiles: explicit argv policy for custom safe bins.- allowlist: explicit trust for executable paths.
Do not treat safeBins as a generic allowlist, and do not add interpreter or runtime binaries (for example python3, node, ruby, bash). If those are needed, use explicit allowlist entries and keep approval prompts enabled.
openclaw security audit warns when interpreter or runtime safeBins entries lack explicit profiles, and openclaw doctor --fix can scaffold missing custom safeBinProfiles entries. openclaw security audit and openclaw doctor also warn when you explicitly add broad-behavior binaries such as jq back into safeBins (jq can read environment data and load jq code from modules or startup files, so prefer explicit allowlist entries or approval-gated runs instead). jq is denied as a safe bin even when explicitly listed. If you explicitly allowlist interpreters, enable tools.exec.strictInlineEval so inline code-eval forms still require reviewer or explicit approval.
For complete policy details and examples, see Exec approvals and Safe bins versus allowlist.
Examples
Foreground:
{ "tool": "exec", "command": "ls -la" }
Background plus poll:
{"tool":"exec","command":"npm run build","yieldMs":1000}
{"tool":"process","action":"poll","sessionId":"<id>"}
Polling is for on-demand status, not for waiting loops. If automatic completion wake is enabled, the command can wake the session when it emits output or fails.
Send keys (tmux-style):
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["Enter"]}
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["C-c"]}
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["Up","Up","Enter"]}
Submit (send CR only):
{ "tool": "process", "action": "submit", "sessionId": "<id>" }
Paste (bracketed by default):
{ "tool": "process", "action": "paste", "sessionId": "<id>", "text": "line1\nline2\n" }
apply_patch
The apply_patch subtool of exec handles structured modifications across multiple files. It activates automatically and works with any model provider, though allowModels offers a way to limit its use. Only modify the config if you need to turn it off or limit it to particular models:
{
tools: {
exec: {
applyPatch: { workspaceOnly: true, allowModels: ["gpt-5.6-sol"] },
},
},
}
Additional details:
- Tool policy remains in effect;
allow: ["write"]grants implicit permission forapply_patch. deny: ["write"]does not blockapply_patch; to prevent patch writes, explicitly denyapply_patchor applydeny: ["group:fs"].- Configuration resides under
tools.exec.applyPatch. - By default,
tools.exec.applyPatch.enabledis set totrue; switching it tofalsedeactivates the tool. - The default for
tools.exec.applyPatch.workspaceOnlyistrue, which restricts operations to the workspace. Only assignfalsewhen you deliberately needapply_patchto create or delete files outside the workspace directory. tools.exec.applyPatch.allowModelsacts as an optional allowlist for model identifiers (either short, likegpt-5.4, or complete, likeopenai/gpt-5.4). When populated, only the listed models receive the tool; when empty, every model gets access.
Related
- Exec Approvals, gates that require approval for shell commands
- Sandboxing, executing commands inside sandboxed environments
- Background Process, exec and process tools for long-running tasks
- Security, tool policy and privileged access controls