Using Your Mac as a Remote Endless Working Agent with Moshi
The complete guide to running an always-on AI agent on your Mac and controlling it from your iPhone
TL;DR: Set up your Mac with mosh + tmux. Connect from your iPhone with Moshi. Get push notifications when your agent needs input, approve from anywhere, keep coding.
The Setup
Your Mac sits on your desk running an AI agent in a tmux session. When you step away, the agent keeps working. When it needs input, you get a push notification on your iPhone. Tap to connect with Moshi, approve the action, and walk away.
- Your Mac: Runs mosh + tmux + claude. Agent runs 24/7.
- Your iPhone: Moshi handles everything—mosh protocol, push notifications, voice input.
┌──────────────────┐
│ Mac (Desktop) │ mosh + tmux + claude
│ Always On │ Agent runs 24/7
└────────┬─────────┘
│ Push notification
▼
┌──────────────────┐
│ iPhone │ Moshi app
│ │ Approve & continue
└──────────────────┘
Why Mosh over Plain SSH
SSH over unreliable networks is painful. Switch WiFi networks, go to cellular, or let your phone sleep—your session dies.
Mosh (Mobile Shell) was built for this.
mosh vs SSH
| Feature | SSH | mosh |
|---|---|---|
| Protocol | TCP | UDP |
| Network roaming | Session dies | Survives |
| Packet loss handling | Freezes | Graceful |
| Local echo | None | Instant (~5ms) |
| Ctrl+C reliability | Can fail | Always works |
According to the mosh research paper, on a link with 29% packet loss, mosh reduced average response time from 16.8 seconds to 0.33 seconds—a 50x improvement.
This is critical for "endless" sessions. Your agent might run for hours or days. Mosh keeps you connected across network changes, sleep cycles, and spotty cellular.
The Scrollback Problem
Critical: mosh has no scrollback buffer.
From GitHub issue #122:
"Mosh's terminal scrollback buffer is incomplete because Mosh synchronizes only the visible state of the terminal."
Run ls -la on a large directory, and the overflow is gone. You can't scroll up.
The solution: always use mosh with a terminal multiplexer. Mosh handles the connection. tmux (or Zellij) handles the scrollback.
Mac Setup (Always-On)
Your Mac needs to stay awake and accessible. Here's the configuration.
Prevent Sleep
System Settings → Energy Saver (or Battery → Options on laptops):
- Prevent automatic sleeping when the display is off: Enable
- Wake for network access: Enable
- Start up automatically after a power failure: Enable (if available)
For headless Mac Minis, you can also disable display sleep entirely since there's no display.
Temporary Override with caffeinate
For one-off long sessions without changing system settings:
# Prevent sleep indefinitely (Ctrl+C to stop)
caffeinate
# Prevent sleep for 4 hours
caffeinate -t 14400
# Prevent sleep while a command runs
caffeinate -s claude
Enable Remote Login
System Settings → General → Sharing → Remote Login: Enable
This enables the SSH server. Mosh uses SSH for initial authentication, then switches to UDP.
Install mosh and tmux
# Install Homebrew if needed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install mosh and tmux
brew install mosh tmux
Headless Mac Mini Tips
If you're running a Mac Mini without a display:
- HDMI dummy plug: Some Macs throttle GPU without a display. A $10 dummy plug fixes this.
- Screen Sharing: Enable in System Settings → Sharing for emergency GUI access.
- Automatic login: System Settings → Users & Groups → Login Options → Automatic login (use with caution, ensure disk encryption is on).
Terminal Multiplexer: tmux (Recommended)
tmux creates persistent terminal sessions that survive disconnections—essential for remote development.
Why tmux with mosh
- Persistence: Sessions survive network drops, phone sleep, and app switches
- Scrollback: Captures all output that mosh discards
- Multiplexing: Multiple windows and panes in one session
- Detach/attach: Start work on your laptop, continue on your phone
- Title propagation: Configurable titles that Moshi displays
Recommended Configuration
Create ~/.tmux.conf:
# Large scrollback buffer (default is 2000)
set -g history-limit 50000
# Enable mouse support (scrolling)
set -g mouse on
# Pass window titles to terminal (Moshi displays these)
set -g set-titles on
set -g set-titles-string "#S:#W"
# Reload config
bind r source-file ~/.tmux.conf \; display "Config reloaded"
Apply changes:
tmux source-file ~/.tmux.conf
tmux Cheatsheet
All commands use the default prefix Ctrl+B. Moshi has a dedicated Ctrl+B button and a tmux shortcuts panel for easy access.
Sessions:
| Command | Description |
|---|---|
tmux new -s dev | Create named session |
tmux attach -t dev | Attach to session |
tmux ls | List sessions |
Ctrl+B, d | Detach from session |
Ctrl+B, $ | Rename session |
Windows:
| Command | Description |
|---|---|
Ctrl+B, c | New window |
Ctrl+B, , | Rename window |
Ctrl+B, n | Next window |
Ctrl+B, p | Previous window |
Ctrl+B, 0-9 | Switch to window by number |
Ctrl+B, & | Close window |
Scrollback:
| Command | Description |
|---|---|
Ctrl+B, [ | Enter scroll mode |
| Arrow keys / PgUp/PgDn | Scroll |
q | Exit scroll mode |
/ | Search forward (in scroll mode) |
? | Search backward (in scroll mode) |
Terminal Multiplexer: Zellij (Alternative)
Zellij is a modern terminal multiplexer with a more discoverable UI. If you find tmux's keybindings hard to remember, Zellij might suit you better.
When to Choose Zellij
- You prefer on-screen hints for keybindings
- You want a more modern, batteries-included experience
- You don't need custom title format propagation
Limitation: Title Customization
Unlike tmux's set-titles-string, Zellij doesn't yet support customizing the terminal title format (issue #1495). Titles propagate automatically, but you can't configure the format like #S:#W.
If title customization matters for your Moshi workflow, stick with tmux.
Installation
brew install zellij
Small-Screen Configuration
Create ~/.config/zellij/config.kdl:
// Remove pane borders (saves screen space)
pane_frames false
// Simplified UI without decorative arrow fonts
simplified_ui true
// Use compact layout (minimal chrome)
default_layout "compact"
// Mouse support
mouse_mode true
// Large scrollback
scroll_buffer_size 50000
The compact layout removes the status bar, giving you maximum terminal space on a phone screen.
Tip: Start sessions with a name to make the status bar more meaningful:
zellij -s claude
This shows "Zellij (claude)" instead of a random name like "friendly-tiger".
Zellij Cheatsheet
Zellij uses modes. Press Ctrl+G to see all available actions.
Basics:
| Command | Description |
|---|---|
zellij | Start new session |
zellij -s dev | Start named session |
zellij attach dev | Attach to session |
zellij ls | List sessions |
Navigation (default mode):
| Command | Description |
|---|---|
Ctrl+T | Tab mode |
Ctrl+S | Scroll mode |
Ctrl+O | Session mode |
Ctrl+Q | Quit |
Tab Mode (Ctrl+T):
| Key | Description |
|---|---|
n | New tab |
h/l | Previous/next tab |
1-9 | Go to tab by number |
r | Rename tab |
x | Close tab |
Scroll Mode (Ctrl+S):
| Key | Description |
|---|---|
j/k | Scroll down/up |
d/u | Half page down/up |
/ | Search |
n/N | Next/previous match |
Esc | Exit scroll mode |
Session Mode (Ctrl+O):
| Key | Description |
|---|---|
d | Detach |
w | Session manager |
Network Layer
Before you can connect from your iPhone, you need a way to reach your Mac from anywhere.
Tailscale (Recommended)
Tailscale creates a secure mesh VPN using WireGuard. Every device gets a stable IP that works from anywhere—home, office, coffee shop, cellular.
Why Tailscale:
- Zero configuration port forwarding
- Works behind NAT and firewalls
- Peer-to-peer (fast, no relay latency in most cases)
- Free for personal use (up to 100 devices)
Mac setup:
# Install Tailscale (CLI only)
brew install tailscale
# Or install from Mac App Store for the menu bar GUI
# Start and authenticate
sudo tailscale up --ssh
# Get your Tailscale IP
tailscale ip
# Example: 100.64.0.1
The --ssh flag enables Tailscale SSH—you can SSH using your Tailscale identity without managing keys.
iPhone setup:
- Install Tailscale from the App Store
- Sign in with the same account
- Your Mac's Tailscale IP now works from your phone
WireGuard (Self-Hosted or Router Built-in)
If you prefer self-hosting, WireGuard gives you the same protocol benefits with full control. Many routers (UniFi, pfSense, OpenWrt, ASUS with Merlin) have WireGuard built-in—check your router's VPN settings.
brew install wireguard-tools
You'll need to set up a WireGuard server (or use a VPS as a relay) and configure keys manually.
Surge / Proxies (Restricted Networks)
If you're in an environment with restrictive firewalls (corporate networks, some countries), you might need a proxy layer:
- Surge (Mac/iOS)
- Shadowsocks
- Custom SOCKS5/HTTP proxies
These can tunnel your mosh/SSH traffic through allowed ports (443, 80) when UDP is blocked.
iPhone Setup with Moshi
Moshi is the native iOS terminal built on mosh—purpose-built for AI agent workflows.
Initial Setup
- Install Tailscale from the App Store and sign in
- Install Moshi from the App Store
- Add your server:
- Host: Your Mac's Tailscale IP (e.g.,
100.64.0.1) - Username: Your Mac username
- Authentication: SSH key (stored in Secure Enclave, protected by Face ID)
- Host: Your Mac's Tailscale IP (e.g.,
Enable Push Notifications
This is Moshi's killer feature for AI agent workflows.
- Open Moshi → Settings → Notifications
- Enable notifications and copy your webhook token
Configure Your AI Agent
Add this to your project's CLAUDE.md or AGENTS.md:
## Notifications
When you complete a task or need input, notify me:
curl -s -X POST https://api.getmoshi.app/api/webhook \
-H "Content-Type: application/json" \
-d '{"token": "YOUR_TOKEN", "title": "Status", "message": "Brief summary"}'
Replace YOUR_TOKEN with your Moshi webhook token.
Now when Claude Code needs approval or finishes a task, you get a push notification on your iPhone and Apple Watch. Tap to open Moshi directly into your session.
Voice Input
Moshi runs OpenAI's Whisper model locally on your iPhone:
- Zero latency: No network round-trip
- Technical accuracy: Understands code, paths, and technical terms
- Privacy: Voice never leaves your device
- Works offline: Subway, airplane mode, spotty cellular
When Claude asks "Should I run the migration?", hold the mic button, say "yes", release. Done.
Powerline Fonts
Moshi has built-in support for Powerline fonts. If your tmux status bar or shell prompt uses Powerline symbols, they'll render correctly without additional font installation.
Security Considerations
SSH Key-Only Authentication
Disable password authentication on your Mac:
# Edit SSH config
sudo nano /etc/ssh/sshd_config
# Add or modify these lines:
PasswordAuthentication no
ChallengeResponseAuthentication no
# Restart SSH
sudo launchctl stop com.openssh.sshd
sudo launchctl start com.openssh.sshd
With Tailscale SSH (--ssh flag), this is handled automatically—authentication uses your Tailscale identity.
Why VPN over Port Forwarding
Never expose SSH (port 22) or mosh (UDP 60000-61000) directly to the internet.
| Approach | Risk |
|---|---|
| Port forwarding | Exposed to entire internet, constant brute-force attempts |
| Tailscale/WireGuard | Only accessible to your authenticated devices |
Tailscale and WireGuard create a private network. Your Mac isn't visible to the public internet at all.
Firewall
If using Tailscale, no firewall changes needed—traffic flows over the Tailscale interface.
If self-hosting WireGuard or exposing services directly:
# macOS firewall (allow mosh)
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /usr/local/bin/mosh-server
The Complete Workflow
Here's how it all fits together:
┌─────────────────────────────────────────────────────────────────┐
│ Your Mac │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ tmux session │ │
│ │ │ │
│ │ $ claude │ │
│ │ > Implementing authentication... │ │
│ │ > Need permission to run: npm install bcrypt │ │
│ │ > [Waiting for approval] │ │
│ │ > curl → Moshi webhook │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────┐
│ Push Notification │
│ → iPhone / Watch │
└─────────────┬─────────────┘
│
┌─────────────▼──────────────┐
│ Your iPhone │
│ │
│ "Claude needs approval" │
│ │
│ [Tap] → Moshi opens │
│ mosh reconnects instantly │
│ tmux session waiting │
│ Say "yes" → done │
└────────────────────────────┘
The daily flow:
- Start your agent on your Mac in a tmux session
- Detach and walk away—go to work, run errands, sleep
- Get notified when Claude needs input
- Tap notification—Moshi connects in seconds
- Approve by voice—agent continues
- Repeat—your agent works endlessly
Your working machine stays clean. Your agent runs 24/7. You're always reachable.
Complete Setup Checklist
Mac
# 1. Install tools
brew install mosh tmux tailscale
# 2. Configure tmux
cat >> ~/.tmux.conf << 'EOF'
set -g history-limit 50000
set -g mouse on
set -g set-titles on
set -g set-titles-string "#S:#W"
EOF
# 3. Start Tailscale
sudo tailscale up --ssh
tailscale ip # Note this IP
# 4. Enable Remote Login
# System Settings → General → Sharing → Remote Login
# 5. Prevent sleep
# System Settings → Energy Saver → Prevent automatic sleeping
Project Configuration
Add to CLAUDE.md or AGENTS.md:
## Notifications
When you complete a task or need input, notify me:
curl -s -X POST https://api.getmoshi.app/api/webhook \
-H "Content-Type: application/json" \
-d '{"token": "YOUR_TOKEN", "title": "Status", "message": "Brief summary"}'
iPhone
- Install Tailscale → sign in
- Install Moshi
- Add server with Tailscale IP
- Settings → Notifications → copy webhook token
- Add token to project
CLAUDE.md
FAQ
Why not use a VPS?
You can use a VPS. But your Mac gives you macOS-specific tooling (Xcode, Simulator, Apple frameworks), local network access for IoT/home automation work, and no monthly fees. For iOS developers, a Mac is often required anyway.
What if I lose internet on my phone?
Mosh handles this gracefully. Your session doesn't die—it waits. When connectivity returns, mosh reconnects automatically. Your tmux session and Claude agent keep running regardless.
How much does this cost?
- Tailscale: Free for personal use
- Moshi: Free (Premium available)
Does the agent keep running if I close Moshi?
Yes. The agent runs in tmux on your Mac. Moshi is just a window into that session. Close Moshi, and the agent continues. Open Moshi, and you're back where you left off.
What about iPad?
Same setup. Moshi works on iPad with the same features.
tmux or Zellij?
tmux if you want customizable title propagation and a battle-tested tool. Zellij if you prefer a modern UI with on-screen hints. Both work with Moshi.
