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.
OpenAI Codex supports local MCP servers in the CLI, IDE extension, and desktop app. Cua Driver connects to Codex through the cua-driver mcp stdio server, giving Codex access to the same 54 computer-use tools available to other MCP-capable agents. This page covers registration, the Codex Agent SDK integration, and a practical desktop example.
Register Cua Driver with Codex
After installing Cua Driver, generate the registration command for your installed version:
cua-driver mcp-config --client codex
This prints the exact codex mcp add command with the resolved absolute path to your cua-driver executable. Its shape is:
codex mcp add cua-driver -- /absolute/path/to/cua-driver mcp
codex mcp list
Using an absolute path is important because Codex may inherit a different PATH than your interactive shell. Open a fresh Codex session after registering the server.
Codex SDK supports MCP servers but does not expose application-owned custom tool callbacks. Always use cua-driver mcp as the Codex–Cua Driver boundary. Do not build a second tool loop that translates the native SDK back into an ad hoc protocol.
Install the Cua Driver agent skill
An optional agent skill provides action-selection guidance for Codex, helping the model sequence computer-use actions more reliably:
cua-driver skills install
cua-driver skills status
The skill is a prompt fragment that teaches Codex the tool naming conventions, the inspect-before-act pattern, and how to handle uncertain mutation outcomes.
Codex Agent SDK integration
The Codex Agent SDK uses MCP as its tool-extension boundary. The integration pattern starts a uniquely named Cua session before creating the Codex instance, passes the MCP server configuration through CodexConfig, and ends the session in a finally block.
# Adapted from libs/cua-driver/examples/agent-sdks/codex_agent.py
import asyncio
import json
import os
import shutil
from uuid import uuid4
from openai_codex import AsyncCodex, CodexConfig, Sandbox
def driver_binary() -> str:
configured = os.environ.get("CUA_DRIVER_BIN")
if configured:
return configured
discovered = shutil.which("cua-driver")
if discovered:
return discovered
raise RuntimeError("cua-driver is not on PATH; set CUA_DRIVER_BIN")
async def run_desktop_task(task: str) -> None:
binary = driver_binary()
session = f"codex-python-{uuid4().hex[:12]}"
started = False
try:
# Start the Cua session before creating the Codex instance
process = await asyncio.create_subprocess_exec(
binary, "call", "start_session",
json.dumps({"session": session, "capture_scope": "window"}),
)
await process.wait()
started = True
config = CodexConfig(
config_overrides=(
f"mcp_servers.cua_driver.command={json.dumps(binary)}",
'mcp_servers.cua_driver.args=["mcp"]',
"mcp_servers.cua_driver.required=true",
)
)
async with AsyncCodex(config) as codex:
thread = await codex.thread_start(
model=os.environ.get("CODEX_MODEL"),
sandbox=Sandbox.read_only,
)
result = await thread.run(
f"""Complete this trusted desktop task through the cua_driver MCP server:
{task}
Session: {session!r}. Pass this session to every tool that accepts one.
Inspect state before each action and verify afterward. If a mutation times out,
observe before retrying. Do not call start_session or end_session.
"""
)
print(result.final_response)
finally:
if started:
process = await asyncio.create_subprocess_exec(
binary, "call", "end_session", json.dumps({"session": session})
)
await process.wait()
asyncio.run(run_desktop_task(
"Inspect the active app and summarize what is visible without changing it"
))
# Run the example from libs/cua-driver/examples/agent-sdks
CUA_CAPTURE_SCOPE=window \
npm run codex -- \
"Inspect the active app and summarize what is visible without changing it"
The TypeScript example follows the same pattern: start session, configure Codex with mcp_servers.cua_driver, run the task, and end the session in finally. The complete source lives at libs/cua-driver/examples/agent-sdks/codex_agent.ts.
The integration scripts:
- Start a uniquely named Cua session outside Codex.
- Mark the Cua MCP server as required.
- Run Codex in a read-only filesystem sandbox.
- Instruct Codex to use only Cua tools for desktop work.
- End the session in
finally.
The filesystem sandbox does not sandbox the separate desktop MCP server. Restrict the task itself, choose an appropriate Cua capture scope, and never blindly retry a mutation after a timeout or disconnect.
MCP server configuration block
For environments that accept a JSON MCP configuration file directly (such as IDE extensions or the Codex desktop app), use this shape:
{
"mcpServers": {
"cua-driver": {
"command": "/absolute/path/to/cua-driver",
"args": ["mcp"],
"required": true
}
}
}
Replace /absolute/path/to/cua-driver with the output of which cua-driver or cua-driver mcp-config --client codex.
Model selection
Set CODEX_MODEL to override the default model used by the Codex SDK:
CODEX_MODEL=codex-mini-latest \
CUA_CAPTURE_SCOPE=window \
.venv/bin/python codex_agent.py "Open Notes and create a new note titled 'Test'"
Computer-use tasks benefit from models with vision capability. The CUA_CAPTURE_SCOPE variable controls whether Cua Driver captures the full desktop (desktop), the active window (window), or picks automatically (auto).
Practical example: inspect the active app
CUA_CAPTURE_SCOPE=window \
.venv/bin/python codex_agent.py \
"Inspect the active app and summarize what is visible without changing it"
Codex will call get_window_state with the active window’s PID to read the accessibility tree and screenshot, then return a structured summary of the visible UI elements.