DEV Community

vianel
vianel

Posted on

I said I didn't want my agents on my phone. I changed my mind.

In my last post about sticking with herdr over Orca, I wrote this about phone notifications:

When I'm away from my desk, I want to be away and disconnect so checking on agents from my phone isn't a feature I'm missing.

Well. herdr has a phone app now (https://herdr.dev/mobile/) , I installed it, and now my agents are on my phone. So let me eat my words properly.

I still don't want my phone buzzing every time an agent finishes. That part hasn't changed. What changed is that I kept walking away from my desk in the middle of a session, and the agent would sit there blocked on a question until I came back. I don't want notifications. I want to continue the same session from wherever I am.

Getting there took me about an hour and four different errors, so here's the whole thing in order. Hopefully it takes you ten minutes.

The app asks for an address, a user and a port

That's it. No account, no pairing code. If those three fields look familiar it's because it's just SSH. The app connects to your machine the same way herdr --remote does.

Which means your Mac has to accept SSH connections, and mine didn't.

Problem 1: Remote Login was off

The obvious fix is one command:

sudo systemsetup -setremotelogin on
Enter fullscreen mode Exit fullscreen mode

And the obvious fix didn't work:

setremotelogin: Turning Remote Login on or off requires Full Disk Access privileges.
Enter fullscreen mode Exit fullscreen mode

Instead of giving my terminal Full Disk Access just for this, I used the toggle: System Settings → General → Sharing → Remote Login. Done.

Then the three fields are:

  • Address: your Mac's local IP (ipconfig getifaddr en0)
  • User: your macOS username (whoami)
  • Port: 22

Problem 2: the phone needs to be allowed in

The app generates its own SSH key and shows you the public half. That goes into authorized_keys on the Mac:

echo 'ssh-ed25519 AAAA... herdr-mobile' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

Small tip from someone who got it wrong three times in a row: paste that as one line. My terminal wrapped it, the chmod ran without a file name, and I spent a few minutes staring at a permission denied that had nothing to do with the actual problem.

The app also shows you a fingerprint for the machine it's talking to. You can check it's really your Mac with:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Enter fullscreen mode Exit fullscreen mode

Problem 3: "Herdr isn't installed yet"

This one confused me the most, because herdr was very much installed. I was literally using it.

Two things were going on.

My PATH. herdr lives in ~/.local/bin, and I add that folder to my PATH in ~/.zshrc. But an SSH session that runs a command doesn't load .zshrc, only .zshenv. So for the phone, that folder didn't exist:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshenv
Enter fullscreen mode Exit fullscreen mode

It wasn't asking for herdr. It was asking for Herdr Core, a separate small binary called hc. The app tells you how to get it:

curl -fsSL https://releases.herdr.dev/core/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

(I read the script before running it, like a responsible adult. It checks the checksum and the code signature and drops the binary in ~/.local/bin.)

After that the app connected. Finally.

Problem 4: "No agents yet"

Connected, and empty. All my panes were running on the Mac and the phone showed nothing.

This is the part worth understanding: the phone shows terminals that run inside Herdr Core, not the panes in your herdr session. An agent you started the normal way isn't visible. You have to start it through hc:

hc run --bg --name stripe claude
hc attach stripe
Enter fullscreen mode Exit fullscreen mode

The first line starts Claude Code in a terminal that Core keeps alive. The second puts your current terminal on it. You work as usual, ctrl+\ detaches, and the agent keeps running. Open the phone and the same session is there, same conversation, same everything.

That's exactly what I wanted. But I wasn't going to type two commands every time.

Making it invisible

My flow is: open a pane, type claude. I wanted to keep that. So claude is now a small function in my .zshrc:

claude() {
  if [[ -n $HC_TERMINAL_ID || ! -t 0 || ! -t 1 || ( $# -gt 0 && $1 != -* ) \
        || -n ${@[(r)(-p|--print|-v|--version|-h|--help)]} ]]; then
    command claude "$@"; return
  fi
  local name=${${${PWD:t:l}//[^a-z0-9_-]/-}[1,32]} out
  out=$(hc run --bg --rm --json --name "$name" -- claude "$@" 2>/dev/null) \
    || out=$(hc run --bg --rm --json -- claude "$@") || { print -r -- "$out"; return 1; }
  hc attach "${${out#*\"address\":\"}%%\"*}"
}
Enter fullscreen mode Exit fullscreen mode

It looks worse than it is:

  • Interactive sessions go through Core. Plain claude, claude --continue, claude --resume.
  • Everything else is left alone. claude -p, claude --version, claude mcp ..., anything piped. Scripts and other agents calling Claude don't notice a thing.
  • The terminal is named after the folder, so on the phone I see the directory name and not t7. If the name is taken it just falls back to an unnamed one.
  • No nesting. Inside a Core terminal, HC_TERMINAL_ID is set, so it runs the real binary.
  • It cleans up. --rm removes the terminal when Claude exits.

And if I ever want the old behaviour, command claude skips the whole thing.

What I'd tell you before you try it

It's local network only, out of the box. The address is your Mac's local IP, so the phone has to be on the same Wi-Fi. For real "away from home" access you'd put something like Tailscale on both devices and use that address. I haven't set that up yet.

Your local IP can change. If the app stops connecting one day, check ipconfig getifaddr en0 again before you debug anything else.

You are opening SSH on your machine. Key-only access from one device on my own network is a trade I'm fine with, but it's a decision, not a default.

So, was I wrong?

Half wrong. I still don't want to be pinged by my agents. When I'm away, I'm away.

But there's a difference between an agent interrupting me and me choosing to pick up where I left off. The first one is a notification. The second one is just my terminal, in my pocket. Turns out I did want that.

Are you running your agents from your phone? Or is that where you draw the line?

Top comments (0)