Codex computer use
is the MCP server inside the ChatGPT Mac app's Computer Use plugin.
Claude Code, Cursor, and agy call it under the name
. Clicks go into
the target app. They do not move the user's pointer.
The long write-up is the Claude artifact
. Open it in Arc
when this file does not answer a case.
Setup (once per machine)
Codex does not need this:
is native there. For Claude Code, Cursor
and agy, run the check first:
bash ~/.agents/skills/codex-cu/scripts/check-codex-cu.sh
PASS: setup is done. Skip this section. The check never opens an app, so a
PASS is not proof that an app call works. SKIP with
:
the user must install the ChatGPT Mac app and its Computer Use plugin, then use
computer use there once (that grants Screen Recording and Accessibility). A
FAIL
launcher cannot resolve a usable version
(the installer says SKIP
no usable Computer Use version yet
): show the user the reason text after the colon.
Only a missing or empty plugin cache means "still downloading, try later". In both
cases stop and tell them. Any other FAIL, or no
tool: ASK the user
which mode. Never pick for them:
- : accept every prompt from codex-cu with no question, including any
that is not an app prompt. Logged-in pages in a browser app become readable.
- : auto-accept Calculator, TextEdit, Preview, Freeform. It is an
auto-accept list, not a sandbox: Claude still asks the user for other apps and
the user may accept them; agy and Cursor are refused for other apps. The
browser surface has no per-app approval in either mode.
Then run:
bash ~/.agents/skills/codex-cu/scripts/install-codex-cu.sh all # or: safe
It installs into
, registers
at user scope for Claude
Code and Cursor when their config file exists and for agy when the
command
exists (the check prints a line per registered runtime), writes
~/.config/codex-cu/approve
, and ends with the
check. If you cannot ask (print mode, worker), stop and show the user both
commands. After setup, tell the user to start a new session: MCP servers load
at session start. To switch mode later, run the installer with the other word,
or edit the policy file (it takes effect at the next prompt, no restart).
The installer skips the first gate on purpose. Terminal, system settings and
Codex itself stay
until the user runs
defaults write -g ComputerUseAllowForbiddenTargets -bool YES
themselves.
Two surfaces
Computer surface treats the target as an app. Read the AX tree, then click or
type. This surface does not need turn metadata.
is the
launcher.
Browser surface enters the page. Read the DOM, run JS, use Playwright locators.
Each
needs Codex turn metadata.
injects
_meta["x-codex-turn-metadata"]
. Computer surface does not need the metadata,
but its app approvals also go through the proxy (see below).
can return a full
list and a
error together.
A metadata error on
does not mean the computer surface failed.
Pick Chrome, not Arc
Arc and Chrome both report
. The numeric
is not stable.
can be absent. Do not use either as the only test.
- Call .
- Read
metadata.extensionInstanceId
.
- Confirm the host parent before a long call.
sh
ps -o ppid= -p $(pgrep -f "ChatGPT for Chrome")
The parent path is Arc or Google Chrome. Sample from 2026-10-05. Re-check
after a reload. Do not reuse these values once the parent check disagrees.
- Arc:
33f909be-429f-479e-b1c2-20bba462cbf3
- Chrome:
75ef88d3-a921-455b-b39e-b40ed5ec2771
and
on the Arc instance do not return. A 120s
wait still fails, and the call can leave
.
Browser surface
Use the Chrome instance from the parent check. One
call per step.
cua.getBrowser({ extensionInstanceId })
.
- with a short name, before any new tab.
- Record ids from .
- Open one new tab and go to the URL.
- Check the page. On example.com,
getByRole("link", { name: "Learn more", exact: true })
is visible.
- Close only that tab.
- Read again. Prior ids match. The new id is gone.
A tab stays on the
that created it. A refused
can still leave
. Close it in that same session. Set
on
the proxy when you must reuse the session.
is not available.
URLs are not allowed. There is
no hover method. Browser surface does not ask for per-app approval.
Rehearsal that passed 2026-10-05: select
,
returns
at once,
,
, the new tab is
closed, the prior tab ids are unchanged.
Computer surface
Arc on this surface is an app, not a browser target.
- Open a URL with . Command-T is less stable.
- . Use the display name. Do not use a bundle id.
- After a page change,
getAXState({ disableDiffing: true })
. The first read can show the old page.
- Click by element index. Use when changes case.
and
are not in this runtime.
needs the second approval,
Allow Computer Use to use X?
. The proxy
answers it from
~/.config/codex-cu/approve
, for every client (Claude, agy,
Cursor):
- on its own line: accept every prompt (full mode, the deploy default).
- One display name per line: accept only those apps (safe mode).
- mixed with names means only those names.
- Any other app, or no policy file: the prompt goes to the client. agy and
cursor-agent cannot answer, so the proxy declines it for them. With no file,
every app is refused in agy and Cursor.
- A Claude hook that accepts codex-cu prompts overrides for
forwarded apps. Remove such a hook; the policy file is the single source.
scripts/test-codex-cu-proxy
runs the proxy against a fake child (accept,
forward, child death, slow client, two-way backpressure, bad policy, shutdown).
Shutdown: once the proxy has seen the client close stdin, it drops (and logs)
an approval prompt instead of answering or forwarding it. A prompt already
forwarded can still meet the close.
in the log means the
reply was queued to the child. After the child exits, the proxy waits while
output still reaches the client; after 30 s with no progress it ends non-zero
(output may be incomplete), at most 5 s later if stderr is blocked.
A refusal reads
Computer Use was not approved to use X
. Add the display name
to the file; the next prompt reads it, no restart. The Chrome display name is
.
Do not
WARNING:
returns the window text. Do not bind Notes, Mail, Messages,
Keychain Access, a password manager, or a terminal unless the user names that
app in the current message.
- Do not treat a metadata error as a dead computer surface.
- Do not pick a browser by numeric id.
- Do not call or on the Arc instance.
- Do not close tabs that were already open.
Not tested
Logged-in Chrome pages, a Stop hook that sends
, many Chrome
profiles, Arc and Chrome at the same time, Freeform drag, AppleScript JS
inside Arc, and
over SSH.