Skill 是指引,不是連接本身
Skill 指引 Agent 尋找或安裝 App、完成配對並進行操作。安裝 Skill 不會自動設定 MCP。App 應在你要控制視窗的那台電腦上執行
使用指南
先使用安裝提示詞,或按照下方分開說明的 CLI、MCP 與遠端連接步驟操作。macOS 與 Windows 使用相同的配對和安全控制
Skill 說明如何操作;CLI 與 MCP 提供呼叫本機服務的方式
Skill 指引 Agent 尋找或安裝 App、完成配對並進行操作。安裝 Skill 不會自動設定 MCP。App 應在你要控制視窗的那台電腦上執行
macOS 與 Windows 都提供 CLI、stdio MCP,以及可選的本機 HTTP MCP。CLI 將截圖存為本機檔案,交由 Agent 開啟;MCP 直接將影像傳回 Agent
模型可以在雲端執行,而命令工具在你的電腦上執行,這仍屬於本機連接。完全在雲端、無法存取你電腦的 Agent,則需要可連通的遠端連接
Agent 若能執行本機命令,先使用 App 的安裝提示詞與 CLI。已有可用的 MCP 連接便繼續使用;要操作另一台電腦時,使用 SSH 隧道上的 HTTP MCP
這些是接入建議,不是自動選擇機制。Computer Use 不會替 Agent 選擇介面,也不會換一種介面重試結果不確定的動作
除非需要手動設定或連接另一台電腦,否則先使用這個流程
從下載頁安裝適合的套件,再開啟 Computer Use。在“接入”選擇“复制安装提示词”,貼給你的 Agent。App 已內建 CLI 執行環境,不需要全域安裝 Node 或複製原始碼儲存庫
Agent 會使用自身支援的 Skill 安裝機制。保留既有 Skill 的自訂內容,並在整個流程使用相同 profile;本指南範例使用 default
macOS 需要在系統設定授予 Computer Use 輔助使用與螢幕錄製權限。Windows 則需讓 App 在已登入的互動桌面執行,並由你檢查系統啟動警告。首次配對請求出現時,在本機 App 核准該客戶端
已有授權的 profile 可直接沿用。配對、作業系統權限與 Agent 自身的工具核准是不同的控制層。客戶端已有所有應用程式的權限時,新增視窗或應用程式不需要再次配對
開啟一個不含敏感內容的測試視窗,將下方唯讀任務複製給 Agent。請它檢查連接、列出視窗、建立背景工作階段、顯示截圖並關閉工作階段,不要點擊、輸入或更改任何內容
成功表示 Agent 實際開啟並顯示影像,而不只是命令正常結束。截圖會傳送給你選擇的 Agent,請避開包含你不希望傳送內容的視窗
使用 computer-use 檢查連線,列出已授權的視窗,開啟測試視窗的工作階段,取得截圖並描述畫面內容,然後關閉工作階段。這次不要點擊或輸入在已安裝 Computer Use 的電腦上執行命令,CLI 不需要 MCP 設定
使用 App 安裝提示詞中的本機路徑提示,或按照下方範例尋找標準安裝位置。範例會設定 cu;若找到多份,請選擇要使用的完整安裝,而不要猜測。後續命令請在同一個終端視窗執行
每次開始新的 Agent 對話,先閱讀 --help 與 instructions,再執行 preflight --profile default。這些命令不需要配對,也不會啟動服務。離線憑據標示為 unverified 並不代表授權有效
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以桌面登入帳戶開啟 PowerShell。使用 App 安裝提示詞中的本機路徑提示,或按照下方方式尋找目前帳戶的安裝;若使用可攜版,請選擇完整解壓縮後的目錄。範例會設定 cuNode 與 cuCli,後續請保留這個 PowerShell 視窗
先閱讀 --help 與 instructions,再檢查 preflight --profile default。不要將 cli.js 單獨移出套件,也不要改用全域安裝的 Node
$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若 preflight 回報 missing,且沒有已知的撤銷原因,才發起首次配對並在本機 App 核准。已有 profile 時直接沿用;invalid、unauthorized 或離線的 unverified 狀態需要診斷,不應刪除憑據後重新配對
範例申請預設的所有桌面應用程式權限,核准前請檢查範圍;獨立瀏覽器的權限另行處理。使用其他 profile 時,請一致替換所有 default
# Only when preflight reports missing credentials and there is no known revocation
cu pair --profile default --name 'My Agent'# Only when preflight reports missing credentials and there is no known revocation
& $cuNode $cuCli pair --profile default --name 'My Agent'執行 doctor 與 targets,選擇測試視窗傳回的目標 ID,再以 background 模式呼叫 session_open。使用傳回的工作階段 ID 執行 observe 與 session_close,將每個佔位值替換為實際傳回值
關閉工作階段前,先用 Agent 的讀圖工具開啟 observe 傳回的截圖檔案。這項檢查不需要點擊或輸入;已安裝版本的精確方法參數可透過 schema 查看
# 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"}'# 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適用於支援 MCP 且能在同一台電腦啟動處理序的 Agent
先完成上方的 CLI 尋找與 profile 檢查。在 App 開啟“接入”→“高级接入”,選擇相同 profile,並複製 Agent 所需的設定。stdio MCP 不需要啟用 HTTP
也可以用 config stdio 產生通用 JSON,或用 config codex 產生 Codex 設定。產生的 stdio 設定包含絕對啟動路徑與 profile 名稱,不包含配對 token
在已設定 cu 的終端視窗執行。依 Agent 支援的格式加入產生的服務項目,並保留其他既有項目
cu config stdio --profile default
# For an Agent that uses Codex TOML, run this instead:
# cu config codex --profile default在已設定 cuNode 與 cuCli 的 PowerShell 視窗執行。保留產生的絕對路徑與參數界線;要求可執行檔路徑的欄位不能貼入整條 shell 命令
& $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,確認服務已提供工具。請它針對測試視窗依序執行 doctor → targets → session_open → observe → session_close,MCP 會直接傳回截圖影像
preflight、instructions 與 recover 是 CLI 輔助命令,不是 MCP 工具。使用 MCP 的 Agent 仍可能需要本機命令權限以進行維護;純 MCP 客戶端不能假設這些輔助命令可用
被控電腦執行 App 與目標視窗;控制端電腦執行 Agent 與 SSH 隧道
保持桌面登入並解除鎖定,執行 Computer Use,完成權限與配對批准,準備 SSH 並啟用 HTTP MCP
準備 SSH 客戶端與金鑰,核對受控電腦,建立通道,匯入私有 HTTP 設定並驗證擷取畫面
兩台電腦應在同一區域網,或已有可連通 SSH 的可信連線環境。本指南不設定公網連接埠轉送、穿透服務或無人值守存取。SSH 與 App 應使用被控端的同一帳戶,讓 profile 與私有檔案一致。該帳戶需登入未鎖定的互動桌面,保持 App 執行,並完成系統權限核准
兩個平台都提供 HTTP MCP,但介面存在不等於完成實機驗收:目前記錄的跨電腦測試是由 Mac 控制 Windows,遠端控制 Mac 尚未完成同等的桌面驗證
開啟「系統設定」→「一般」→「共享」→「遠端登入」,啟用後只允許你打算使用的帳戶。記下顯示的登入名稱與位址。這項設定不需要授予遠端帳戶完整磁碟存取權;SSH 權限也不會授予 Computer Use 操作權限
若系統設定不同,請參考 Apple 遠端登入說明
在管理員 PowerShell 檢查 OpenSSH Server 選用元件,僅在未安裝時加入,再啟動 sshd。檢查既有 SSH 輸入規則,不要重複新增;將來源位址限制為控制端或可信連線範圍。不要在防火牆開放 MCP 連接埠
服務自動啟動是可選的持續性變更。請參考 Microsoft OpenSSH 設定說明;第二個範例只在你選擇時才啟用自動啟動
$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-NetFirewallPortFilterSet-Service -Name sshd -StartupType AutomaticmacOS 已內建 SSH 客戶端。Windows 先檢查 ssh -V,若不存在,再從 Windows 設定加入 OpenSSH Client 選用功能。產生受密碼片語保護的專用金鑰,或沿用合適的既有金鑰,不要覆寫它
只透過可信管道將 .pub 公開金鑰傳到被控端,私密金鑰留在控制端。範例使用專用金鑰路徑;若該位置已有金鑰,請取消而不是取代
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"$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"在被控電腦以 SSH 目標帳戶本機登入,將控制端的公開金鑰作為新一行加入 ~/.ssh/authorized_keys,保留既有金鑰。目錄應屬於該帳戶,權限為 700;檔案權限為 600。不要貼入私密金鑰
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一般帳戶將公開金鑰加入該帳戶的 %USERPROFILE%\.ssh\authorized_keys;範例將檔案存取限制為該帳戶、Administrators 與 SYSTEM。請檢查目錄屬於該帳戶,且其他一般帳戶不能寫入。管理員帳戶在預設 OpenSSH 設定下改用 %ProgramData%\ssh\administrators_authorized_keys,需從管理員 PowerShell 管理
以附加方式保留既有金鑰。管理員金鑰檔案由管理員帳戶共用,只能由 Administrators 與 SYSTEM 存取。若要將金鑰限制為單一管理員,需另外審查並明確設定 SSH 服務,不要把這份共用檔案當成個別帳戶的授權。請使用對應範例與 Microsoft 金鑰管理說明;自訂 sshd_config 可能改變所需位置
$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$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-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubssh-keygen.exe -lf "$env:ProgramData\ssh\ssh_host_ed25519_key.pub"將帳戶與位址佔位值替換為被控端的實際登入資料。使用專用金鑰,核對指紋,並確認進入預期帳戶。啟動隧道前先結束該遠端 shell;SSH 登入成功不會啟動 Computer Use 或核准配對
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 computerssh.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 連接埠
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>'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>'在被控端沿用 CLI 尋找步驟的變數與預期的既有 profile;只有 profile 不存在且未曾被撤銷時,才完成首次本機配對。開啟 App“接入”→“高级接入”,啟用本機 HTTP MCP。每次 App 或服務重新啟動後預設關閉
用對應命令匯出新的 HTTP 設定檔。與 stdio 設定不同,這份 JSON 含有 Bearer 憑據。Windows 要求存放在 App 私有資料目錄。匯出工具不會覆寫既有檔案,請先檢查該檔案或選用新檔名
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& $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透過 SSH/SFTP 將匯出的 JSON 取回新建的本機私有目錄。將遠端路徑佔位值替換為匯出命令傳回的絕對路徑;Windows 被控端使用正斜線,並保留整個遠端參數外的引號。範例將下載後的檔案限制為只有你的帳戶可存取
將 URL 與授權標頭匯入支援 HTTP MCP 和私有憑據儲存的 Agent。保留 URL http://127.0.0.1:47631/mcp,隧道會連到被控端。不要將憑據貼入 Agent 對話、網頁、儲存庫或共享資料夾。直接使用 HTTP 連接不需要全域安裝 Node
重新載入 Agent 的 MCP 連接。在有需要時保留私密設定;確認傳輸完成後,可只刪除被控端額外匯出的副本,不要刪除 App 的配對憑據
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"$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"執行相同的唯讀流程: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;若曾啟用自動啟動,需明確將它停用。不再授權該金鑰時,只移除對應的專用公開金鑰項目
Stop-Service sshd
Set-Service -Name sshd -StartupType Manual保留完整錯誤與既有 profile,改變連接方式不會改變授權
檢查完整安裝與 App 安裝提示詞中的本機路徑提示。移動 App 或可攜版目錄後,應重新產生 stdio 設定,因為其中使用絕對路徑。舊版 App 若沒有 instructions 或 preflight,可參考已安裝 Skill 的相容性指引並評估升級;缺少命令不代表 App 未安裝
CLI 命令、MCP 設定與診斷應使用相同 profile。檢查 doctor.authorization、capabilities.authorization 或線上的 preflight.profile.authorization;缺少欄位代表範圍未知。targets 會省略客戶端授權範圍以外的視窗
已有桌面客戶端時,使用者可在 App 選擇“客户端”→“允许所有应用…”並於本機確認。這會保留 token、profile 與 MCP 設定,獨立瀏覽器權限不變。僅瀏覽器客戶端需另行在本機檢查;舊版 App 沒有這項控制時,應升級或在本機檢查,不要自動重新配對
也請檢查應用程式在登入桌面中是否有可見視窗,以及系統權限是否已授予。已有所有應用程式的授權時,新視窗不需要逐一核准
SSH 需檢查被控端位址、允許的帳戶、SSH 服務、防火牆規則、金鑰檔案位置與 ACL。主機指紋改變時,務必在被控端核對。HTTP 需確認被控 App 正在執行、HTTP 開關已啟用,且隧道佔用控制端的 47631 連接埠
收到 401 回應時,檢查所選 profile 與客戶端是否已被撤銷。系統權限不足、桌面鎖定或非互動式桌面需在被控端處理。不要為了繞過隧道問題而透過防火牆開放 MCP
先閱讀已安裝版本的 instructions 與 preflight。Host 故障,或桌面動作結果不確定後連接中斷且沒有使用者停止時,Agent 可用同一份完整套件與既有 profile 嘗試一次 recover。範例是本機 CLI 命令,不是遠端 MCP 工具
恢復不能解除暫停或緊急停止、恢復已撤銷的存取、授予系統權限或重新配對,這些情況需要使用者在本機處理。成功後查詢原動作,建立新的背景工作階段並觀察;不要沿用舊工作階段、快照或元素。若恢復失敗或下一步再次故障,應回報問題而不是循環重試
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& $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 actionunknown 表示輸入是否送達仍不確定。保留原 requestId,查詢 action_status,並在重新連接後檢查新的觀察結果。不要將 MCP 改成 CLI 來重試、產生新的請求 ID,或重複等效的點擊與按鍵
executed 但效果未確認時需要觀察,不需要重新啟動服務。畫面沒有改變不能證明輸入未送達;若無法確定有重要後果的動作是否已發生,請由使用者確認