ESP-KVM agent

A small program for the machine ESP-KVM is plugged into. It talks to the device over the same USB cable as the keyboard and mouse, with no network in between. The console then shows what the machine is, moves text to and from its clipboard and can shut it down cleanly.

Download  Source (Apache-2.0)

What it does

Machine infoname, OS and version, architecture, uptime, the user, and the IP addresses of its network interfaces
Clipboard, sendputs text from the console on the machine's clipboard, up to 64 KB
Clipboard, getreads the machine's clipboard into the console. Off unless allowed on the machine, and never while its screen is locked
Restart, shut downthrough the OS, so programs get to close. Off unless allowed on the machine

It runs no commands and only answers what the device asks, one line of JSON per question.

Turn it on in ESP-KVM

Settings, Power, "Serial port over USB": set it to agent and restart the device. The machine then sees a serial port next to the keyboard and mouse. Linux, Windows 10 and 11 and macOS all have the driver built in. The agent finds the port by its USB IDs (303A:4013), so the port name does not matter.

The port can't be on together with the gamepad: the two need more USB endpoints than the ESP32-P4 has.

Install on the machine

Pick the file for the machine from the releases. It is one file, about 3.5 MB.

Linux

In the desktop session, with the clipboard:

sudo ./espkvm-agent-linux-amd64 install --desktop

It starts at every login of every user. The clipboard needs wl-clipboard on Wayland or xclip on X11.

As a system service, for a server with no desktop (no clipboard):

sudo ./espkvm-agent-linux-amd64 install

The service runs as its own user espkvm-agent, not root. Both ways add a udev rule that keeps ModemManager away from the port. Files for arm64 and 32-bit arm are there too.

Windows

espkvm-agent-windows-amd64.exe install

From a terminal, no administrator needed. It starts at every login.

macOS

xattr -d com.apple.quarantine espkvm-agent-darwin-arm64
./espkvm-agent-darwin-arm64 install

The file is not signed yet, hence the first line. It starts at every login.

Without installing

espkvm-agent runanswer the device until Ctrl+C
espkvm-agent findprint which port is ESP-KVM's
espkvm-agent infoprint what it would tell the device
espkvm-agent uninstalltake it all out again (with sudo on Linux)

What the device may do

Two switches give the device more. They go to install or run on the machine. The device can't turn them on by itself.

--allow-clipboard-readthe device may read the clipboard, while the screen is not locked
--allow-powerthe device may shut the machine down or restart it. On Linux as a service this adds a polkit rule for the espkvm-agent user

Whoever controls ESP-KVM already has this machine's keyboard and mouse, so the agent adds little they could not get by typing. The exception is a locked screen: typing gets nowhere there, and the clipboard may still hold a password copied a minute ago. That is why reading it is off by default and stops while the screen is locked. Linux checks logind's lock flag, which GNOME, KDE and most lock screens set. Windows checks the input desktop, macOS the I/O registry.

On Linux the system service also runs without capabilities, with most of the system read-only, so a bug in the agent does not hand out root.

When something does not work

"No agent on the machine yet"is the setting on "agent" and was the device restarted? Does espkvm-agent find see the port? On Linux, is the agent running: systemctl status espkvm-agent, or systemctl --user status espkvm-agent for the desktop one
"runs as a system service, which has no clipboard"install it with --desktop
"Reading the clipboard is off"install it again with --allow-clipboard-read
"The machine's screen is locked"unlock it, or send text with Send, which works either way
"no clipboard tool"install wl-clipboard or xclip

For scripts

The device passes it all on over its REST API:

GET  /api/v1/agent             is an agent there, its version and OS
GET  /api/v1/agent/info        the machine
GET  /api/v1/agent/clipboard   {"text": "..."}
POST /api/v1/agent/clipboard   {"text": "..."}
POST /api/v1/agent/power       {"action": "shutdown"} or {"action": "reboot"}

The protocol between the device and the agent is in PROTOCOL.md.