跳到正文
Computer Use

使用指南

连接 Agent,在本机或远程操作

从安装提示词开始,或按下方独立流程配置 CLI、MCP 和远程连接。macOS 与 Windows 使用相同的配对和安全控制

选择接入方式

Skill 告诉 Agent 怎么使用,CLI 和 MCP 则提供调用本机服务的入口

Skill 是使用说明,不是连接本身

Skill 指导 Agent 发现或安装 App、完成配对并操作应用。安装 Skill 不等于配置 MCP;App 必须运行在你想要操作窗口的那台电脑上

两个平台都有三种调用入口

macOS 和 Windows 都提供 CLI、stdio MCP,以及可选的本机 HTTP MCP。CLI 把截图保存为本机文件,由 Agent 打开;MCP 直接向 Agent 返回图片

模型可以运行在云端,而命令工具运行在你的电脑上,这仍属于本机连接。完全运行在云端、无法访问你电脑的 Agent,才需要能连通的远程入口

根据 Agent 的能力选择流程

Agent 能执行本机命令时,优先使用 App 安装提示词和 CLI;已有可用 MCP 连接时继续使用;连接另一台电脑时,使用 HTTP MCP 加 SSH 隧道

这些是接入建议,不是自动选择机制。Computer Use 不会替 Agent 选择入口,也不会通过另一个入口重试结果不确定的动作

通过安装提示词快速开始

没有手动配置或跨电脑接入需求时,按这个流程操作即可

1. 安装 App,复制提示词

从下载页安装适合当前系统的包,然后打开 Computer Use。在“接入”页点击“复制安装提示词”,粘贴给你的 Agent。App 已内置 CLI 运行时,无需安装全局 Node 或克隆仓库

Agent 按自身支持的方式安装 Skill,保留已有 Skill 的自定义内容,并始终使用同一个 profile;本指南示例使用 default

2. 完成系统权限与首次配对

macOS 需要在系统设置中为 Computer Use 授予辅助功能和屏幕录制权限。Windows 需要在已登录的交互桌面运行 App,由你处理系统启动提示。首次配对请求出现时,在本机 App 内批准

已有授权 profile 时直接复用。配对、操作系统权限与 Agent 自己的工具审批是不同的控制;客户端已有所有应用权限时,新增窗口或应用不需要再次配对

3. 验证一次真实观察

打开一个不含敏感内容的测试窗口,把下方可复制的只读测试任务交给 Agent,要求检查连接、列出窗口、创建后台会话、展示截图并关闭会话,不点击、不输入、不修改内容

验收以 Agent 实际打开并展示图片为准,不能只看命令是否成功退出。截图会交给你选择的 Agent,测试时避开不希望它接收的信息

安全的第一个任务
使用 computer-use 检查连接,列出已授权窗口,打开测试窗口的会话,获取截图并描述看到的内容,然后关闭会话。此次不要点击或输入

本机 CLI

在安装 Computer Use 的电脑上执行命令,CLI 不需要添加 MCP 配置

macOS:定位已安装的 CLI

使用 App 安装提示词中的本机路径提示,或按下方示例发现标准安装位置。示例设置 cu;如果发现多份安装,明确选择要使用的完整安装包,不自动猜测。后续命令在同一个终端中执行

每个新的 Agent 对话开始时,先阅读 --help 和 instructions,再执行 preflight --profile default。这些命令不需要配对,也不启动服务;离线凭据标记为 unverified,不能据此认为授权有效

macOS · Terminal
cuApp=''
for candidate in '/Applications/Computer Use.app' "$HOME/Applications/Computer Use.app"; do
  if [ -d "$candidate" ]; then
    if [ -n "$cuApp" ]; then
      printf '%s\n' 'Multiple installations: choose the intended App path' >&2
      cuApp=''
      break
    fi
    cuApp="$candidate"
  fi
done
# For multiple or custom installations, set cuApp to the intended absolute path
cu() {
  [ -n "$cuApp" ] || { printf '%s\n' 'Set cuApp first' >&2; return 1; }
  cuResources="$cuApp/Contents/Resources"
  [ "$(/usr/bin/plutil -extract CFBundleIdentifier raw -o - "$cuApp/Contents/Info.plist")" = com.starroy.computeruse ] || return 1
  for file in "$cuApp/Contents/MacOS/ComputerUseHost" "$cuResources/bin/node" "$cuResources/bin/computer-use" "$cuResources/bin/cua-driver"; do
    [ -x "$file" ] || { printf 'Missing executable: %s\n' "$file" >&2; return 1; }
  done
  for file in runtime/cli.js runtime/host.js package.json build-receipt.json skills/computer-use/SKILL.md; do
    [ -f "$cuResources/$file" ] || { printf 'Missing file: %s\n' "$file" >&2; return 1; }
  done
  [ -d "$cuResources/node_modules" ] || return 1
  "$cuResources/bin/computer-use" "$@"
}
cu --help && cu instructions && cu preflight --profile default

Windows:使用包内运行时

以当前桌面用户打开 PowerShell。使用 App 安装提示词中的本机路径提示,或按下方示例发现当前用户的安装;便携版则使用完整解压目录。示例设置 cuNode 和 cuCli,后续命令在同一个 PowerShell 窗口中执行

阅读 --help 和 instructions,然后检查 preflight --profile default。不要把 cli.js 单独移出安装包,也不要替换为全局 Node

Windows · PowerShell
$ErrorActionPreference = 'Stop'
$cuRoot = Join-Path $env:LOCALAPPDATA 'Programs\Computer Use'
# For a portable/custom installation, replace cuRoot with its complete package directory
foreach ($file in @('ComputerUse.WindowsHost.exe', 'bin\node.exe', 'bin\cua-driver.exe', 'runtime\cli.js', 'runtime\host.js', 'package.json', 'build-receipt.json', 'skills\computer-use\SKILL.md')) {
  if (-not (Test-Path -LiteralPath (Join-Path $cuRoot $file) -PathType Leaf)) {
    throw "Incomplete package: $file"
  }
}
if (-not (Test-Path -LiteralPath (Join-Path $cuRoot 'node_modules') -PathType Container)) {
  throw 'Incomplete package: node_modules'
}
$cuNode = Join-Path $cuRoot 'bin\node.exe'
$cuCli = Join-Path $cuRoot 'runtime\cli.js'
& $cuNode $cuCli --help
if ($LASTEXITCODE -ne 0) { throw 'CLI help failed' }
& $cuNode $cuCli instructions
if ($LASTEXITCODE -ne 0) { throw 'Read the installed version compatibility instructions' }
& $cuNode $cuCli preflight --profile default

仅在所选 profile 缺失时配对

如果 preflight 返回 missing,且没有已知撤销记录,再发起首次配对并在本机 App 批准。profile 已存在时直接复用;出现 invalid、unauthorized 或离线 unverified 时先排查,不删除凭据后重新配对

示例申请默认的所有桌面应用权限,请在批准前确认范围;独立浏览器权限另外处理。使用其他 profile 时,将所有 default 统一替换

macOS · Terminal
# Only when preflight reports missing credentials and there is no known revocation
cu pair --profile default --name 'My Agent'
Windows · PowerShell
# Only when preflight reports missing credentials and there is no known revocation
& $cuNode $cuCli pair --profile default --name 'My Agent'

检查、列窗口、观察,再关闭会话

执行 doctor 和 targets,选取测试窗口返回的目标 ID,再调用 session_open 并指定 background 模式。将返回的会话 ID 用于 observe 和 session_close,把示例中的占位值替换为真实返回值

关闭会话前,用 Agent 的读图工具打开 observe 返回的截图文件。这项检查不需要点击或输入;完整参数以已安装版本的 schema 为准

macOS · Terminal
# Run each command separately, inspect its result, then replace the next placeholder
cu doctor --profile default
cu targets --profile default
cu session_open --profile default --json '{"targetId":"TARGET_ID","mode":"background"}'
cu observe --profile default --json '{"sessionId":"SESSION_ID"}'
# Read the screenshot file returned by observe, then close this session
cu session_close --profile default --json '{"sessionId":"SESSION_ID"}'
Windows · PowerShell
# Run each step separately and inspect the result
& $cuNode $cuCli doctor --profile default
& $cuNode $cuCli targets --profile default

# File input avoids native-command JSON quoting differences in PowerShell 5.1 and 7
$cuRequest = Join-Path ([IO.Path]::GetTempPath()) ("cu-observe-" + [Guid]::NewGuid().ToString() + '.json')
$utf8 = New-Object Text.UTF8Encoding($false)
[IO.File]::WriteAllText($cuRequest, '{"targetId":"TARGET_ID","mode":"background"}', $utf8)
& $cuNode $cuCli session_open --profile default --input $cuRequest

# Replace SESSION_ID with the returned sessionId
[IO.File]::WriteAllText($cuRequest, '{"sessionId":"SESSION_ID"}', $utf8)
& $cuNode $cuCli observe --profile default --input $cuRequest
# Read the screenshot file returned by observe, then close this session
& $cuNode $cuCli session_close --profile default --input $cuRequest
Remove-Item -LiteralPath $cuRequest

本机 stdio MCP

适用于支持 MCP,且能在同一台电脑上启动进程的 Agent

复用配对,生成配置

先完成上方 CLI 的安装发现和 profile 检查。在 App“接入 → 高级接入”选择相同 profile,复制适合 Agent 的配置;stdio MCP 无需开启 HTTP

也可以用 config stdio 生成通用 JSON,或用 config codex 生成 Codex 配置。stdio 设置包含绝对启动路径和 profile 名称,不包含配对 token

macOS 配置命令

在已设置 cu 的终端中执行。按 Agent 支持的格式添加生成的服务器配置,保留其他已有配置项

macOS · Terminal
cu config stdio --profile default
# For an Agent that uses Codex TOML, run this instead:
# cu config codex --profile default

Windows 配置命令

在已设置 cuNode 和 cuCli 的 PowerShell 中执行。保留生成的绝对路径和参数边界,不要把整段 shell 命令粘贴到只接受可执行文件路径的字段里

Windows · PowerShell
& $cuNode $cuCli config stdio --profile default
# For an Agent that uses Codex TOML, run this instead:
# & $cuNode $cuCli config codex --profile default

重新加载 Agent,验证工具调用

重新加载 MCP 配置或重启 Agent,确认服务器提供了工具。让 Agent 对测试窗口依次执行 doctor → targets → session_open → observe → session_close,MCP 会把截图直接作为图片返回

preflight、instructions 和 recover 是 CLI 辅助命令,不是 MCP 工具。使用 MCP 的 Agent 仍可能需要本机命令权限处理维护操作,纯 MCP 客户端不能假定这些命令可用

跨电脑:通过 SSH 隧道连接 HTTP MCP

被控电脑运行 App 和要操作的窗口,控制端电脑运行 Agent 和 SSH 隧道

被控电脑

保持桌面登录和解锁,运行 Computer Use,完成权限和配对批准,准备 SSH 并启用 HTTP MCP

运行 Agent 的电脑

准备 SSH 客户端和密钥,核对被控电脑,建立隧道,导入私有 HTTP 配置并验证截图

两台电脑:确认前提

使用同一局域网,或已有能连接 SSH 的可信网络。本指南不配置公网端口映射、穿透服务或无人值守访问。SSH 与 App 使用被控端的同一个账户,保证 profile 和私有文件一致;该用户应保持交互桌面登录且已解锁,App 已运行并完成系统权限授权

两平台都有 HTTP MCP,但接口支持不等于完成实机验收:现有跨电脑验收是 Mac 控制 Windows,远控 Mac 尚未完成同等桌面验收

被控 Mac:仅为指定用户开启 SSH

打开“系统设置 → 通用 → 共享 → 远程登录”,开启后仅允许要使用的账户,记下界面显示的登录名和地址。本流程无需为远程用户开启完全磁盘访问;SSH 权限也不会授予 Computer Use 操作权限

系统设置不同版本的操作可参考 Apple 远程登录说明

被控 Windows:安装并启动 OpenSSH Server

在管理员 PowerShell 中检查 OpenSSH Server 可选组件,仅在缺失时安装,然后启动 sshd。先检查已有的 SSH 入站规则,不重复添加;将来源地址限制为控制端或可信网络,不在防火墙中开放 MCP 端口

开机自动启动属于额外的持久化设置,可按需选择。详见 Microsoft OpenSSH 安装说明;仅当你需要自动启动时执行第二段示例

Windows · PowerShell
$ErrorActionPreference = 'Stop'
$cuSsh = Get-WindowsCapability -Online -Name 'OpenSSH.Server~~~~0.0.1.0'
if ($cuSsh.State -ne 'Installed') {
  Add-WindowsCapability -Online -Name 'OpenSSH.Server~~~~0.0.1.0'
  Set-Service -Name sshd -StartupType Manual
}
Start-Service sshd
Get-Service sshd
Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' |
  Select-Object Name, Enabled, Direction, Action, Profile
Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' | Get-NetFirewallPortFilter
Windows · PowerShell
Set-Service -Name sshd -StartupType Automatic

控制端:检查 SSH 并准备密钥

macOS 已包含 SSH Client。Windows 先运行 ssh -V;缺失时,在系统设置中添加 OpenSSH Client 可选功能。生成带口令的专用密钥,或复用合适的已有密钥,不覆盖它

仅通过可信渠道把 .pub 公钥传到被控电脑,私钥保留在控制端。示例使用专用密钥路径;如果该位置已有密钥,取消生成,不要替换

macOS · Terminal
command -v ssh ssh-keygen sftp
cuKey="$HOME/.ssh/id_ed25519_computer_use"
if [ -e "$cuKey" ] || [ -e "$cuKey.pub" ]; then
  printf '%s\n' 'Key already exists: reuse the intended pair; do not overwrite it'
else
  install -d -m 700 "$HOME/.ssh"
  ssh-keygen -t ed25519 -f "$cuKey" -C 'computer-use'
fi
# Copy only this public key to the target computer
cat "$cuKey.pub"
Windows · PowerShell
$ErrorActionPreference = 'Stop'
Get-Command ssh.exe, ssh-keygen.exe, sftp.exe -ErrorAction Stop
$cuKey = Join-Path $env:USERPROFILE '.ssh\id_ed25519_computer_use'
if ((Test-Path -LiteralPath $cuKey) -or (Test-Path -LiteralPath "$cuKey.pub")) {
  Write-Output 'Key already exists: reuse the intended pair; do not overwrite it'
} else {
  New-Item -ItemType Directory -Path (Split-Path $cuKey) -Force | Out-Null
  ssh-keygen.exe -t ed25519 -f $cuKey -C computer-use
  if ($LASTEXITCODE -ne 0) { throw 'Key generation failed' }
}
# Copy only this public key to the target computer
Get-Content -LiteralPath "$cuKey.pub"

被控 Mac:添加公钥授权

在被控电脑本机以 SSH 目标用户登录,把控制端公钥另起一行追加到 ~/.ssh/authorized_keys,保留已有密钥。目录归该用户所有、权限为 700,文件权限为 600;不要粘贴私钥

macOS · Terminal
cuPublicKey='<PUBLIC_KEY_LINE>'
case "$cuPublicKey" in
  'ssh-ed25519 '*)
    install -d -m 700 "$HOME/.ssh"
    cuAuthorized="$HOME/.ssh/authorized_keys"
    if [ -L "$cuAuthorized" ]; then
      printf '%s\n' 'Review the existing authorized_keys symlink before continuing' >&2
    else
      (umask 077; touch "$cuAuthorized")
      grep -Fqx -- "$cuPublicKey" "$cuAuthorized" || printf '\n%s\n' "$cuPublicKey" >> "$cuAuthorized"
      chmod 600 "$cuAuthorized"
    fi
    ;;
  *) printf '%s\n' 'Replace PUBLIC_KEY_LINE with the complete public key' >&2 ;;
esac

被控 Windows:选择正确的密钥文件和 ACL

普通账户把公钥添加到该用户的 %USERPROFILE%\.ssh\authorized_keys;示例将文件权限限制为该账户、Administrators 和 SYSTEM,另需检查目录归该用户所有,其他普通账户不可写。管理员账户的默认 OpenSSH 配置使用 %ProgramData%\ssh\administrators_authorized_keys,需要在管理员 PowerShell 中管理

追加时保留已有密钥。管理员密钥文件由管理员账户共享,只应允许 Administrators 和 SYSTEM 访问。如果需要将密钥限制为单个管理员,应先审查并明确配置服务器,不能把共享文件当成单用户授权。按账户类型使用对应示例,并核对 Microsoft 密钥管理说明;自定义 sshd_config 可能改变文件位置

Windows · PowerShell
$ErrorActionPreference = 'Stop'
$cuPublicKey = '<PUBLIC_KEY_LINE>'
if (-not $cuPublicKey.StartsWith('ssh-ed25519 ')) { throw 'Replace PUBLIC_KEY_LINE with the complete public key' }
$cuAuthorized = Join-Path $env:USERPROFILE '.ssh\authorized_keys'
New-Item -ItemType Directory -Path (Split-Path $cuAuthorized) -Force | Out-Null
if ((Test-Path -LiteralPath $cuAuthorized) -and ((Get-Item -LiteralPath $cuAuthorized).Attributes -band [IO.FileAttributes]::ReparsePoint)) {
  throw 'Review the existing authorized_keys link before continuing'
}
if (-not (Test-Path -LiteralPath $cuAuthorized) -or -not (Select-String -LiteralPath $cuAuthorized -Pattern $cuPublicKey -SimpleMatch -Quiet)) {
  Add-Content -LiteralPath $cuAuthorized -Value ("`r`n" + $cuPublicKey) -Encoding ascii
}
$cuSid = [Security.Principal.WindowsIdentity]::GetCurrent().User
$cuAcl = New-Object Security.AccessControl.FileSecurity
$cuAcl.SetOwner($cuSid)
$cuAcl.SetAccessRuleProtection($true, $false)
foreach ($sid in @($cuSid, [Security.Principal.SecurityIdentifier]'S-1-5-18', [Security.Principal.SecurityIdentifier]'S-1-5-32-544')) {
  $cuAcl.AddAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'Allow')))
}
Set-Acl -LiteralPath $cuAuthorized -AclObject $cuAcl
Windows · PowerShell
$ErrorActionPreference = 'Stop'
$cuPublicKey = '<PUBLIC_KEY_LINE>'
if (-not $cuPublicKey.StartsWith('ssh-ed25519 ')) { throw 'Replace PUBLIC_KEY_LINE with the complete public key' }
$cuAuthorized = Join-Path $env:ProgramData 'ssh\administrators_authorized_keys'
if ((Test-Path -LiteralPath $cuAuthorized) -and ((Get-Item -LiteralPath $cuAuthorized).Attributes -band [IO.FileAttributes]::ReparsePoint)) {
  throw 'Review the existing administrators_authorized_keys link before continuing'
}
if (-not (Test-Path -LiteralPath $cuAuthorized) -or -not (Select-String -LiteralPath $cuAuthorized -Pattern $cuPublicKey -SimpleMatch -Quiet)) {
  Add-Content -LiteralPath $cuAuthorized -Value ("`r`n" + $cuPublicKey) -Encoding ascii
}
$cuAdmins = [Security.Principal.SecurityIdentifier]'S-1-5-32-544'
$cuAcl = New-Object Security.AccessControl.FileSecurity
$cuAcl.SetOwner($cuAdmins)
$cuAcl.SetAccessRuleProtection($true, $false)
foreach ($sid in @($cuAdmins, [Security.Principal.SecurityIdentifier]'S-1-5-18')) {
  $cuAcl.AddAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'Allow')))
}
Set-Acl -LiteralPath $cuAuthorized -AclObject $cuAcl

被控端:在本机读取 SSH 主机指纹

在被控电脑本机读取主机密钥指纹,并通过可信渠道记录。控制端首次 SSH 连接时,将显示的指纹与它核对,一致后才接受;指纹变化需要排查,不能直接关闭主机密钥检查

macOS · Terminal
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Windows · PowerShell
ssh-keygen.exe -lf "$env:ProgramData\ssh\ssh_host_ed25519_key.pub"

控制端:先验证 SSH 登录

将用户名和地址占位值替换为被控电脑的实际信息,使用专用密钥,核对指纹并确认登录到了正确账户。退出远程 shell 后再建立隧道;SSH 登录成功不代表 Computer Use 已启动或配对已批准

macOS · Terminal
ssh -i "$HOME/.ssh/id_ed25519_computer_use" -o IdentitiesOnly=yes -o HostKeyAlgorithms=ssh-ed25519 '<REMOTE_USER>@<REMOTE_HOST>'
# Compare the offered SHA256 fingerprint with the target computer before accepting
# After verifying the login, type exit to return to the Agent computer
Windows · PowerShell
ssh.exe -i "$env:USERPROFILE\.ssh\id_ed25519_computer_use" -o IdentitiesOnly=yes -o HostKeyAlgorithms=ssh-ed25519 '<REMOTE_USER>@<REMOTE_HOST>'
# Compare the offered SHA256 fingerprint with the target computer before accepting
# After verifying the login, type exit to return to the Agent computer

控制端:建立本机回环隧道

在单独的终端中持续运行这条命令,只绑定 127.0.0.1:47631,转发到被控端的相同端口。Host 会校验地址和端口,不能仅修改本地端口来绕过冲突

如果端口占用,先确认是自己的旧隧道,或关闭控制端的本机 HTTP MCP,再重试。不要结束无关进程,不使用 -g,不绑定 0.0.0.0,也不直接向外开放 MCP 端口

macOS · Terminal
ssh -i "$HOME/.ssh/id_ed25519_computer_use" \
  -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes \
  -o HostKeyAlgorithms=ssh-ed25519 -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -N \
  -L 127.0.0.1:47631:127.0.0.1:47631 '<REMOTE_USER>@<REMOTE_HOST>'
Windows · PowerShell
ssh.exe -i "$env:USERPROFILE\.ssh\id_ed25519_computer_use" `
  -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes `
  -o HostKeyAlgorithms=ssh-ed25519 -o ExitOnForwardFailure=yes `
  -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -N `
  -L 127.0.0.1:47631:127.0.0.1:47631 '<REMOTE_USER>@<REMOTE_HOST>'

被控端:开启 HTTP,导出私有配置

在被控端复用前面发现 CLI 时设置的变量和已有目标 profile;仅在 profile 缺失且没有已知撤销记录时,完成首次本机配对。在 App“接入 → 高级接入”中启用本机 HTTP MCP,每次重启 App 或服务后都需要重新开启

使用对应命令导出新的 HTTP 配置文件。它与 stdio 设置不同,JSON 包含 Bearer 凭据;Windows 必须写入 App 私有数据目录。导出命令拒绝覆盖已有文件,请先确认旧文件,或选择新文件名

macOS · Terminal
install -d -m 700 "$HOME/.config/computer-use"
cu config http --profile default --out "$HOME/.config/computer-use/remote-http.json"
# The CLI refuses to overwrite an existing file; do not print its contents
Windows · PowerShell
& $cuNode $cuCli config http --profile default --out "$env:LOCALAPPDATA\Computer Use\remote-http.json"
# Export only into the Host private data directory; existing files are not overwritten
# Do not print the file contents

控制端:传输配置并连接 Agent

通过 SSH/SFTP 将导出的 JSON 下载到新的本机私有目录。远程路径占位值使用导出命令返回的绝对路径;被控端是 Windows 时使用正斜线,并保留整个远程参数的引号。示例将下载文件限制为自己的账户可访问

把 URL 和授权请求头导入支持 HTTP MCP 与私有凭据存储的 Agent 设置。URL 保持为 http://127.0.0.1:47631/mcp,隧道会将连接送到被控端。不要把凭据粘贴到 Agent 对话、网页、仓库或共享目录;直接连接 HTTP 不需要安装全局 Node

重新加载 Agent 的 MCP 连接,按需要保留本机私有配置。确认传输后,可以删除被控端为传输而额外导出的那份 JSON,不要删除 App 的配对凭据

macOS · Terminal
cuRemoteDir="$(mktemp -d "$HOME/.computer-use-remote.XXXXXX")"
# Replace REMOTE_CONFIG_PATH with the absolute path returned by config http
# The exported filename is remote-http.json; keep the entire remote argument quoted
(
  umask 077
  cd "$cuRemoteDir" &&
  sftp -i "$HOME/.ssh/id_ed25519_computer_use" \
    -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes \
    -o HostKeyAlgorithms=ssh-ed25519 \
    '<REMOTE_USER>@<REMOTE_HOST>:<REMOTE_CONFIG_PATH>' &&
  chmod 600 remote-http.json
)
printf 'Private configuration directory: %s\n' "$cuRemoteDir"
Windows · PowerShell
$ErrorActionPreference = 'Stop'
$cuRemoteDir = Join-Path $env:USERPROFILE ('.computer-use-remote-' + [Guid]::NewGuid().ToString())
New-Item -ItemType Directory -Path $cuRemoteDir | Out-Null
$cuSid = [Security.Principal.WindowsIdentity]::GetCurrent().User
$cuAcl = New-Object Security.AccessControl.DirectorySecurity
$cuAcl.SetOwner($cuSid)
$cuAcl.SetAccessRuleProtection($true, $false)
$cuAcl.AddAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($cuSid, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')))
Set-Acl -LiteralPath $cuRemoteDir -AclObject $cuAcl
# Replace REMOTE_CONFIG_PATH with the absolute exported path, using / separators
Push-Location -LiteralPath $cuRemoteDir
try {
  sftp.exe -i "$env:USERPROFILE\.ssh\id_ed25519_computer_use" `
    -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes `
    -o HostKeyAlgorithms=ssh-ed25519 `
    '<REMOTE_USER>@<REMOTE_HOST>:<REMOTE_CONFIG_PATH>'
  if ($LASTEXITCODE -ne 0) { throw 'SFTP failed; do not use the partial file' }
} finally {
  Pop-Location
}
Write-Output "Private configuration directory: $cuRemoteDir"

控制端:通过 MCP 验证被控电脑

执行相同的只读流程:doctor → targets → session_open → observe → session_close,确认窗口和截图来自被控电脑,而非控制端

远程 HTTP 不能启动 Host,也不能调用本地 recover。服务不可用时,由被控端用户检查 App 和状态;不要通过另开一份 App 绕过暂停、紧停或已撤销的授权

两台电脑:安全重连或结束

隧道断开时,保留动作原始的 requestId,重连后查询 action_status 并重新观察,不重发结果不确定的动作。如果 App 或服务已重启,需要被控端用户再次启用 HTTP

完成后先关闭会话,在隧道终端按 Ctrl+C,再在被控端 App 关闭 HTTP。如需停止 SSH 访问,macOS 关闭“远程登录”,Windows 停止 sshd;如果之前启用了自动启动,再明确关闭。若不再允许该密钥登录,只移除专用公钥对应的那一行

Windows · PowerShell
Stop-Service sshd
Set-Service -Name sshd -StartupType Manual

排错与故障恢复

保留具体错误和已有 profile,切换连接方式不会改变授权范围

找不到 CLI,或 MCP 启动路径失效

检查安装包是否完整,以及 App 安装提示词中的本机路径提示。移动 App 或便携目录后,重新生成 stdio 配置,因为它使用绝对路径。旧 App 缺少 instructions 或 preflight 时,使用已安装 Skill 的兼容说明并评估升级;缺少新命令不代表 App 未安装

profile 被拒绝,或找不到窗口

CLI 命令、MCP 配置与诊断使用同一 profile。检查 doctor.authorization、capabilities.authorization 或在线 preflight.profile.authorization,字段缺失表示范围未知。targets 会完全省略授权范围外的窗口

已有桌面权限的客户端可由用户在 App“客户端”页选择“允许所有应用…”并本机确认,原 token、profile 和 MCP 配置继续可用,独立浏览器权限保持不变。仅浏览器客户端需要另行本机复核;旧 App 没有此按钮时先升级或本机复核,不自动重新配对

同时确认应用在已登录桌面上有可见窗口,且系统权限已授予。已有所有应用授权时,新窗口不需要逐个批准

SSH 或 HTTP 无法连接

SSH 先检查目标地址、获准账户、SSH 服务、防火墙规则、密钥文件位置和 ACL。主机指纹变化必须在被控端核对。HTTP 则检查被控端 App 是否运行、HTTP 是否开启,以及隧道是否占用了控制端的 47631 端口

返回 401 时,核对所选 profile 和客户端是否已被撤销。系统权限缺失、桌面锁定或非交互会话需要在被控端处理,不要为绕过隧道问题而在防火墙中直接开放 MCP

在本机尝试一次服务故障恢复

先阅读当前安装包的 instructions 和 preflight。Host 失败,或桌面动作结果未知后连接丢失且没有用户停止状态时,Agent 可使用同一完整安装包和已有 profile 尝试一次 recover。示例属于本地 CLI 命令,不是远程 MCP 工具

恢复不能解除暂停或紧停、还原已撤销授权、授予系统权限或重新配对,这些需要用户本机处理。成功后查询原动作,创建新的后台会话并观察,不复用旧会话、快照或元素;恢复失败或下一步再次故障时报告原因,不循环重试

macOS · Terminal
cu preflight --profile default
# Only for a recoverable service fault; inspect preflight before running once
cu recover --profile default
# If an action is uncertain, preserve its original requestId and query it after recovery
cu action_status --profile default --json '{"requestId":"ORIGINAL_REQUEST_ID"}'
# Open a new session and observe; never replay the uncertain action
Windows · PowerShell
& $cuNode $cuCli preflight --profile default
# Only for a recoverable service fault; inspect preflight before running once
& $cuNode $cuCli recover --profile default
# If an action is uncertain, preserve its original requestId and query it after recovery
$cuStatusInput = Join-Path ([IO.Path]::GetTempPath()) ("cu-status-" + [Guid]::NewGuid().ToString() + '.json')
[IO.File]::WriteAllText($cuStatusInput, '{"requestId":"ORIGINAL_REQUEST_ID"}', (New-Object Text.UTF8Encoding($false)))
& $cuNode $cuCli action_status --profile default --input $cuStatusInput
Remove-Item -LiteralPath $cuStatusInput
# Open a new session and observe; never replay the uncertain action

结果不确定的动作绝不重放

unknown 表示输入是否送达不确定。保留原始 requestId,重连后查询 action_status 并检查新观察;不要从 MCP 换成 CLI 重试,不换新请求 ID,也不重复等价的点击或按键

executed 但效果未确认时应继续观察,不需要重启服务。画面不变不能证明输入未送达;如果无法确定有后果的操作是否发生,应交由用户判断