diff --git a/README.md b/README.md index 2db03ceb4..81d3ee50b 100644 --- a/README.md +++ b/README.md @@ -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** diff --git a/docs/content/docs/how-to-guides/driver/connect-your-agent.mdx b/docs/content/docs/how-to-guides/driver/connect-your-agent.mdx index e9bdb7006..38e3b8da0 100644 --- a/docs/content/docs/how-to-guides/driver/connect-your-agent.mdx +++ b/docs/content/docs/how-to-guides/driver/connect-your-agent.mdx @@ -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'; @@ -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: diff --git a/libs/cua-driver/rust/crates/cua-driver/src/cli.rs b/libs/cua-driver/rust/crates/cua-driver/src/cli.rs index a546a13be..287935b8e 100644 --- a/libs/cua-driver/rust/crates/cua-driver/src/cli.rs +++ b/libs/cua-driver/rust/crates/cua-driver/src/cli.rs @@ -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." } ] }, @@ -936,7 +936,7 @@ pub fn build_manifest() -> serde_json::Value { /// Print the MCP server config snippet or a client-specific install command. /// /// `--client ` 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() @@ -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 [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); } } @@ -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, diff --git a/libs/cua-driver/rust/crates/platform-windows/examples/mcp_config_parity.rs b/libs/cua-driver/rust/crates/platform-windows/examples/mcp_config_parity.rs index 4bee36f68..7144bf633 100644 --- a/libs/cua-driver/rust/crates/platform-windows/examples/mcp_config_parity.rs +++ b/libs/cua-driver/rust/crates/platform-windows/examples/mcp_config_parity.rs @@ -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"]), ]; @@ -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"))] diff --git a/libs/cua-driver/scripts/install.sh b/libs/cua-driver/scripts/install.sh index 84bfb0269..e173e8f5f 100755 --- a/libs/cua-driver/scripts/install.sh +++ b/libs/cua-driver/scripts/install.sh @@ -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 @@ -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