Remote desktop
See and control the screen with noVNC. Windows uses a built-in capture server; Linux works with wayvnc (Hyprland, Sway) or x11vnc. Keyboard and clipboard work in both directions.
Self-hosted · Windows & Linux
Remote desktop, an interactive terminal and system management for machines you own. No port forwarding on the controlled computer: the agent connects out to your server, and you open a browser tab.
See and control the screen with noVNC. Windows uses a built-in capture server; Linux works with wayvnc (Hyprland, Sway) or x11vnc. Keyboard and clipboard work in both directions.
A real shell in xterm.js: PowerShell, cmd or Git Bash on Windows, and Bash, Zsh or Fish on Linux. Multiple tabs, resizing, Ctrl+C and the current folder shown live.
Live CPU, memory, swap, disk, uptime and signed-in users. Lock, restart or shut down a computer, each behind its own permission.
Password and emailed code to sign in, per-computer permissions, signed one-time grants for every session, an emergency stop and a full audit log.
The agent dials out to your server over WSS and reconnects on its own. Nothing listens for inbound connections on the computers you control.
Runs as a Windows service that can show the lock and sign-in screen, or as a systemd user unit on Linux. Restarts on its own after a crash.
Three parts. You run the server; each computer runs a small agent; you use a browser.
Requirements: Node 22.18 or newer (24 recommended) and stable Rust.
npm install
cp .env.example server/.env
npm run dev:server # http://127.0.0.1:8787
npm run dev:web # http://localhost:5173
Open the web UI and create an account. In development, the sign-in code is printed in the server console.
cd agent
cargo build --release
This produces the rcagent binary for Windows or Linux.
Choose Add computer in the web UI to get a pairing code, then on the computer to control:
rcagent pair --server http://127.0.0.1:8787 \
--code ABCD-EFGH --allow desktop,terminal
rcagent run
--allow is the host owner's own allow-list. The web UI can never enable more.
# Windows, elevated terminal
rcagent service install
# Linux, no root
rcagent service install
loginctl enable-linger $USER
Check what the agent detected with rcagent status.
| Host | Backend | Setup |
|---|---|---|
| Windows | Built-in (GDI capture, SendInput, Tight/JPEG) | Nothing to install |
| Hyprland, Sway, other wlroots | wayvnc on a private unix socket | pacman -S wayvnc |
| X11 (any desktop) | x11vnc on a private unix socket | apt install x11vnc |
| GNOME / KDE on Wayland | Existing local VNC server | Set desktop.backend = "vnc" |
The server refuses plain HTTP on anything but localhost. Put it behind a TLS reverse proxy, set
PUBLIC_ORIGIN, TRUST_PROXY=1 and SMTP, then npm run build && npm start.
# Caddyfile
remote.example.com {
reverse_proxy 127.0.0.1:8787
}
A scrypt-hashed password and a single-use, 10-minute emailed code. Rate limited with generic errors. Optional re-verification before terminal or power actions.
Random HttpOnly, SameSite=Strict cookies with idle and absolute expiry. You can list and revoke them. The Origin is checked on every change and every WebSocket upgrade.
An Ed25519 key is created on the host, and the server keeps only the public key. Each connection signs a fresh nonce, and the agent pins the server's signing key.
Desktop, terminal and power are separate permissions, with desktop only by default. Every request carries a signed, single-use grant that the agent checks against its own allow-list.