Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

## Cua Drivers - Background computer-use on macOS and Windows, with Linux pre-release

Drive native desktop apps **in the background**. Agents click, type, and verify without stealing the cursor or focus. Use the same CLI and MCP server on macOS and Windows from Claude Code, Cursor, Codex, OpenClaw, and custom clients. Linux support is available as a pre-release backend while platform testing is still in progress.
Drive native desktop apps **in the background**. Agents click, type, and verify without stealing the cursor or focus. Use the same CLI and MCP server on macOS and Windows from Claude Code, Cursor, Codex, Qwen Code, Droid CLI, OpenClaw, and custom clients. Linux support is available as a pre-release backend while platform testing is still in progress.

**macOS / Linux**

Expand Down
45 changes: 44 additions & 1 deletion docs/content/docs/how-to-guides/driver/connect-your-agent.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Connect your agent
description: Register Cua Driver as an MCP server with Claude Code, Codex, Cursor, Antigravity, OpenClaw, OpenCode, Hermes, and Pi.
description: Register Cua Driver as an MCP server with Claude Code, Codex, Cursor, Antigravity, OpenClaw, OpenCode, Hermes, Qwen Code, Droid CLI, and Pi.
---

import { Callout } from 'fumadocs-ui/components/callout';
Expand Down Expand Up @@ -205,6 +205,49 @@ Each call is one-shot and returns JSON or text on stdout, which is the shape Pi

Verify: run `cua-driver --help` from the same Pi shell context.

## Qwen Code

[Qwen Code](https://github.com/QwenLM/qwen-code) (QwenLM's coding agent) uses cua-driver for its Computer Use backend. Generate the config snippet:

```bash
cua-driver mcp-config --client qwen
```

Paste the printed JSON into `~/.qwen/settings.json`, or `.qwen/settings.json` for project scope:

```json
{
"mcpServers": {
"cua-driver": {
"command": "cua-driver",
"args": ["mcp"]
}
}
}
```

Verify: restart Qwen Code and confirm `cua-driver` appears in the MCP server list.

## Droid CLI

[Droid CLI](https://factory.ai) (Factory AI's coding agent) registers MCP servers with `droid mcp add`:

```bash
droid mcp add cua-driver cua-driver mcp --type stdio
```

Or generate the equivalent config snippet:

```bash
cua-driver mcp-config --client droid
```

Verify:

```bash
droid mcp list
```

## Any other client

For any client that accepts the standard `mcpServers` shape, print the generic config:
Expand Down
47 changes: 43 additions & 4 deletions libs/cua-driver/rust/crates/cua-driver/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ pub fn build_manifest() -> serde_json::Value {
] },
{ "name": "mcp-config",
"description": "Print the MCP server config snippet or a client-specific install command.",
"args": [ { "name": "--client", "type": "string", "description": "One of: claude, codex, cursor, hermes, antigravity, openclaw, opencode, pi. Omit for the generic snippet." } ] },
"args": [ { "name": "--client", "type": "string", "description": "One of: claude, codex, cursor, hermes, antigravity, openclaw, opencode, qwen, droid, pi. Omit for the generic snippet." } ] },
{ "name": "manifest",
"description": "Emit this machine-readable description of the CLI surface.",
"args": [ { "name": "--pretty", "type": "flag", "description": "Pretty-print the JSON." } ] },
Expand Down Expand Up @@ -936,7 +936,7 @@ pub fn build_manifest() -> serde_json::Value {
/// Print the MCP server config snippet or a client-specific install command.
///
/// `--client <name>` selects one of: claude, codex, cursor, hermes,
/// antigravity, openclaw, opencode, pi. Omit for the generic JSON snippet.
/// antigravity, openclaw, opencode, pi, qwen, droid. Omit for the generic JSON snippet.
pub fn run_mcp_config(client: Option<&str>) {
let binary = std::env::current_exe()
.ok()
Expand Down Expand Up @@ -1102,8 +1102,47 @@ pub fn run_mcp_config(client: Option<&str>) {
exactly the shape Pi is designed around."
);
}
Some("qwen") | Some("qwen-code") => {
// Qwen Code (QwenLM/qwen-code) uses cua-driver for its Computer Use
// backend. It reads MCP server configuration from ~/.qwen/settings.json
// (user-scope) or .qwen/settings.json in the project root.
//
// Qwen Code's MCP server schema only accepts command, args, cwd, env,
// and timeout — no "type" discriminator. Do NOT add "type": "stdio".
//
// No `qwen mcp add` subcommand — paste the printed JSON into the
// config file and restart Qwen Code.
//
// Forward slashes in the binary path so the JSON literal is valid on
// Windows (backslashes would need escaping inside a JSON string).
let normalised = binary.replace('\\', "/");
let full = serde_json::json!({
"mcpServers": {
"cua-driver": {
"command": normalised,
"args": ["mcp"],
}
}
});
let pretty = serde_json::to_string_pretty(&full)
.unwrap_or_else(|_| full.to_string());
println!("{pretty}");
}
Some("droid") | Some("droid-cli") => {
// Droid CLI (Factory AI — https://factory.ai) supports a
// `droid mcp add` subcommand for stdio servers:
//
// droid mcp add <name> <command> [args...] --type stdio
//
// The name here is "cua-driver" to stay consistent with other
// client registrations.
//
// Quote the binary path so paths containing spaces are treated as a
// single argument by the shell.
println!("droid mcp add cua-driver \"{binary}\" mcp --type stdio");
}
Some(other) => {
eprintln!("Unknown client '{other}'. Valid: claude, codex, cursor, antigravity, openclaw, opencode, hermes, pi.");
eprintln!("Unknown client '{other}'. Valid: claude, codex, cursor, antigravity, openclaw, opencode, hermes, qwen, droid, pi.");
process::exit(2);
}
}
Expand Down Expand Up @@ -2057,7 +2096,7 @@ fn cli_docs_json() -> serde_json::Value {
{
"name": "mcp-config",
"abstract": "Print MCP server config or a client-specific install command.",
"discussion": "Supported clients include claude, codex, cursor, antigravity, openclaw, opencode, hermes, and pi.",
"discussion": "Supported clients include claude, codex, cursor, antigravity, openclaw, opencode, hermes, qwen, droid, and pi.",
"arguments": no_args,
"options": [{"name":"client","short_name":null,"help":"Client name to print configuration for.","type":"String","default_value":null,"is_optional":true}],
"flags": no_flags,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ fn main() {
(vec!["--client", "openclaw"], vec!["openclaw mcp set cua-driver"]),
(vec!["--client", "opencode"], vec!["opencode.ai/config.json", "\"type\": \"local\""]),
(vec!["--client", "hermes"], vec!["mcp_servers:", "cua-driver:"]),
(vec!["--client", "qwen"], vec!["\"mcpServers\"", "\"command\":", "\"args\":"]),
(vec!["--client", "droid"], vec!["droid mcp add cua-driver"]),
(vec!["--client", "pi"], vec!["does not support MCP natively"]),
];

Expand All @@ -42,7 +44,7 @@ fn main() {
"unknown-client stderr wrong: {stderr:?}");
println!("unknown-client err OK");

println!("\n✅ PASS: mcp-config 8 client paths + unknown-client error verified");
println!("\n✅ PASS: mcp-config 10 client paths + unknown-client error verified");
}

#[cfg(not(target_os = "windows"))]
Expand Down
6 changes: 5 additions & 1 deletion libs/cua-driver/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ Next steps:
• Codex (OpenAI):
codex mcp add cua-driver -- $BIN_LINK mcp

• Droid CLI (Factory AI):
droid mcp add cua-driver cua-driver mcp --type stdio

• OpenClaw:
cua-driver mcp-config --client openclaw

Expand All @@ -472,11 +475,12 @@ Next steps:
}
Or inside gh copilot chat: /mcp add → type=STDIO, command=$BIN_LINK, args=mcp

• Cursor / OpenCode / Hermes / Antigravity (no add CLI — paste config):
• Cursor / OpenCode / Hermes / Antigravity / Qwen Code (no add CLI — paste config):
cua-driver mcp-config --client cursor # JSON for ~/.cursor/mcp.json
cua-driver mcp-config --client opencode # JSON for opencode.json
cua-driver mcp-config --client hermes # YAML for ~/.hermes/config.yaml
cua-driver mcp-config --client antigravity # JSON for ~/.gemini/config/mcp_config.json (shared with Antigravity IDE)
cua-driver mcp-config --client qwen # JSON for ~/.qwen/settings.json

For other clients accepting the generic mcpServers shape:
cua-driver mcp-config
Expand Down
Loading