Use Cua Driver in process
Call the typed Cua Driver SDK directly from Python or TypeScript without a daemon.
Use the same-process SDK when your application owns the desktop-control
lifecycle. CuaDriver.create() loads the Rust runtime into the importing
process; it does not launch cua-driver serve or use IPC.
The importing application owns OS permissions and permission UX. On macOS,
direct check_permissions calls are read-only even when prompt is requested;
relaunch the responsible host after changing TCC grants. Direct macOS runtimes
also return facility_unavailable for agent-cursor overlay operations unless
the host installs a suitable AppKit main-thread adapter. Use a private worker
or explicit service when the overlay is required.
Install the SDK#
python -m pip install cua-driverCapture the desktop with an implicit session#
The first stateful call creates one implicit session for the SDK transport.
start_session is optional and no capture scope is stored on the session.
Actions select an exact window or desktop target per call.
import asyncio
from cua_driver import (
CuaDriver,
EndSessionInput,
GetDesktopStateInput,
)
async def main() -> None:
driver = CuaDriver.create()
try:
result = await driver.get_desktop_state(
GetDesktopStateInput(
session=None,
screenshot_out_file=None,
)
)
if result.is_error:
raise RuntimeError(result.text)
print(result.images[0].mime_type)
finally:
await driver.end_session(EndSessionInput(session=None))
await driver.shutdown()
asyncio.run(main())Keep one CuaDriver object for the application lifetime. Repeated unnamed calls
reuse its implicit session. End it explicitly when useful; shutdown() also
runs cleanup. shutdown() is idempotent and rejects new work after shutdown
while allowing already-admitted operations to finish.
If an external agent must also connect to your signed desktop application, use Expose MCP from a desktop app instead.