So you’ve discovered Claude Code and now you’re hooked. The problem? It runs on your Mac, and you’re currently… not at your Mac. Maybe you’re on a train, at a coffee shop, or pretending to listen in a meeting while secretly thinking about that bug you need to fix.
Good news: with a bit of setup and a working network connection, you can reach Claude Code from your phone, tablet, or that borrowed laptop at a conference. Here’s how I made it work.
2026 update: This is still a useful personal workflow, but treat it as a pattern, not a universal secure-access blueprint. Claude Code’s authentication details can change; its current docs describe macOS Keychain storage and a file fallback when the Keychain rejects a login write. Tailscale encrypts traffic end-to-end, but its coordination service still needs connection metadata, and some networks force relayed instead of direct connections. Termius and other mobile SSH clients can also be suspended by iOS or Android background rules, so keep the actual work inside
dtach,tmux, orscreenand treat stored mobile SSH keys as a deliberate trust decision.
The Stack
- Tailscale — secure access to your machine
- Termius — SSH client that works everywhere
- dtach — session persistence without the bloat
- SSH ProxyJump — reaching machines behind firewalls
Let’s break it down.
1. Secure Access with Tailscale
First things first: you probably don’t want your dev machine exposed to the entire internet. Enter Tailscale.
What is it? A mesh VPN built on WireGuard. Instead of routing all traffic through a central server (slow, single point of failure), Tailscale creates encrypted peer-to-peer connections between your devices.
Why it’s great:
- Zero config — Install, log in, done. No port forwarding, no firewall rules
- NAT traversal — Works through basically any network, even that sketchy hotel WiFi
- End-to-end encryption — Traffic is encrypted between devices; Tailscale never sees your data
- Magic DNS — Access your machines by name:
ssh macbook.tailnet.ts.net
Quick setup:
- Download Tailscale on your Mac and phone
- Log in with the same account
- Your devices can now talk to each other securely
Your phone can now reach your Mac via its Tailscale IP or hostname. This connection doesn’t require a public SSH port; access within the tailnet still depends on its access rules.
2. SSH Client: Termius
Now you need an SSH client on your mobile device. I use Termius.
Why Termius?
- Cross-platform — iOS, Android, macOS, Windows, Linux. Same app everywhere
- Encrypted sync — Your hosts, credentials, and SSH keys sync across devices using end-to-end encryption
- Actually good mobile experience — Not just a desktop app crammed into a phone
Setup tips:
- Add your Mac as a host with its Tailscale hostname
- Import your SSH key (or generate a new one)
- Enable Touch ID / Face ID for quick access
With Termius + Tailscale, you can SSH into your Mac from your phone in about 3 taps.
3. Connection Stability: Two Approaches
Here’s where it gets interesting. SSH over mobile networks can be… fragile. Your connection drops when you switch from WiFi to LTE, your phone goes to sleep, or — my personal favorite — you step into an elevator. Every. Single. Day. My building’s elevator is apparently a Faraday cage designed by someone who really hates remote work.
Two solutions:
Option A: Mosh (Mobile Shell)
Mosh is designed for exactly this problem.
How it works:
- Uses UDP instead of TCP
- Synchronizes terminal state, not keystrokes
- Survives IP address changes, network switches, and laptop sleep
Installation:
# On your Mac (server)
brew install mosh
# Connect from Termius or another mosh client
mosh user@macbook.tailnet.ts.netThe catch? Mosh has some annoying limitations:
- No native scrollback — Mosh only syncs the visible screen. You can’t scroll up. Workaround: run
tmuxinside Mosh - No ProxyJump support — Can’t chain through jump hosts (more on this later)
If you need scrollback or ProxyJump, there’s a better option…
Option B: dtach (My Current Setup)
dtach is a tiny program that does one thing: detach/reattach terminal sessions. No window splitting, no status bars, no 200 keybindings to memorize. Just persistence.
Why dtach over tmux?
- Lighter — Does one thing well
- TERM-agnostic — Doesn’t break terminal features like scrollback
- Native scrolling works — Because dtach just forwards control sequences
Here’s my setup in ~/.zshrc — it auto-attaches to an existing session or creates a new one:
# Auto-attach dtach for SSH sessions
if [[ -z "$DTACH" ]] && [[ -n "$SSH_CONNECTION" ]] && [[ -t 0 ]]; then
SOCKET="/tmp/dtach-$USER"
if [[ -S "$SOCKET" ]]; then
# Existing session — attach to it
exec /opt/homebrew/bin/dtach -a "$SOCKET"
else
# New session — create socket and start a shell
export DTACH=1
exec /opt/homebrew/bin/dtach -c "$SOCKET" zsh
fi
fiWhat’s happening here:
- When you SSH in, it checks if a dtach socket exists
- If yes → attaches to your existing session (you pick up right where you left off)
- If no → starts a new shell session
The Keychain unlock dance:
If Claude Code cannot access your saved login over SSH, your Keychain may be locked. Unlock the login Keychain as the same user running Claude Code; you don’t need sudo for your own Keychain.
First, check its path:
security login-keychain -d userThen unlock that path. This is a common default; use the path printed above if yours differs:
security unlock-keychain "$HOME/Library/Keychains/login.keychain-db"The command prompts for your Keychain password, usually the same as your login password. Without an explicit path, security unlock-keychain selects the default Keychain, which may differ from your login Keychain. Keep the password out of your shell configuration and command arguments.
Unlocking isn’t required for every authentication method. The current Claude Code docs say that macOS normally uses the encrypted Keychain, but when a login write is rejected, it falls back to .credentials.json in the Claude configuration directory with permissions 0600. A Console sign-in that creates an API key still requires a writable Keychain. Check which method you’re using before treating an authentication error as a Keychain problem.
Installation:
brew install dtachDetaching: Press Ctrl+\ to detach. Your session keeps running; just SSH back in to resume.
4. Host Chaining with SSH ProxyJump
Here’s my scenario: Tailscale works great on my Mac at home. But on mobile networks? Let’s just say the authorities in my country have… opinions about WireGuard traffic. The kind of opinions that occasionally make your packets disappear into the void. Tailscale on my phone works sometimes, and sometimes it just… doesn’t.
Solution? I have a VPS with a public IP and Tailscale installed. When mobile Tailscale acts up, I SSH to the VPS directly, and from there jump to my Mac via the tailnet. This gives me another route, as long as the network allows SSH to the VPS.
The setup:
- VPS with public IP + Tailscale (your reliable “entry point”)
- Your Mac with Tailscale (reachable from VPS via tailnet)
- Your phone — Tailscale optional, regular internet is enough
The good news? Termius supports jump hosts out of the box. Just set your VPS as a “Jump Host” in the host settings for your Mac, and it handles the rest. No SSH config files to manage, syncs across all your devices.
SSH will:
- Connect to VPS via public internet (no Tailscale needed on phone)
- From VPS, connect to your Mac via Tailscale
- Works even when mobile WireGuard is having a bad day
Note: This is another reason I use dtach instead of Mosh — Mosh doesn’t support ProxyJump natively.
Putting It All Together
My daily workflow:
- Tailscale runs on my Mac and phone
- Termius on my iPhone has my hosts configured
- dtach keeps my Claude Code session alive
- ProxyJump lets me reach my work machine through a VPS
The result? I can pull out my phone, tap twice, and I’m in an active Claude Code session — complete with scrollback, full terminal features, and all my context preserved.
Is it as good as sitting at my desk? No. But it’s surprisingly usable for quick fixes, code reviews, or just keeping an eye on a long-running task.
I also use this exact setup to manage my “second brain” in Obsidian with Claude Code — but that’s a story for another post.
Now if you’ll excuse me, I have some code to write. I’m heading to the beach — and yes, I’m bringing Claude with me. Russian beaches in January are… brisk. But that’s never stopped me before.






