Keep Cua Driver running
Register Cua Driver as a persistent daemon that starts automatically and survives reboots.
External MCP clients and one-shot CLI calls require a daemon. The daemon owns
the per-pid element cache, permission policy, recording and configuration
state, macOS TCC attribution, and the Windows interactive-session context. Keep
it running when you use those interfaces. Applications that import
CuaDriver.create() execute through the same-process SDK and do not need this
setup.
Every entry below starts the daemon in the default standard
permission mode. The mode is fixed at
launch, so a bounded or unrestricted daemon needs that configuration in the
autostart entry itself — see Pin a permission
mode.
cua-driver autostart is not implemented for macOS yet, so write a LaunchAgent instead.
If you have a checkout of the cua repo, the helper script writes it for you (run from the repo root):
bash libs/cua-driver/scripts/install-local.sh --autostartLocal installers embed the checkout's full Git commit in
get_config.source_sha. A build from a modified or untracked source tree uses
<commit>-dirty so it cannot be mistaken for an exact commit build. Source
snapshots without .git must provide CUA_DRIVER_SOURCE_SHA explicitly.
If you installed via the one-line installer and have no checkout, create the plist yourself. Save this file at ~/Library/LaunchAgents/com.trycua.cua-driver.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.trycua.cua-driver</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/CuaDriver.app/Contents/MacOS/cua-driver</string>
<string>serve</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>Load the LaunchAgent:
launchctl load ~/Library/LaunchAgents/com.trycua.cua-driver.plistA LaunchAgent daemon starts under launchd and is attributed to com.trycua.driver. Grant Accessibility and Screen Recording once, and those grants persist across reboots. If you start prompts from a terminal without a LaunchAgent, macOS attributes them to the terminal instead of the driver, so the grants do not apply to Cua Driver.
Pin a permission mode#
--permission-mode, --capability-manifest, --approve-capability-manifest, and
--dangerously-bypass-approvals are read once, when the daemon starts. Put them
in the autostart entry so an unattended restart comes back in the same mode
instead of falling back to standard.
Add each flag as its own <string> inside ProgramArguments, after serve:
<key>ProgramArguments</key>
<array>
<string>/Applications/CuaDriver.app/Contents/MacOS/cua-driver</string>
<string>serve</string>
<string>--permission-mode</string>
<string>bounded</string>
<string>--capability-manifest</string>
<string>/Users/you/cua-session.yaml</string>
<string>--approve-capability-manifest</string>
</array>launchd does not expand ~ or run a shell, so the manifest path must be
absolute. Reload the agent after editing:
launchctl unload ~/Library/LaunchAgents/com.trycua.cua-driver.plist
launchctl load ~/Library/LaunchAgents/com.trycua.cua-driver.plistEvery form is trusted launch configuration: anyone who can edit the plist, the
Scheduled Task, the systemd unit, or those environment variables can change the
mode the daemon comes back in. Bad configuration fails startup rather than
silently downgrading to standard — a bounded daemon with no approved manifest,
or unrestricted without its acknowledgement, does not bind its action socket
at all. Confirm the daemon is up, then make one call your manifest does not
allow and check that it is refused:
cua-driver status
cua-driver call <a tool outside allow.tools> '{}'
# Error: ...Verify it's running#
cua-driver status
# Cua Driver daemon is running
# socket: /Users/you/Library/Caches/cua-driver/cua-driver.sock
# pid: 12345On Windows the socket path is \\.\pipe\cua-driver and status also reports the session number.
Stop it cleanly#
cua-driver stopThis sends a shutdown signal to the daemon process. The autostart entry, whether LaunchAgent, Scheduled Task, or systemd unit, remains registered and starts it again on the next logon or trigger.