Skip to main content
How-To6 min read

Running a coding agent from your phone

Agentic coding sessions run long these days. Mine regularly run for hours: the agent works through a plan, edits files, runs tests, and keeps going until it hits something worth stopping for. That is the point of running an agent instead of babysitting a script. But it creates a specific kind of dead time. When the agent stops to ask permission or lay out a decision, it waits. If I am away from the desk when that happens, the session does not fail, it just sits there, blocked, until I get back to a keyboard.

The fix is not a smarter agent. It is being able to reach the running session from wherever I actually am. I built this with tools I already had installed, nothing custom, and it turned "the agent is stuck for three hours until I'm home" into "I'll glance at it from the coffee shop."

The stack: four tools you probably already know

None of this needed software written for the purpose. Four pieces, all standard:

  1. A mesh VPN. I use Tailscale. Install it on the laptop and on the phone, both join the same private network, and from that point on they can reach each other directly, from anywhere, with no port forwarding and nothing exposed to the public internet.
  2. The Mac's built-in SSH server. Turned on under System Settings, General, Sharing, Remote Login. No separate install needed.
  3. tmux, for session persistence. The agent runs inside a named tmux session on the laptop. tmux keeps that session alive independent of any one connection to it, so a dropped connection never touches the agent.
  4. An SSH client on the phone. I use Termius on iPhone. Any decent one works the same way.

The flow: attach, look, answer, detach

In practice: I start the agent inside a named tmux session on the laptop, at my desk, the normal way. Later, wherever I am, I open the SSH client on the phone, connect over the VPN, and attach to that same tmux session. What I am looking at is not a summary or a notification, it is the exact live session: I can scroll back through what the agent has done, read the question it is stuck on, and answer it or approve the next step.

Then I detach, and the agent keeps working exactly as before. Nothing runs on the phone. It is a window into the laptop, not a second copy of anything.

Lock the door: key only

This setup is worth doing properly or not at all, because Remote Login listens on every network interface the laptop joins, not only the VPN one. So before relying on it day to day, I hardened SSH access itself: generate a fresh Ed25519 keypair, install the public half on the Mac, import the private half into the phone's SSH client, then go into the SSH server configuration and turn off password authentication and keyboard-interactive authentication entirely. After that, a connection succeeds only if it presents the right key. Guessing a password is no longer a path in.

Worth thinking through before you do it: with password authentication off, if you ever lose the phone, and the key on it, you cannot SSH your way back in from anywhere else either. Getting back in at that point means physical access to the Mac. That is the right trade for the security it buys, but it is a real trade, and it is worth knowing about in advance rather than discovering it at the worst moment.

What actually goes wrong

Two things bit me doing this for real, both worth knowing up front.

The first is sleep. A sleeping Mac is not reachable, no matter how well the rest of the setup works. Keep the laptop plugged in and turn on "Prevent automatic sleeping when the display is off" in the sleep settings. To be fair, sleep is not destructive: it suspends the tmux session rather than killing it, so the agent's work is still there and picks back up the moment the machine wakes. You just cannot reach it, or wake it remotely, until something else wakes the Mac first.

The second is smaller but has cost me time: on recent versions of macOS, trying to flip Remote Login on from the command line can quietly fail because of permission protections built into the OS. Going into System Settings and toggling it there just works. If a command line attempt seems to succeed but SSH still refuses connections, check the Settings toggle before assuming anything else is wrong.

The bottom line

I want to be honest about what this does and does not do. It does not make the agent smarter, faster, or more capable. What it removes is dead time. A question that would previously have parked a session for three hours now gets answered from a queue, a lunch break, or a commute. That matters more than it sounds like, because it is what makes long-running, semi-autonomous agent work practical in the first place: approvals stop being tied to a desk. It is really the same idea as making sure an agent only pauses at the point that actually needs a human, something I wrote about in where the irreversible line should sit. This setup is just how the human shows up on the other side of that line faster.

If you are running agents long enough that this dead time is costing you real hours, and you want the whole approval and guardrail picture set up properly rather than bolted on after the fact, send a briefand I'll walk through it with you.

More questions?

Easier on a call than in a blog post.

Replying within 4 hours during working hours