SDK reference
Python and TypeScript packages, constructors, methods, results, and errors for the typed Cua Driver SDK.
Packages#
| Runtime | Package | Import |
|---|---|---|
| Python | cua-driver | from cua_driver import CuaDriver |
| Node.js / TypeScript | @trycua/cua-driver | import { CuaDriver } from "@trycua/cua-driver" |
Both packages are generated from the same Rust and UniFFI contract. Methods are
asynchronous. Python uses snake_case; TypeScript uses camelCase.
Constructors#
| Python | TypeScript | Behavior |
|---|---|---|
CuaDriver.create(options=None) | CuaDriver.create(options?) | Creates the primary same-process runtime. No daemon, executable, or IPC is required. |
CuaDriver.create_configured(options) | CuaDriver.createConfigured(options) | Trusted-host constructor with an immutable runtime ceiling and compatibility mode. |
CuaDriver.create_configured_with_authorization_host(options, host) | CuaDriver.createConfiguredWithAuthorizationHost(options, host) | Adds a trusted host callback for residual authorization boundaries. |
CuaDriver.create_configured_with_activity_observer(options, observer) | CuaDriver.createConfiguredWithActivityObserver(options, observer) | Adds content-free activity events without changing authorization. |
CuaDriver.create_configured_with_host_integrations(options, host, observer) | CuaDriver.createConfiguredWithHostIntegrations(options, host, observer) | Installs both optional host integrations. |
CuaDriver.create_private_worker(options) | CuaDriver.createPrivateWorker(options) | Spawns one supervised process-isolated runtime over inherited pipes; no reusable endpoint is created. |
CuaDriver.connect(socket_path=None) | CuaDriver.connect(socketPath?) | Connects the same typed surface to a daemon. This is a compatibility and app-hosting path. |
DriverOptions currently contains
claude_code_compatibility / claudeCodeCompatibility, which defaults to
false.
create() validates the immutable permission-mode, managed-policy,
user-policy, and bounded-manifest startup configuration before constructing
the native runtime. Every subsequent same-process call passes the same native
authorization coordinator used by daemon-backed calls. An invalid
configuration returns DriverError.Configuration; a denied generic call
returns a tool error with stable code permission_denied.
create_configured() accepts ConfiguredDriverOptions, whose
authorization field is RuntimeAuthorizationOptions: an allowed-mode
set, the compatibility mode inherited by ordinary CuaDriver calls, bounded
manifest path when that compatibility mode is bounded, maximum absolute and
idle session TTLs, and the separate unrestricted-risk acknowledgement.
Applications may create more than one same-process runtime. Each runtime owns
an independent authorization ceiling, session registry, browser bindings,
recording state, and shutdown lifecycle.
Trusted host code may call the top-level create_trusted_session(driver, …) /
createTrustedSession(driver, …) factory and receive a CuaDriverSession.
Keeping the factory separate preserves the released structural
CuaDriverProtocol and CuaDriverLike interfaces. The returned object is
already bound to one immutable authorization context. Its public session
string remains only a lifecycle label: a tool argument cannot select, replay,
or widen the context. Call close() at the host lifecycle boundary; dropping
the object, ending the session, or shutting down the runtime also revokes it.
PrivateWorkerOptions adds the absolute Cua Driver binary path, host identity,
startup and shutdown timeouts, configured runtime options, a safe environment
allowlist, and optional stderr inheritance. Worker configuration is sent after
spawn on the inherited channel rather than in argv. Caller-provided
environment entries cannot set authorization controls; process-admin managed
policy and disablement variables are inherited by both private workers and
embedded services so a child topology cannot relax its parent's ceiling.
Closing the host channel terminates the worker; a worker cannot be discovered
or reattached.
Daemon connect() clients retain the daemon compatibility mode. An embedded
host may create a trusted session only over its original authenticated service
connection; an ordinary or standalone daemon client cannot.
Authorization host#
Routine standard-mode automation does not call the authorization host. The
callback currently handles the existing logged-in Chromium profile boundary.
It receives an attested, expiring request and must return the same
request_digest with Allow, Deny, or Cancel.
Python:
from cua_driver import (
CuaDriver,
DriverAuthorizationAction,
DriverAuthorizationDecision,
DriverAuthorizationHost,
)
class AppAuthorization(DriverAuthorizationHost):
async def authorize(self, request):
allowed = await app_ui.confirm(request.human_summary)
return DriverAuthorizationDecision(
action=(
DriverAuthorizationAction.ALLOW
if allowed
else DriverAuthorizationAction.DENY
),
request_digest=request.request_digest,
)
driver = CuaDriver.create_configured_with_authorization_host(
options,
AppAuthorization(),
)TypeScript:
import {
CuaDriver,
DriverAuthorizationAction,
type DriverAuthorizationHost,
} from "@trycua/cua-driver";
const authorizationHost: DriverAuthorizationHost = {
async authorize(request) {
const allowed = await appUi.confirm(request.humanSummary);
return {
action: allowed
? DriverAuthorizationAction.Allow
: DriverAuthorizationAction.Deny,
requestDigest: request.requestDigest,
};
},
};
const driver = CuaDriver.createConfiguredWithAuthorizationHost(
options,
authorizationHost,
);The callback is trusted application code. Do not expose it as a model tool,
forward resource_json / resourceJson to an agent, or auto-accept every
request. Cua Driver intentionally does not prescribe or render the host UI.
Activity observer#
DriverActivityObserver receives content-free events for authorized actions,
authorization refusals, ordinary action failures, grant issue and revocation,
and session start and end. Events include the tool name, risk class, adapter
IDs, public session label, and stable refusal code. They never include tool
arguments, text, images, URLs, file paths, or attested resource JSON.
The observer cannot authorize, deny, or change a result. Return quickly and hand expensive work to an application queue.
execution_mode() / executionMode() reports the generated
DriverExecutionMode value. The enum variants are Embedded, PrivateWorker,
Daemon, and the Rust-only carrier-backed Remote.
Lifecycle and metadata#
| Python | TypeScript | Result |
|---|---|---|
metadata() | metadata() | Driver version, protocol version, and platform metadata |
execution_mode() | executionMode() | DriverExecutionMode |
is_available() | isAvailable() | Whether the runtime can serve calls |
shutdown() | shutdown() | Stops admission and awaits admitted work |
In TypeScript, shutdown() and uniffiDestroy() have separate jobs:
shutdown() closes runtime admission and awaits admitted operations;
uniffiDestroy() immediately frees the generated UniFFI object handle.
JavaScript's FinalizationRegistry is only a nondeterministic fallback, so
orderly applications call both, in that order. Python finalization releases its
handle automatically, but applications must still await shutdown().
Session methods#
| Python | TypeScript | Input |
|---|---|---|
start_session | startSession | StartSessionInput |
get_session | getSession | GetSessionInput |
list_sessions | listSessions | ListSessionsInput |
end_session | endSession | EndSessionInput |
get_session_state | getSessionState | GetSessionStateInput (deprecated) |
escalate_session | escalateSession | EscalateSessionInput (deprecated) |
start_session is optional. The first ordinary call creates an implicit
session owned by the SDK transport, and later calls on that transport reuse it.
The default idle TTL is five minutes. Shutdown, explicit end, and transport
close run the same cleanup hooks. A call that is still in flight cannot expire,
and only completed calls refresh the idle timer.
For multi-call work, prefer a short public session label and pass the same
value on every call that accepts it. Passing it once is not sticky: a later call
that omits the field uses the transport's implicit session instead. Use
start_session to name or configure a run before acting, or to revive a public
name after it has ended. For one-off or deliberately unlabeled work, omitting
session is valid.
get_session and list_sessions return content-free state only for sessions
visible to that transport. The public label is a map key, never an
authorization credential. A trusted host can inspect its wider runtime
namespace through list_host_sessions_json() / listHostSessionsJson(); agent
tools cannot use that operator view.
StartSessionInput.capture_scope / captureScope, get_session_state, and
escalate_session remain available for legacy capture-scope sessions during
the compatibility window. New code selects a target on each action. There is
no deescalate_session method.
Typed desktop methods#
| Python | TypeScript | Input |
|---|---|---|
get_desktop_state | getDesktopState | GetDesktopStateInput |
get_screen_size | getScreenSize | GetScreenSizeInput |
get_cursor_position | getCursorPosition | GetCursorPositionInput |
move_cursor | moveCursor | MoveCursorInput |
click | click | ClickInput |
drag | drag | DragInput |
scroll | scroll | ScrollInput |
type_text | typeText | TypeTextInput |
press_key | pressKey | PressKeyInput |
hotkey | hotkey | HotkeyInput |
move_cursor, click, drag, scroll, type_text, press_key, and
hotkey accept an ActionTarget / actionTarget on each call:
window: { kind: "window", pid, window_id }
desktop: { kind: "desktop", display_id: "primary" }The desktop target uses screen coordinates and foreground delivery. The window
target uses coordinates from that window's screenshot and keeps the existing
background or foreground delivery ladder. Legacy flat scope, pid, and
window_id fields remain accepted but cannot be combined with target.
Typed cursor methods#
| Python | TypeScript | Input |
|---|---|---|
set_agent_cursor_enabled | setAgentCursorEnabled | SetAgentCursorEnabledInput |
set_agent_cursor_motion | setAgentCursorMotion | SetAgentCursorMotionInput |
set_agent_cursor_theme | setAgentCursorTheme | SetAgentCursorThemeInput |
get_agent_cursor_state | getAgentCursorState | GetAgentCursorStateInput |
Cursor-bearing actions create or wake the transport's implicit session even
when the caller does not supply a public session. Cursor configuration methods
still take a public session label. cua.default is the only built-in theme. A
trusted local operator may validate, compile, and install
a custom theme with cua-driver cursor-theme; agent-facing tools may select an
installed theme ID but cannot install source or compiled theme data. See
Agent cursor themes for the
semantic profile and authoring workflow.
Use list_tools_json() / listToolsJson() and call_tool() / callTool() for
the generic, platform-extensible tool surface. Its top-level
enforcement_adapters array distinguishes active, metadata-only, and
not-exposed permission adapters. Prefer typed methods when one is available.
ToolResult#
Desktop methods return ToolResult.
| Python field | TypeScript field | Meaning |
|---|---|---|
text | text | Human-readable result text |
images | images | Returned images and MIME types |
structured_json | structuredJson | Structured platform result |
is_error | isError | Whether the tool reported failure |
error_code | errorCode | Stable tool error code, when present |
verified | verified | Whether post-action verification succeeded |
degraded | degraded | Whether a reduced-capability path was used |
raw_json | rawJson | Complete extensible result envelope |
Errors#
The generated DriverError variants are:
ConfigurationInvalidArgumentsTransportProtocolToolShutdownRuntimeAlreadyExistsWorkerRemoteActionInterrupted
Tool-level failures may also arrive as ToolResult.is_error / isError.
Inspect the result before consuming images or structured fields.
ActionInterrupted includes an ActionCompletion value: NotStarted,
Completed, or Unknown. Do not automatically retry a non-idempotent action
when completion is unknown.
RuntimeAlreadyExists remains in the stable error vocabulary for hosts or
platform facilities that cannot safely establish another owner. Ordinary
second-runtime creation no longer returns it.
See MCP tools for the agent-facing tool catalog and SDK, MCP, and process hosting for the architecture boundary.