My coding agents do not run on my laptop. They run on a few small virtual machines on a private network, and I reach them over SSH — from a desktop, or from a phone when an idea or a failing check turns up away from the desk. The session keeps running when I disconnect, so the agent can work through a plan while I am elsewhere and I can look in on it later.
This works better than I expected. It also left two gaps that took real work to close.
Gap one: you cannot paste a screenshot into SSH
A terminal session carries text. The clipboard stays on the device in your hand. For an agent that is a real loss: a screenshot of a broken layout or an error dialog is often the fastest way to explain a problem, and over SSH there is no way to hand it over.
What the agent can do is read an image from a file path. So the fix is a small upload page on the private network, plus a drop command on each machine that fetches whatever was uploaded to a predictable path. I upload from the phone's browser and type "I dropped screenshots for you." A skill installed with the command tells the agent to run drop pull itself and read the paths it prints. No path typing, no scp.
The interesting parts were not the upload:
- Phones send awkward images. HEIC files, rotation stored as metadata, photos over the size limit the model accepts. The service detects formats by their bytes, never by extension, applies rotation to the pixels and strips all metadata from what the agent reads. The original stays untouched on the server; the agent reads a normalised copy that fits.
- "Latest" must never be stale. If a pull finds nothing new, the agent is told to say so. It must not read an older file and present it as what I just sent. That rule lives in the skill because it is exactly the mistake an agent eager to help would make.
- Several sessions, one inbox. Each upload batch gets a short id the page shows me, so an agent can fetch that exact batch even if another session already pulled the newest one.
- The image is data, not instruction. Text in a screenshot or in a filename is something to report on, never a command to follow.
The private network is the access boundary; the service has no login of its own. An early draft had an access token, but it was handed out by the same unauthenticated page it was supposed to protect. A boundary like that only looks like security, so it went. The limits that matter are on resources instead: file count, file size, pixel count, two image decodes at a time, a storage quota, and thirty days of retention.
Gap two: several machines, slightly different agents
Every machine running an agent has its own settings, instructions, hooks and plugins. Edit them on one machine and they drift away from the others. Copy everything everywhere and you copy credentials, session history and machine-specific paths along with it.
So the shared configuration lives in one private repository with an explicit allowlist. Shared: preferences, the global instructions, the curated plugin list, my own commands and hooks. Kept per machine: which optional features this machine actually has, gateway endpoints, tool paths. Never synced: credentials, sessions, transcripts, memories, caches.
A timer on each machine checks for updates every few minutes and only applies a change that is a clean fast-forward. If I edited an installed file by hand, the sync notices, backs it up once and leaves that file alone until I reconcile it. It never commits or pushes on its own. No machine silently overwrites another machine's work. That is the same rule I want from the agents themselves.
What carries over
Both tools exist because the agent is good at the work and bad at noticing what it was not given. The upload service makes sure the agent can actually see what I see. The configuration sync makes sure each agent works under the same rules. Neither one is clever. Both are designed around the failure that would be easy to miss: the stale image presented as new, and the edit that quietly disappears.
The upload service is public: github.com/Pauhe/claude-drop, including its design document and the external reviews that changed it.