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.
What it does
| Machine info | name, OS and version, architecture, uptime, the user, and the IP addresses of its network interfaces |
| Clipboard, send | puts text from the console on the machine's clipboard, up to 64 KB |
| Clipboard, get | reads the machine's clipboard into the console. Off unless allowed on the machine, and never while its screen is locked |
| Restart, shut down | through 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 run | answer the device until Ctrl+C |
espkvm-agent find | print which port is ESP-KVM's |
espkvm-agent info | print what it would tell the device |
espkvm-agent uninstall | take 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-read | the device may read the clipboard, while the screen is not locked |
--allow-power | the 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.