Agent Screen
Local dashboard for viewing, routing tasks to, and controlling agent devices over Tailscale
#Agent Screen
Agent Screen is a local dashboard for a fleet of agent computers connected through Tailscale. It shows each device's screen, opens the native VNC client for control, and can route a prompt to an agent command on that device over SSH.
The controller listens on 127.0.0.1 only. Real device names, SSH aliases, Tailnet hosts, and task commands live in a private chmod 600 file outside the repository.
#What it does
- Shows configured macOS and Windows devices in one local dashboard.
- Captures screens through allowlisted SSH aliases.
- Opens the configured
vnc://route in the controller's native client. - Sends task text over SSH stdin, so the prompt never becomes a shell argument.
- Keeps the last good frame in an owner-only local cache.
#Requirements
- macOS controller with Python 3.11 or newer.
- Tailscale and SSH connectivity between the controller and each device.
- VNC or Screen Sharing enabled only on the private network.
- A logged-in desktop session on each target. macOS capture uses
screencapture; Windows capture uses the interactive desktop APIs available to the SSH session. - Optional: an agent CLI that accepts a prompt on stdin. The example uses
hermes chat --query-file - --oneshot.
#Install
git clone https://github.com/destrynewiger/agent-screen.git cd agent-screen python3 -m venv .venv . .venv/bin/activate python -m pip install -e .
Create the private device file:
mkdir -p ~/.config/agent-screen cp examples/devices.example.json ~/.config/agent-screen/devices.json chmod 600 ~/.config/agent-screen/devices.json
Edit that file with your own SSH aliases and Tailscale VNC routes. Keep the file out of Git.
Start the controller:
agent-screen
Open http://127.0.0.1:8766.
If that port is in use, choose another unprivileged port:
AGENT_SCREEN_PORT=8876 agent-screen
#Device configuration
Each device has these fields:
| Field | Purpose |
|---|---|
id |
Stable local identifier used by the dashboard. |
label |
Agent name shown in the dashboard. Use a role or alias if preferred. |
device |
Human-readable machine label. |
ssh_alias |
A fixed alias from ~/.ssh/config. Request bodies cannot override it. |
platform |
macos or windows. |
vnc_uri |
Fixed vnc://host:port route used by Take control. |
task_command |
Optional command array. Agent Screen passes the prompt through stdin. |
For a named agent profile, point task_command at that profile's wrapper or CLI invocation. Agent Screen quotes every configured token and does not accept command text from the browser.
#Security model
- The HTTP service refuses non-loopback binds, foreign Host headers, and foreign Origins.
- Browser APIs expose labels and capability flags, not SSH aliases or VNC hosts.
- Device IDs map to a startup-time allowlist. HTTP callers cannot supply hosts, URIs, or commands.
- The device file must belong to the current user and have no group or world permissions.
- SSH uses batch mode and strict host-key checking.
- Frames use
Cache-Control: no-storeand an owner-only cache directory.
Agent Screen does not configure Tailscale ACLs, SSH, VNC, or agent credentials. Keep those controls narrow. Never expose the dashboard or VNC port to the public internet.
#Test
python3 -m unittest discover -s tests -v
#Status
This is an early public release. macOS Screen Recording permissions and Windows session isolation vary by host setup, so test capture on each device before relying on unattended monitoring.
#License
MIT