adk-computer-use
Give an ADK agent safe, governed control of a real desktop.
This crate is the ADK-Rust orchestration layer for
computer-use-mcp. It does not
perform any desktop actuation itself. The actual clicking, typing, and
screen-reading happens in computer-use-mcp, which remains authoritative for
policy, target validation, control leases, physical-user interruption, and
idempotent (run-once) effects. What lives here is everything you need on the ADK
side to drive that server without becoming the component that decides what is
safe: a deterministic workflow, strongly-typed wire contracts, an authorization
gate wired to your identity, and tamper-evident evaluation receipts.
The problem it solves
Letting an LLM drive a live desktop is high-risk: one wrong action can send an email, delete a file, or approve a payment. This crate makes that risk manageable by wrapping every action in the same fixed, predictable control flow:
- Observe widely, mutate narrowly. Observation (capabilities, screenshot, accessibility tree) runs in parallel, but only one node in the entire graph is ever allowed to mutate anything.
- Preview before acting. Every action is previewed first. Anything that requires human approval pauses the graph at a durable checkpoint rather than proceeding.
- Approval is bound to the action. When you resume after approval, the action is pinned to the exact action and policy digests it was approved for. An approval for one action cannot authorize a different action.
- Authority is rechecked at mutation time. Envelope expiry, approval authority, reservation scope, lease validity, and receipt identity are checked again immediately around the single executor call.
- Reservations have deterministic cleanup. Once acquired, a reservation is released after verification and on every later error path. When the primary operation and cleanup both fail, the returned error records both.
- Identity cannot be forged. The principal and tenant come from
adk-auth, not from model output or graph state, so a prompt cannot change who you are mid-run.
How it fits together
The core of the crate is a deterministic adk-graph workflow you
build with build_reference_graph. It interacts with the outside world through a
single trait, ComputerUseRuntime. In production that trait is backed by a live
MCP server; in tests and the portable example it is a plain Rust struct you write
yourself, with no server, network, or OS dependency.
flowchart TD
START --> discover[discover capabilities]
START --> visual[observe visual]
START --> semantic[observe semantic]
discover --> join[join observations]
visual --> join
semantic --> join
join --> plan
plan --> preview
preview -->|allowed| reserve[reserve target]
preview -->|approval| approval[request approval - interrupt]
preview -->|blocked| blocked
approval --> reserve
reserve --> lease[acquire lease]
lease --> execute[execute - single mutation]
execute --> verify
verify --> END
blocked --> END
Read top to bottom: observe in parallel, join the results, preview, branch to approval when required, acquire the one-writer lease, perform the single mutation, then verify it happened. The reservation is released after verification and on every error after it is acquired.
What's included
| Module | What it provides |
|---|---|
contracts |
The computer-use-mcp MCP server wire types (action, target, approval, receipt, lease, session, safety), each validated so they cannot carry unsafe or disclosing data. |
runtime |
The ComputerUseRuntime trait plus its live MCP adapter, ComputerUseMcpRuntime. |
graph |
build_reference_graph and its checkpointer-aware variant. |
auth |
ScopeAuthorizer and ComputerUseAuthContext — the computer:* scope gate tied to your adk-auth identity. |
cancellation |
CancellationBridge — revokes desktop authority first, then stops the agent. |
eval |
ComputerUseEvaluator and the tamper-evident AdkEvaluationReceipt. |
error |
ComputerUseError, which converts cleanly into adk_core::AdkError. |
Run the portable example
Because everything runs through the ComputerUseRuntime trait, you can run the
whole graph with no server, no desktop, and no specific OS:
You'll see the observations join, the action take the "allowed" route, and a
committed receipt. The example declares no postcondition, so it reports
committed: true and verified: false rather than claiming an observation it
did not make. In code:
use Arc;
use ;
use ;
use json;
# async
The full in-process runtime is in
examples/minimal_graph.rs, which is a good starting
point for writing your own.
Driving a real desktop
To drive a live desktop, use ComputerUseMcpRuntime pointed at a running
computer-use-mcp server. The ADK code is identical on every OS; only the demo
scaffolding (reading the clipboard, building a native window) is platform-specific.
The cross-platform live demo runs on macOS, Linux, and Windows:
live_clipboard— a plain-English request that ends up on the real clipboard, then verified by reading it back with the platform's own tool (pbpasteon macOS,Get-Clipboardon Windows,wl-paste/xclip/xselon Linux).
The native-UI showcases are macOS-specific (they build an AppKit window and drive
Finder), and live under examples/macos/:
live_form— a native AppKit form, picture-in-picture approval, and an independent read-back to confirm the result.live_background_finder— updates a Finder comment in the background, then rolls it back, without taking focus.
Approvals and resuming
When a preview requires sign-off, the graph does not block a thread. It interrupts
and hands you the preview as durable checkpoint data. To continue, insert an
approval object back into the graph state that echoes the digests from the
action you are approving:
If either digest does not match the interrupted action, the resume is rejected, so
an approval cannot authorize a different action. The bearer token never enters ADK
or model state: set "runtimeApproved": true to let the runtime hold it
instead of passing a grantId.
Evaluation
ComputerUseEvaluator replays a session's event trajectory and flags safety
violations: mutations without a lease, commits that were never verified, and the
same mutation running more than once. AdkEvaluationReceipt wraps the evidence in
a canonically-hashed, tamper-evident artifact. CI can produce a receipt, but
signing the matching statement is a release authority's responsibility, so CI
output alone cannot promote a release.
License
Same terms as the ADK-Rust workspace — see the repository root.