- Added window discovery, targeting, and frame validation for macOS, Windows, and Linux platforms. - Updated computer tool and protocol definitions to support listing and targeting specific application windows. - Refactored native computer tool exposure to function-only representation across models. - Updated documentation and test suites to reflect window-scoped computer control capabilities.
6.4 KiB
Tool approval mode
Tool approval has two independent inputs:
- Tool declaration — every tool may declare an
approvaltier:read: reads data or updates UI-only session metadata.write: mutates workspace/session state but does not execute arbitrary code.exec: executes code, shells out, drives a browser, spawns agents, or performs similarly broad actions.
- User policy —
tools.approval.<toolName>: allow | deny | promptoverrides the mode for that tool unless a non-yolo safety override forces a prompt.
Tools without an approval declaration are treated as exec. This is the safe default for unknown custom tools. MCP server tools declare write.
Modes
Configure with tools.approvalMode:
| Mode | Auto-approves | Prompts for |
|---|---|---|
always-ask |
read |
write, exec |
write |
read, write |
exec |
yolo (default) |
read, write, exec |
none |
--auto-approve and --yolo force tools.approvalMode: yolo for the session.
User overrides
tools.approval is honored in every mode:
tools:
approvalMode: write
approval:
bash: prompt
read: allow
mcp__filesystem__delete: deny
Resolution per tool call:
- Compute the tool's approval decision from
tool.approval(args); omitted meansexec. - Normalize
tools.approval.<tool>if present; invalid values are ignored. - In
yolomode, the user policy is used when present; otherwise the call is allowed. Safetyoverridereasons do not force a prompt inyolo. - In non-yolo modes, if the tool sets
override: true,denyis blocked and all other cases prompt, even if user policy saysallow. - Otherwise, a valid user policy wins.
- Otherwise, the active mode auto-approves or prompts by tier.
Safety overrides
A tool can force a prompt with object-form approval:
approval: { tier: "exec", override: true, reason: "Critical pattern detected" }
bash uses this for critical destructive patterns such as rm -rf /, fork bombs, remote-fetch-then-execute, writes to /etc/passwd, and host shutdown commands. These surface as reason in the approval prompt, but in yolo mode they are auto-approved unless a user policy for the tool is set to prompt or deny.
Computer safety
The disabled-by-default computer tool chooses its tier from the complete ordered batch:
- batches containing only
screenshotandwaituseread; - any pointer or keyboard action uses
exec; - missing or malformed actions conservatively use
exec.
The selected window and ordered action summaries appear in the approval prompt. Numeric window targeting preserves the foreground app and real pointer, but it still sends real input to the chosen application and can cause side effects.
Tool approval does not authorize the underlying real-world action. On-screen text is untrusted and cannot override direct user instructions. Consequential actions still require point-of-risk confirmation of the exact target, scope, and values unless the user's direct message already authorized them.
Per-tool prompt details
Tools can add approval-prompt body lines with formatApprovalDetails(args). The standard prompt includes:
Allow tool: <name>Origin: MCP server toolfor unannotatedmcp__...toolsReason: <reason>when the tool decision supplies one- tool-specific details such as command, path, code, browser action, or subagent assignment
Defining approval on tools
Built-in and custom tools share the same shape:
export type ToolTier = "read" | "write" | "exec";
export type ToolApprovalDecision = ToolTier | { tier: ToolTier; reason?: string; override?: boolean };
export type ToolApproval = ToolApprovalDecision | ((args: unknown) => ToolApprovalDecision);
approval?: ToolApproval;
formatApprovalDetails?: (args: unknown) => string | string[] | undefined;
Examples:
approval: "read";
approval: (args) => (LSP_READONLY_ACTIONS.has(args.action) ? "read" : "write");
approval: (args) =>
isCritical(args.command)
? { tier: "exec", override: true, reason: "Critical pattern detected" }
: "exec";
ACP sessions
ACP (omp acp) uses the same settings resolver as normal OMP launches. Global ~/.omp/agent/config.yml applies, project config for the ACP session cwd applies, and any --config <file> overlays passed to the ACP server process apply to sessions created by that process.
To auto-approve ACP tool calls, set the mode in global or project config:
tools:
approvalMode: yolo
Or launch the ACP server with a runtime override or a one-process config overlay:
omp acp --yolo
omp acp --auto-approve
omp acp --approval-mode yolo
omp acp --config ./acp-yolo.yml # file contains tools.approvalMode: yolo
Precedence is the normal settings precedence: runtime flags (--approval-mode, --auto-approve, --yolo) override --config overlays, which override project config, which overrides global config. ACP does not currently define a session/new, session/load, or session/resume approval-policy field, so ACP clients that need per-session yolo should launch a separate omp acp process with one of the flags above or with a session-specific --config overlay.
tools.approvalMode: yolo fully applies to ACP when it is explicitly configured or supplied by a runtime flag. It skips OMP's approval prompts and also skips the ACP client permission gate for bash, edit, delete, and move unless tools.approval.<tool> is prompt or deny. The schema default is yolo, but default-config ACP sessions still keep the client permission gate; set tools.approvalMode: yolo explicitly when the client wants unattended execution.
When ACP approval is required, OMP routes it through the ACP client instead of the terminal TUI. Client-gated bash, edit, delete, and move calls use ACP session/request_permission; generic approval prompts use form elicitation when the client advertises elicitation.form. A rejected, cancelled, or unsupported prompt rejects/cancels the tool call; OMP does not silently allow it.
Subagents
Subagents run headless with tools.approvalMode: yolo so they do not stall waiting for UI. The parent task approval is the authorization boundary. User tools.approval.<tool> settings continue to control whether a tool is allowed, prompted, or blocked.