Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/trycua/cua/llms.txt

Use this file to discover all available pages before exploring further.

Cua Driver lets any computer-use agent drive the host desktop — installed apps, signed-in browser sessions, local files, and the current OS user session. MCP-capable agents connect through cua-driver mcp; applications that want an in-process runtime import the Python or TypeScript SDK directly.
This page connects an agent to Cua Driver on the current machine. To create a disposable isolated desktop instead, use Cua Sandbox.

Before you start

Install Cua Driver, start the daemon, and verify it can see the host desktop:
cua-driver --version
cua-driver call list_apps
On macOS, grant Accessibility and Screen Recording before connecting any agent:
cua-driver permissions status
See Installation for the full setup sequence.

Decide the permission mode first

Registering the MCP server does not choose a permission mode — the process that owns the driver runtime does, at launch. Every config below therefore runs in the default standard mode unless you configure the owning process.
  • macOS: cua-driver mcp proxies to the CuaDriver.app daemon to keep TCC attribution with the app, so that daemon’s launch flags decide the mode. Start it in the mode you want before the client connects, and use autostart to make that persist across reboots.
  • Windows and Linux: bare cua-driver mcp owns its own runtime and has no --permission-mode flag. Either set CUA_DRIVER_PERMISSION_MODE — plus CUA_DRIVER_SESSION_POLICY_FILE and CUA_DRIVER_SESSION_POLICY_APPROVED for bounded — in the client’s env block, or run a cua-driver serve daemon in that mode and point the client at it with --socket.
A standard-mode runtime allows input against every application on the desktop. If an agent should reach only a reviewed set of apps, origins, and directories, register it against a bounded runtime instead — see Permission Modes.

Generate the client config

mcp-config prints the exact registration command or JSON for any supported client:
cua-driver mcp-config --client <client>
The generated output is the source of truth for all supported clients and current command shapes.

Claude Code

Register the standard stdio server:
claude mcp add --transport stdio cua-driver -- cua-driver mcp
claude mcp list
Claude Code also supports a computer-use compatibility profile that exposes driver tools under a cua-computer-use server name. This matches the mcp__cua-computer-use__screenshot tool name that Claude Code uses as its image-grounding cue:
claude mcp add --transport stdio cua-computer-use -- cua-driver mcp --claude-code-computer-use-compat
This keeps all of Cua Driver’s normal MCP tools and changes only screenshot, which in compatibility mode requires pid and window_id and captures that specific window only. Generate the current exact command at any time:
cua-driver mcp-config --client claude

Codex

Print the Codex registration command:
cua-driver mcp-config --client codex
It emits a command using the absolute installed binary path, which avoids PATH issues in app-launched Codex sessions:
codex mcp add cua-driver -- /Users/you/.local/bin/cua-driver mcp
codex mcp list
Restart Codex or open a fresh session after adding the server. For richer agent guidance, also install the Cua Driver skill:
cua-driver skills install
cua-driver skills status

Cursor

Generate the Cursor JSON snippet:
cua-driver mcp-config --client cursor
Paste it into ~/.cursor/mcp.json (global) or .cursor/mcp.json (project scope):
{
  "mcpServers": {
    "cua-driver": {
      "command": "cua-driver",
      "args": ["mcp"],
      "type": "stdio"
    }
  }
}
Restart Cursor and confirm cua-driver appears in the MCP server list.

Generic MCP JSON config

For any client that accepts the standard mcpServers shape, print the generic config:
cua-driver mcp-config
The output is the stdio transport block every compliant MCP client understands:
{
  "mcpServers": {
    "cua-driver": {
      "command": "cua-driver",
      "args": ["mcp"]
    }
  }
}
After saving the config, restart the client and confirm the cua-driver server is connected.

Other supported clients

mcp-config also prints the correct shape for clients that use config files or different add commands:
ClientGenerate withNotes
Antigravitycua-driver mcp-config --client antigravityPaste into ~/.gemini/config/mcp_config.json; --client gemini is a legacy alias.
OpenClawcua-driver mcp-config --client openclawGateway-spawned MCP does not inherit OpenClaw.app’s macOS grants; use the embedded host instead.
OpenCodecua-driver mcp-config --client opencodeConfigure a real MCP server so screenshots are preserved in image blocks.
Hermescua-driver mcp-config --client hermesPaste under mcp_servers and reload MCP servers in Hermes.
Qwen Codecua-driver mcp-config --client qwenSupports both a CLI add command and ~/.qwen/settings.json.
Factory Droidcua-driver mcp-config --client droidSupports CLI and JSON config forms.
ZCodecua-driver mcp-config --client zcodeConfigure MCP in the GUI, or use zai mcp add for the Z.ai CLI.
For clients without a dedicated preset, resolve the absolute path with command -v cua-driver and use the client’s native stdio MCP interface:
# Grok Build
grok mcp add cua-driver -- /absolute/path/to/cua-driver mcp

# Kimi Code CLI
kimi mcp add cua-driver -- /absolute/path/to/cua-driver mcp

Python in-process SDK

Applications that want to embed the runtime directly — without a separate daemon — import the Python SDK. The same native runtime runs in-process through generated UniFFI bindings:
from cua_driver import CuaDriver

async def main():
    driver = await CuaDriver.create()
    apps = await driver.list_apps()
    print(apps)
CuaDriver.create() loads the native runtime in the application process. A daemon is not required for direct application use. The connect() path is retained for clients that want to connect to an external daemon.

TypeScript in-process SDK

import { CuaDriver } from "@trycua/cua-driver";

const driver = await CuaDriver.create();
const apps = await driver.listApps();
console.log(apps);
The TypeScript package exposes the same Rust runtime through the generated UniFFI bindings. Install it with your package manager and import from the package root — there is no /sdk, /mcp, or /native public suffix.
The language packages (cua_driver for Python, @trycua/cua-driver for TypeScript) are for client applications, not for agents. MCP remains implemented by the cua-driver executable as the runtime-neutral agent boundary.

Next steps

Permission Modes

Lock an agent to a bounded manifest or grant unrestricted access.

Background Delivery

Understand how agents act without stealing focus or moving your cursor.

Build docs developers (and LLMs) love