> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberdesk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Legacy Cyberdriver

> Stable Python-based Cyberdriver client

This page documents the legacy Python Cyberdriver (`0.0.x`). It is currently the recommended stable install path for most desktop automation use cases, especially when you do not need Windows login-screen access. Use the [Cyberdriver 1.x beta](/cyberdriver/quickstart#beta-cyberdriver-1x-windows-install) only when you specifically need the newer Windows service path.

## What is legacy Cyberdriver?

Legacy Cyberdriver is a small Python-based executable that connects your desktop to Cyberdesk, enabling AI-powered automation of desktop tasks. It provides a secure bridge between Cyberdesk's cloud infrastructure and your local Windows machine.

### Key features

* **Local HTTP server** - Endpoints for display, keyboard, mouse, clipboard, file, and shell control.
* **WebSocket tunnel** - Secure outbound connection to Cyberdesk Cloud.
* **Works on physical and virtual machines** - Run on a local Windows computer or Windows VM.
* **Stealth mode** - Runs invisibly in the background on Windows.
* **Keepalive mode** - Prevents idle timeouts and session locks.
* **Black screen recovery** - Automatically recovers from RDP display issues.
* **Persistent virtual display** - Can start a virtual display that runs on the console session.
* **Remote updates** - Update supported legacy versions from the dashboard.

### No firewall configuration required

Legacy Cyberdriver does not require inbound firewall ports. It connects outbound to Cyberdesk Cloud through a secure reverse tunnel.

* Works behind corporate firewalls.
* No router configuration needed.
* No exposed ports on your machine.
* Secure, encrypted connection.

## Installation

### Windows PowerShell installation

The easiest way to install legacy Cyberdriver on Windows is using the PowerShell installer. The script below pins the stable legacy download to `v0.0.41`.

<Steps>
  <Step title="Run the installer in PowerShell">
    ```powershell theme={null}
    # Create tool directory
    $toolDir = "$env:USERPROFILE\.cyberdriver"
    New-Item -ItemType Directory -Force -Path $toolDir

    # Download cyberdriver
    try {
        Invoke-WebRequest -Uri "https://github.com/cyberdesk-hq/cyberdriver/releases/download/v0.0.41/cyberdriver.exe" -OutFile "$toolDir\cyberdriver.exe" -ErrorAction Stop
    } catch {
        Write-Host "ERROR: Failed to download Cyberdriver. If Cyberdriver is already running, run 'cyberdriver stop' first. Otherwise, check your internet connection and try again." -ForegroundColor Red
        return
    }

    # Verify installation
    if (Test-Path "$toolDir\cyberdriver.exe") {
        $fileSize = (Get-Item "$toolDir\cyberdriver.exe").Length
        if ($fileSize -gt 34MB) {
            # Add to PATH if not already there
            $userPath = [Environment]::GetEnvironmentVariable("Path", "User")
            if ($userPath -notlike "*$toolDir*") {
                [Environment]::SetEnvironmentVariable("Path", $userPath + ";" + $toolDir, "User")
            }
            Write-Host "Cyberdriver installed successfully! You may need to restart your terminal for PATH changes to take effect."
        } else {
            Write-Host "ERROR: Download appears incomplete (file too small). Please try again." -ForegroundColor Red
        }
    } else {
        Write-Host "ERROR: Download failed. Please try again." -ForegroundColor Red
    }
    ```
  </Step>

  <Step title="Restart PowerShell">
    Close and reopen PowerShell for the PATH changes to take effect. Once restarted, you can connect to Cyberdesk Cloud.
  </Step>
</Steps>

<Note>
  Legacy Cyberdriver automatically disables PowerShell's QuickEdit Mode on startup. This prevents the terminal from freezing if you accidentally click it while Cyberdriver is running.
</Note>

## Getting started

### Connect to Cyberdesk Cloud

To connect your desktop to Cyberdesk for remote automation:

```bash theme={null}
cyberdriver join --secret YOUR_API_KEY
```

Replace `YOUR_API_KEY` with your API key from the [Cyberdesk Dashboard](https://cyberdesk.io/dashboard).

On Windows, legacy Cyberdriver runs in stealth mode by default, so `cyberdriver join` continues in the background with no visible window. You'll see a confirmation message, then your PowerShell prompt returns immediately.

### Stopping Cyberdriver

To stop Cyberdriver:

```bash theme={null}
cyberdriver stop
```

<Tip>
  Since legacy Cyberdriver runs invisibly in the background, `cyberdriver stop` is the recommended way to shut it down. You can also end `cyberdriver.exe` in Task Manager.
</Tip>

### Naming a machine at join time

Pass `--name <value>` to `cyberdriver join` to set a human-readable display name for the machine. The value lands on `Machine.name` in the dashboard and is searchable via the API.

```bash theme={null}
cyberdriver join --secret YOUR_API_KEY --name "i-0abc123def456"
```

Behavior:

* **First join** (new fingerprint): the machine is created with `name` set to your value.
* **Subsequent joins** (same fingerprint, different `--name`): the existing machine's name is updated.
* **Subsequent joins without `--name`**: the existing name is preserved.
* **Validation:** printable ASCII only, max 128 characters, surrounding whitespace trimmed.
* **Uniqueness is not enforced.** Two machines can share the same name.

#### Parallel provisioning recipe

When you boot many VMs from the same image, every fresh registration starts as `name: null` and the only differentiator is the Cyberdesk machine ID. Push a name you already know per VM and look it up afterwards.

<Steps>
  <Step title="Pick a unique name per VM">
    For example, use the cloud-provider instance ID, hostname, or workflow run ID.

    ```bash theme={null}
    cyberdriver join --secret "$CYBERDESK_API_KEY" --name "$INSTANCE_ID"
    ```
  </Step>

  <Step title="Look up the machine via API">
    ```bash theme={null}
    curl -H "Authorization: Bearer $CYBERDESK_API_KEY" \
      "https://api.cyberdesk.io/v1/machines?name=$INSTANCE_ID"
    ```

    The response is a paginated list. Pick a unique-per-VM string to make this a one-shot lookup.
  </Step>

  <Step title="Use the returned machine ID for runs">
    With the Cyberdesk-issued machine ID in hand, you can target the VM for workflow runs, proxy requests, and automation.
  </Step>
</Steps>

## Common issues

### Cyberdriver can't click or interact with certain apps

If Cyberdriver appears to be running but can't click on or interact with specific applications, especially legacy enterprise software or system utilities, this is typically a permissions issue.

Solution: run Cyberdriver from an Administrator PowerShell terminal:

1. Right-click PowerShell and select **Run as Administrator**.
2. Navigate to your desired directory.
3. Run `cyberdriver join --secret YOUR_API_KEY`.

Some desktop applications require admin privileges to receive input from other processes. For regular user-level applications, you can run Cyberdriver normally without admin privileges.

### Connection issues

If Cyberdriver fails to connect or keeps disconnecting:

1. Verify your API key.
2. Check your internet connection.
3. Run `cyberdriver logs` and contact support with the output.

### Performance issues

If automation seems slow or unresponsive:

1. Close unnecessary applications.
2. Check CPU usage.
3. Disable Windows animations to speed up window switching.

### TLS certificate issues

Legacy Cyberdriver uses your system certificate store by default, which works automatically on most machines. It also bundles `certifi` as a fallback for machines missing standard root CAs.

If you see TLS/SSL certificate errors:

1. Corporate networks with SSL inspection should work if your IT department's certificate is installed in the OS trust store.
2. Fresh Windows machines may be missing root certificates. Install Windows updates or contact support if `certifi` fallback does not resolve it.

### Space key not working in certain apps

Some applications, particularly legacy enterprise apps, may not respond correctly to space key input. Try the experimental space flag:

```bash theme={null}
cyberdriver join --secret YOUR_API_KEY --experimental-space
```

This sends space using a virtual key code (`VK_SPACE`) instead of the hardware scan code.

### Failed to load Python DLL during start or reinstall

If you see an error like this:

```text theme={null}
Failed to load Python DLL 'C:\Users\Administrator\AppData\Local\.cyberdriver\_pyinstaller\_MEI42282\python39.dll'.
LoadLibrary: The specified module could not be found.
```

The installation is likely corrupted. Fully remove all Cyberdriver remnants, reboot, then reinstall.

Run in PowerShell:

```powershell theme={null}
$ErrorActionPreference = "Stop"

# Stop running instances
try { cyberdriver stop --force --timeout 3 | Out-Null } catch {}
Get-Process cyberdriver -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue

# Stop updater/launcher leftovers if present
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
  Where-Object { $_.CommandLine -match "cyberdriver-updater|cyberdriver-update\.exe|launch-hidden\.ps1|launch-hidden\.vbs" } |
  ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }

# Remove any leftover scheduled restart tasks from self-update
Get-ScheduledTask -TaskName "CyberdriverRestart_*" -ErrorAction SilentlyContinue |
  Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue

# Remove all known Cyberdriver folders
$paths = @(
  "$env:USERPROFILE\.cyberdriver",
  "$env:LOCALAPPDATA\.cyberdriver",
  "$env:APPDATA\.cyberdriver"
)
foreach ($p in $paths) {
  if (Test-Path $p) { Remove-Item $p -Recurse -Force -ErrorAction SilentlyContinue }
}

# Remove old PATH entry for clean reinstall
$toolDir = "$env:USERPROFILE\.cyberdriver"
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($userPath) {
  $newPath = (($userPath -split ';') | Where-Object { $_ -and ($_ -ne $toolDir) }) -join ';'
  [Environment]::SetEnvironmentVariable("Path", $newPath, "User")
}

Write-Host "Cyberdriver cleanup complete. Reboot, then reinstall."
```

### Clear all Cyberdriver traces (reset before reinstall)

If Cyberdriver gets stuck, keeps saying it is "already running", or a reinstall leaves broken remnants behind, run the one-liner below in PowerShell to wipe every trace of it, then run the install script again. This is often the quickest fix.

```powershell theme={null}
Get-Process -Name "Cyberdriver","cyberdriver" -EA SilentlyContinue | Stop-Process -Force -EA SilentlyContinue; Get-Service -Name "Cyberdriver","Cyberdriver Service" -EA SilentlyContinue | ForEach-Object { Stop-Service $_.Name -Force -EA SilentlyContinue; sc.exe delete $_.Name }; @("$env:USERPROFILE\.cyberdriver","$env:LOCALAPPDATA\.cyberdriver","$env:APPDATA\.cyberdriver","$env:ProgramFiles\Cyberdriver","${env:ProgramFiles(x86)}\Cyberdriver","$env:APPDATA\Cyberdriver","$env:APPDATA\Cyberdesk","$env:LOCALAPPDATA\Cyberdriver","$env:LOCALAPPDATA\Cyberdesk","$env:ProgramData\Cyberdriver","$env:ProgramData\Cyberdesk","C:\Windows\System32\config\systemprofile\AppData\Roaming\Cyberdriver","C:\Windows\System32\config\systemprofile\AppData\Roaming\Cyberdesk","C:\Windows\System32\config\systemprofile\AppData\Local\Cyberdriver","C:\Windows\System32\config\systemprofile\AppData\Local\Cyberdesk") | Where-Object { Test-Path $_ } | ForEach-Object { Remove-Item -LiteralPath $_ -Recurse -Force -EA SilentlyContinue }; foreach ($scope in 'User','Machine') { try { $p=[Environment]::GetEnvironmentVariable('Path',$scope); if($p){ [Environment]::SetEnvironmentVariable('Path', (($p -split ';' | Where-Object { $_ -and $_ -inotmatch '\\\.?cyberd(river|esk)' }) -join ';'), $scope) } } catch {} }; Remove-MpPreference -ExclusionPath "$env:LOCALAPPDATA\.cyberdriver\_pyinstaller" -EA SilentlyContinue; @("HKCU:\Software\Cyberdriver","HKCU:\Software\Cyberdesk","HKLM:\Software\Cyberdriver","HKLM:\Software\Cyberdesk","HKLM:\Software\WOW6432Node\Cyberdriver","HKLM:\Software\WOW6432Node\Cyberdesk","HKCU:\Software\Classes\cyberdriver","HKLM:\Software\Classes\cyberdriver") | Where-Object { Test-Path $_ } | ForEach-Object { Remove-Item $_ -Recurse -Force -EA SilentlyContinue }; Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*","HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -EA SilentlyContinue | Where-Object { $_.GetValue("DisplayName") -like "*Cyberdriver*" -or $_.GetValue("DisplayName") -like "*Cyberdesk*" } | ForEach-Object { Remove-Item $_.PSPath -Recurse -Force -EA SilentlyContinue }; Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs","$env:ProgramData\Microsoft\Windows\Start Menu\Programs" -Filter "*Cyberdriver*" -Recurse -EA SilentlyContinue | Remove-Item -Force -EA SilentlyContinue; Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs","$env:ProgramData\Microsoft\Windows\Start Menu\Programs" -Filter "*Cyberdesk*" -Recurse -EA SilentlyContinue | Remove-Item -Force -EA SilentlyContinue; Get-ChildItem "$env:USERPROFILE\Desktop","$env:PUBLIC\Desktop" -Filter "*Cyberdriver*.lnk" -EA SilentlyContinue | Remove-Item -Force -EA SilentlyContinue; Get-ChildItem "$env:USERPROFILE\Desktop","$env:PUBLIC\Desktop" -Filter "*Cyberdesk*.lnk" -EA SilentlyContinue | Remove-Item -Force -EA SilentlyContinue; Get-ScheduledTask -TaskName "*Cyberdriver*" -EA SilentlyContinue | Unregister-ScheduledTask -Confirm:$false; Get-ScheduledTask -TaskName "*Cyberdesk*" -EA SilentlyContinue | Unregister-ScheduledTask -Confirm:$false; Write-Host "Cyberdriver cleanup complete! Restart if an 'already running' message persists, then run the install script again." -ForegroundColor Green
```

For a full breakdown of what this removes, see [Clear All Cyberdriver Traces](/cyberdriver/clear-cyberdriver-traces).

## Configuration

Legacy Cyberdriver stores persistent configuration at:

* `%LOCALAPPDATA%\.cyberdriver\config.json`

The configuration file includes:

* **Version**: Current Cyberdriver version.
* **Fingerprint**: Unique Cyberdesk machine identifier.

Connection details such as the current host, auth secret, and active tunnel state are runtime state, not fields stored in `config.json`.

## API endpoints

When you run `cyberdriver join`, legacy Cyberdriver opens a local HTTP server on port `3000` by default. If that port is already in use, it falls forward to the next available local port. It also creates a secure reverse tunnel to Cyberdesk Cloud, allowing remote access without opening inbound ports.

### Display

* `GET /computer/display/screenshot` - Capture screen.
  * Query params: `width`, `height`, `mode` (`exact`, `aspect_fit`, `aspect_fill`)
  * Returns: PNG image.
* `GET /computer/display/dimensions` - Get screen dimensions.

### Keyboard

* `POST /computer/input/keyboard/type` - Type text.
  * Body: `{"text": "Hello world"}`
* `POST /computer/input/keyboard/key` - Send key combinations.
  * Body: `{"text": "ctrl+c"}`

### Clipboard

* `POST /computer/copy_to_clipboard` - Send `Ctrl+C` and return clipboard contents keyed by the requested name.
  * Body: `{"text": "account_number"}`

### Mouse

* `GET /computer/input/mouse/position` - Get cursor position.
* `POST /computer/input/mouse/move` - Move cursor instantly.
* `POST /computer/input/mouse/click` - Click mouse button.
* `POST /computer/input/mouse/drag` - Drag from a start position to an end position.
* `POST /computer/input/mouse/scroll` - Scroll mouse wheel vertically or horizontally.

### File system

* `GET /computer/fs/list` - List directory contents.
* `GET /computer/fs/read` - Read file contents.
* `POST /computer/fs/write` - Write file contents.

### PowerShell

* `POST /computer/shell/powershell/exec` - Execute PowerShell commands.
* `POST /computer/shell/powershell/session` - Compatibility endpoint for create/destroy session IDs.

## Security considerations

<Warning>
  Legacy Cyberdriver provides remote access to your desktop. Keep your API key secret, use trusted machines, monitor dashboard activity, and update regularly for security fixes.
</Warning>

## Legacy feature details

Legacy-specific features such as stealth mode, console protection, keepalive mode, black screen recovery, persistent virtual display, coordinate capture, and remote updates are kept here for compatibility. Some newer Cyberdriver docs describe the RustDesk-based `1.x` client and may not apply to this Python executable.

If you are intentionally running legacy Cyberdriver and need exact behavior for one of these features, contact the founders at [founders@cyberdesk.io](mailto:founders@cyberdesk.io).

## Next steps

<CardGroup cols={2}>
  <Card title="Quick Start Guide" icon="rocket" href="/quickstart">
    Create and run your first workflow.
  </Card>

  <Card title="SDK Guides" icon="code" href="/sdk-guides/typescript">
    Learn how to trigger runs programmatically.
  </Card>

  <Card title="Dashboard" icon="browser" href="https://cyberdesk.io/dashboard">
    Create workflows and manage machines.
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:founders@cyberdesk.io">
    Get help from the Cyberdesk team.
  </Card>
</CardGroup>
