Cua Docs

Telemetry and privacy

Exact Cua Driver telemetry controls, event schema, and privacy boundaries.

Cua Driver sends content-free product telemetry to the PostHog EU ingest endpoint. Telemetry is enabled by default. The installer prints a notice before it sends the first event, and the preference persists across driver processes and upgrades.

If an installation or release event fails, the driver leaves its success marker unset and waits 15 minutes before retrying. Commands during that interval do not wait for another telemetry request.

Control telemetry#

cua-driver telemetry status --json
cua-driver telemetry disable
cua-driver telemetry enable

An environment override takes precedence over the saved preference:

CUA_DRIVER_RS_TELEMETRY_ENABLED=false cua-driver mcp

Disabling telemetry stops telemetry requests. It does not delete the local installation ID, so enabling telemetry later resumes the same pseudonymous installation identity. A normal uninstall also preserves the ID and saved preference. To create a new identity, run:

cua-driver telemetry reset-id

Use uninstall --purge when uninstalling if you also want to remove retained Cua Driver state.

Separate update check#

The telemetry setting does not control Cua Driver's update check. On mcp, serve, and doctor startup, Cua Driver may make a content-free request to the public GitHub Releases API and cache the result locally for 20 hours. This request does not include the telemetry installation ID or command usage.

Disable the update check separately when you need to prevent that GitHub request and cache write:

CUA_DRIVER_RS_UPDATE_CHECK=false cua-driver mcp

Set the same environment variable in your MCP server configuration to keep the update check disabled across sessions.

Inspect events locally#

inspect builds the event without sending a network request. It replaces the installation ID with a redacted placeholder.

cua-driver telemetry inspect cua_driver_mcp_session_started --json
cua-driver telemetry inspect cua_driver_mcp_tool_completed --json
cua-driver telemetry inspect cua_driver_agent_session_started --json
cua-driver telemetry inspect cua_driver_agent_session_ended --json

Common client event properties#

Every schema-v3 client event has this fixed envelope:

PropertyMeaning
telemetry_schema_versionFixed integer 3
product_versionInstalled Cua Driver version
os_familymacos, windows, linux, or other
os_majorMajor operating-system version only
archBounded CPU architecture
is_ciWhether a recognized CI environment is present
is_syntheticExplicit Cua-owned test marker; false by default
transportcli, daemon, mcp_stdio, mcp_http, or unknown
process_session_idRandom ID created once per process and never persisted
id_persistedWhether the installation ID came from durable local state

Client events set $process_person_profile to false. The installation UUID is used only as the PostHog distinct_id; it is not duplicated into event properties. This is pseudonymous installation telemetry, not anonymous telemetry.

The client does not send an IP address as an event property. PostHog derives a country code and country name from the network request during ingestion, then discards the client IP before storing the event. A country-only transformation removes continent, city, subdivision, postal-code, coordinate, accuracy-radius, and time-zone properties.

Fixed events#

EventAdditional bounded properties
cua_driver_installation_registeredinstall_channel
cua_driver_release_installedinstall_channel, product_version
cua_driver_serveNone. Transitional process-start event for cua-driver serve; transport is daemon
cua_driver_cli_completedFixed command, allowlisted tool for call, bounded operation, computer_action, bounded MCP client_kind, success, exit_class, and duration_bucket
cua_driver_mcp_startup_completedexecution path, bounded daemon state, success, duration bucket, and execution_mode
cua_driver_mcp_session_startednormalized MCP client and protocol, capability booleans, optional reported agent context, and execution_mode
cua_driver_mcp_tool_completedallowlisted tool, bounded compound-tool operation, computer_action, protocol success, error class, structured-refusal code, duration bucket, output shape and size buckets, and execution_mode
cua_driver_agent_session_starteddeclaration kind, revival flag, concurrent-session bucket, entry transport, client kind, capture scope, and execution_mode
cua_driver_agent_session_endedend reason, duration and count buckets, browser-refusal bucket, success flags, feature-family flags, multi-transport flag, client kind, capture scope, bounded auto-escalation outcome, and execution_mode
cua_driver_permissions_gate_startedmissing-permission booleans
cua_driver_permissions_gate_dismissedmissing-permission booleans and duration bucket
cua_driver_permissions_gate_completedmissing-permission booleans, panel and dismissal flags, fixed resolution, and duration bucket
cua_driver_update_checkedfixed source and outcome, strict public target release version or unknown, and cache-hit flag
cua_driver_update_apply_startedstrict public target release version and whether a daemon was running
cua_driver_update_apply_completedstrict public target release version or unknown, fixed outcome and failure class, prior daemon state, and duration bucket

The transitional cua_driver_serve event carries the common event properties and no additional properties. It does not contain command arguments or process output.

The legacy cua_driver_install event remains part of lifetime registration dashboards so existing installations are not registered a second time.

Reported model and agent context#

An MCP host can explicitly report agent context in the initialize request:

{
  "params": {
    "_meta": {
      "ai.cua/agent-context": {
        "provider": "anthropic",
        "model": "claude-sonnet-4-5",
        "agent_name": "claude-code",
        "agent_version": "1.x"
      }
    }
  }
}

These values are self-reported and normalized through allowlists. Unknown values become custom or unknown. Cua Driver does not infer a model from the MCP client name, does not use MCP Sampling to identify the parent model, and does not collect the complete initialize payload. Stdio emits once per process. A long-lived HTTP process emits once per normalized client category, so the event measures HTTP client-category adoption rather than every connection.

Cua agent sessions#

A Cua agent session is one lifecycle episode owned by a trusted transport. It may have an optional public session label, but telemetry never sends that label or the runtime's private transport identity.

The start event is emitted for a successful start_session or the first admitted session-requiring call on a transport. Its declaration is start_session or implicit_first_action. Repeated calls in the same live episode do not emit another start. Explicitly reviving an ended public label creates a new episode with revived=true.

The end event is emitted for explicit end, idle expiry, transport cleanup, and revocation. It contains aggregate counters and booleans. When the platform has a cursor entry, the event includes bounded cursor categories: enabled state, built-in/default/custom icon class, automatic/custom color source, label presence, motion customization, and an active-cursor count bucket. cursor_outcome_observed=false distinguishes a missing cursor entry from a disabled or default cursor.

Both session events carry the closed client_kind (cli, direct, mcp, python_sdk, or typescript_sdk). The Python and TypeScript package roots select their category automatically; applications cannot attach a free-form client label. execution_mode independently distinguishes embedded from standalone hosts. The end event adds used_window_modality and used_desktop_modality, which are content-free booleans derived from admitted calls.

capture_scope, auto_escalated_to_desktop, and escalation_reason remain bounded compatibility fields for legacy capture-scope sessions. New per-call targets do not mutate session capture state. Free-form escalation detail is never observed or sent.

Computer-action success covers fixed pointer and keyboard capabilities, app launch and kill, window activation, state-changing page operations, and successful browser navigation, click, type, pointer, file-assignment, download, or dialog-resolution calls. A structured browser refusal does not count as a completed computer action. get_browser_state and browser_dialog inspection are reads for this classifier, and browser_prepare is tracked as browser use rather than a computer action because preparation may either reuse an endpoint or produce an approved visible side effect.

The end event includes used_browser and a bounded browser_refusal_count_bucket. It does not include browser targets, pages, profiles, or per-site information.

Per-call computer_action is derived from the same fixed classifier used by the session aggregate. It describes the tool category; combine it with success=true when measuring value. Cua-owned automated tests can set CUA_DRIVER_TELEMETRY_SYNTHETIC=true. This marks every event from that process with is_synthetic=true so product metrics can exclude test traffic without relying on installation IDs. Third-party CI remains independently identified by is_ci.

For finite CLI commands, operation distinguishes only reviewed verbs for recording, permissions, config, autostart, skills, and update. client_kind is populated only for mcp-config. Unknown values become other; commands without a meaningful sub-operation use not_applicable.

Update funnel#

Explicit CLI and MCP update checks emit cua_driver_update_checked. Its source is cli or mcp; its outcome is up_to_date, available, or unavailable. Background checks emit only available on the freshness-bounded network path, rather than on every startup. Cached startup banners do not emit another event.

cua-driver update --apply emits cua_driver_update_apply_started immediately before launching the canonical installer and cua_driver_update_apply_completed after the attempt. Completion outcomes are installed, already_current, or failed. Failure classes are limited to none, check_failed, installer_exit, or installer_launch; raw errors and exit codes are not collected.

The common product_version is the version that initiated the check or update. target_version is accepted only when it is a strict public SemVer value. The existing cua_driver_release_installed event with install_channel=update_apply independently confirms that the new binary recorded the installed release. Together these events support the funnel from update availability through apply and first use of the installed release.

For the compound page tool, operation is one of execute_javascript, get_text, query_dom, click_element, insert_text, type_keystrokes, enable_javascript_apple_events, or other.

Typed browser tools use these reviewed operation values:

Tooloperation values
get_browser_statebrowser_bind, browser_snapshot_dom_refs_v1, browser_snapshot_semantic_v2, or other
browser_preparebrowser_prepare_isolated, browser_prepare_existing_profile, or other
browser_clickbrowser_click_trusted, browser_click_dom_event, or other
browser_typebrowser_type_insert_text, browser_type_keystrokes, or other
browser_dialogbrowser_dialog_inspect, browser_dialog_accept, browser_dialog_dismiss, or other
browser_set_input_filesbrowser_set_input_files
browser_downloadbrowser_download
browser_pointerAction-and-route values such as browser_pointer_scroll_trusted or browser_pointer_drag_dom_event; invalid combinations become other
browser_navigatenot_applicable; the tool name already identifies the operation

Structured browser refusals#

A browser refusal is a successful MCP exchange with a behavioral result of refused. The tool-completion event therefore keeps success=true and error_class=none, while refusal_code records one closed, content-free code. The allowed values are:

  • none
  • browser_route_unavailable
  • browser_requires_setup
  • browser_binding_ambiguous
  • browser_binding_stale
  • browser_wrong_target_refused
  • browser_tab_required
  • browser_tab_not_found
  • browser_ref_stale
  • browser_input_trust_unavailable
  • browser_endpoint_owner_mismatch
  • browser_consent_required
  • browser_consent_revoked
  • browser_reconnect_exhausted
  • browser_input_incomplete
  • browser_action_unavailable
  • other for an unrecognized future refusal until it is reviewed for telemetry

browser_consent_revoked indicates only that the browser consent flow was dismissed or denied. It does not include who acted, the browser profile, the prompt contents, or any associated page state.

Data that is never collected#

Routine telemetry excludes task text, prompts, tool arguments, tool response bodies, typed text, screenshots, accessibility trees, window titles, application names, free-form client labels, escalation detail, file paths, URLs, arbitrary MCP metadata, raw cursor IDs, labels, colors, icon paths, numeric motion values, and raw error messages. Browser telemetry also excludes target, tab, frame, ref, process, window, and session identifiers; profile names and paths; queries and coordinates; approval tokens; endpoint URLs and ports; refusal messages and details; and requested or delivered text lengths.

Tool-completion events retain only coarse result shape: text, image, mixed, empty, or unknown; a size bucket; a duration bucket; a fixed error class; and, for reviewed structured browser refusals, the fixed code above. The content itself never crosses the telemetry observer boundary. A proxy and daemon negotiate one completion-event owner. Mixed-version pairs retain proxy ownership, which prevents duplicate events during upgrades.

To bound client and ingestion load, each Cua Driver process emits at most 1,000 routine tool-completion events in an hour. If that ceiling is reached before a successful computer action, the process may emit that first value event as well. Lifecycle, permissions, and aggregate session events are not subject to this ceiling.

A CLI call is always delegated to the daemon. The daemon owns the completion event and reports transport=daemon, so the event is emitted only once.

Region and deletion controls#

Client events are sent to PostHog's EU ingest endpoint. PostHog processes the request IP long enough to derive country-level distribution, then discards the IP before event storage. Stored telemetry keeps only the derived country code and country name; it excludes continent, city, subdivision, postal code, coordinates, accuracy radius, and time zone. PostHog does not create person profiles for these events.

Retention and server-side deletion are governed by the Cua privacy policy; the client does not enforce a retention window or submit deletion requests. telemetry reset-id and uninstall purge controls remove local identity state only. Do not post the installation UUID in a public issue.