cmux-iphone
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Fail
- rm -rf — Recursive force deletion command in .github/workflows/release.yml
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Bridge your Claude Code / Codex / cmux sessions to your iPhone & Apple Watch — approve, prompt, and mirror live terminals on the go.
Cmux iPhone
English · 한국어
Watch and control your Claude Code, Codex, and cmux
sessions from your iPhone (and Apple Watch).
See live terminal output and send prompts; approve permission requests on iPhone and monitor them on Apple Watch — over your LAN or Tailscale.
https://github.com/user-attachments/assets/5f478c28-2086-4696-9d76-e43dda853201
How it works (two halves)
iPhone / Watch ──HTTP+SSE──► cmux-iphone bridge (Node) ──hooks──► Claude Code
(SwiftUI app) ◄──────────── on your Mac ──RPC───► cmux mirror
──log───► Codex
- Bridge (Mac): a small Node server (
cmux-iphone) that receives Claude Code
hook events, mirrors live cmux workspaces, watches Codex, and serves the phone
over HTTP + Server-Sent Events. Discovered on the LAN via Bonjour. - App (iPhone + Watch): a SwiftUI app that pairs with the bridge, shows live
sessions/terminal output, and answers permission prompts.
Everything runs on your own machines — no cloud, no account, no server to host.
The bridge is loopback-only by default (expose it over Tailscale/LAN explicitly); a pairing code + per-device token are the auth boundary.
Run it over Tailscale or a trusted LAN — it is not built to face the open internet
(see SECURITY.md).
cmux is optional. With cmux installed you get the live workspace/terminal
mirror; without it, the bridge still streams hook-based Claude/Codex sessions.
Requirements
| Component | Minimum |
|---|---|
| macOS | 13+ |
| Node.js | 18+ |
| Xcode | 16+ (to build the app) |
| iOS / watchOS | 17 / 10 |
| Claude Code | recent |
| cmux | optional, 0.63.2+ (uses cmux's mobile.* RPC) |
| Tailscale | optional (remote access) |
Install — the Mac bridge
Homebrew (recommended)
brew install lim-won/tap/cmux-iphone
cmux-iphone setup
brew upgrade cmux-iphone updates it; re-run cmux-iphone setup once afterward so
the LaunchAgent / cmux workspace re-point at the new version.
From source
git clone https://github.com/lim-won/cmux-iphone && cd cmux-iphone/skill/bridge
npm ci # reproducible install (use `npm install` if no lockfile)
npm link # optional: puts `cmux-iphone` on your PATH
cmux-iphone setup # or: node bin/cmux-iphone.js setup
cmux-iphone setup is idempotent (safe to re-run). It:
- checks macOS + Node 18+, detects Claude/Codex/cmux/Tailscale,
- writes
config.jsonand generates secrets (0600, never rotated on re-run), - backs up
~/.claude/settings.jsonand merges Cmux iPhone's hooks (scoped —
it never touches another tool's hooks), - picks a runner — in-cmux when cmux is present (so the live mirror works), or
a LaunchAgent when it isn't, - health-checks the bridge and prints your LAN/Tailscale address + pairing code.
Why two runners? A
launchdprocess cannot reach the cmux control socket
(verified). So when cmux is present the bridge runs inside a cmux workspace;
otherwise it runs as a LaunchAgent serving hook/phone/Codex sessions only.
Using the cmux mirror
For the live cmux mirror, cmux must be running and its control socket
reachable when you run setup (configure cmux's socket password if it uses one).
Then:
cmux-iphone setup --cmux # fails fast if cmux RPC isn't reachable (instead of half-installing)
cmux-iphone doctor # confirm: cmux RPC = mobile.workspace.list OK
If cmux is installed but its socket isn't reachable, setup stops and tells you —
it won't silently start a bridge that can't mirror. To skip cmux entirely and run
hook/phone/Codex sessions only: cmux-iphone setup --launchd.
Manage it with the CLI:
| Command | What it does |
|---|---|
cmux-iphone setup |
install / repair (idempotent) |
cmux-iphone doctor |
read-only diagnostics — paste this into a GitHub issue |
cmux-iphone status |
bridge state, LAN/Tailscale address, cmux, paired devices |
cmux-iphone pair |
show the pairing code · --list · --revoke <id> |
cmux-iphone logs |
tail the LaunchAgent log (for an in-cmux bridge, open the Agent Bridge workspace) |
cmux-iphone restart |
restart the bridge |
cmux-iphone uninstall |
remove hooks + service (--purge also deletes data) |
Install — the iPhone / Watch app (build it yourself)
There is no App Store / TestFlight build — Cmux iPhone is distributed as
source and you build it with your own free Apple ID. (TestFlight requires a paid
Apple Developer Program; a public binary may come later if the project enrolls.)
1. Set your bundle id (one command — no XcodeGen needed; the iPhone id, the
Watch id, and the Watch's companion id all derive from it):
./scripts/configure-ios.sh com.yourname.cmuxiphone
open ios/CmuxiPhone/CmuxiPhone.xcodeproj
2. Add your Apple ID to Xcode: Xcode → Settings → Accounts → + → Apple ID
(a free account works).
3. Set the Team on BOTH targets: select the project → for CmuxiPhone and
CmuxiPhoneWatch, Signing & Capabilities → Automatically manage signing →
Team = your Personal Team. (The bundle ids are already set by step 1.)
4. Enable Developer Mode on the iPhone (iOS 16+): Settings → Privacy &
Security → Developer Mode → On → restart. (Do the same on the Watch if
deploying to it: Watch app / watchOS Settings → Privacy & Security.)
5. Run: plug in your iPhone (with the Watch paired), pick the CmuxiPhone
scheme + your iPhone as the destination → Run (⌘R). For the Watch app, pick
the CmuxiPhoneWatch scheme and the paired-Watch destination (deploy via the
iPhone if direct watch install fails).
6. Trust the developer cert: on the iPhone, Settings → General → VPN & Device
Management → tap your developer profile → Trust.
Free-team limits: the app expires ~7 days after building (re-run from
Xcode to refresh), no push notifications (local notifications only), max 3
devices. SideStore/AltStore can auto-refresh the iPhone app wirelessly.Maintainers: the project is generated from
project.ymlwithxcodegen— only
needed if you change the project structure; end users use the script above.
Pair
- Open the app → enter the pairing code (see below) + the Mac's address
(cmux-iphone statusshows the LAN and Tailscale addresses). - Same Wi-Fi → the bridge is also auto-discovered (Bonjour), so you can skip
typing the address. Across networks, use the Tailscale address so the
same pairing works whether you're in the office or away.
Each device gets its own token; revoke any of them withcmux-iphone pair --revoke <id> (see cmux-iphone pair --list).
Where do I get the pairing code?
You don't need to be a developer — it's two commands at most:
- At install,
cmux-iphone setupprints your code (and the addresses) at the
end. It generates one stable code per Mac and saves it — it does not
keep changing, so you can reuse it. - Anytime later, run
cmux-iphone pairto show it again.
$ cmux-iphone pair
Pairing code: 000000
Enter this code in the Cmux iPhone app on your iPhone.
Choose your own code (optional): set
CMUX_IPHONE_PAIR_CODE=123456in the
bridge's environment to pin a memorable code. The code is the pairing gate
(rate-limited — 5 tries per 5 min — and each device still gets its own token), so
keep it private. Trusted LAN or Tailscale use is recommended; do not expose the
bridge directly to the public internet.
Rotating code (optional): prefer a code that rotates over a fixed one? Run
cmux-iphone setup --rotating— a fresh 6-digit code each restart (24h TTL,
cleared once a device pairs) instead of the stable per-Mac default.
Watch approvals (beta): the Watch shows approvals but you answer them on
the iPhone for now.
Remote access over Tailscale
The bridge speaks plain HTTP and is built for your LAN or a private
Tailscale tailnet — never the open internet. Tailscale
lets your iPhone reach your Mac from anywhere, as if they were on the same Wi-Fi.
1. Install Tailscale on both devices, same account.
brew install --cask tailscale # Mac (or download the app), then sign in
On the iPhone, install Tailscale from the App Store and sign in with the same
account. Both devices now share one private tailnet.
2. Find your Mac's Tailscale address.
cmux-iphone status
# Tailscale: http://100.x.y.z:7860
100.x.y.z is your Mac's tailnet IP. With MagicDNS enabled (Tailscale admin
console) you can use the Mac's hostname instead (e.g. your-mac).
3. Pair the phone with that address. Bonjour auto-discovery only works on the
same Wi-Fi and does not cross the tailnet, so for remote access enter the address
by hand: in the app tap Enter IP manually, type the 100.x.y.z (or MagicDNS
hostname) + your pairing code (cmux-iphone pair). The same pairing then works on
Wi-Fi, cellular, or anywhere your tailnet reaches — no re-pairing.
4. Exposing the bridge (it is loopback-only by default). For safety the bridge
binds 127.0.0.1 out of the box, so a fresh install is never reachable over
plaintext HTTP by anyone else on your network — and your phone can't reach it yet.
Pick how to expose it:
cmux-iphone setup --bind 100.x.y.z # Tailscale IP — encrypted, recommended
cmux-iphone setup --lan # entire LAN — plaintext, trusted networks only
Both persist bindAddress to config.json and restart the bridge. (The HOST env
var only affects a bridge you launch by hand — the managed launchd/cmux service does
not inherit it, so use setup --bind or edit config.json for the installed bridge.)
Re-run cmux-iphone status to confirm the bound address, and keep the Mac awake for
remote use:sudo pmset -a sleep 0 && sudo pmset -a disablesleep 1.
Multiple Macs on the road? See
REMOTE-SETUP.mdfor naming
each Mac (office-mac-1, …) and switching between them in the app.
Troubleshooting
Run cmux-iphone doctor first — it prints a PASS/WARN/FAIL report (no
secrets) that's ideal to paste into an issue.
- iPhone "Connection failed": run
cmux-iphone statusto get the bridge's
actual address + port (it may bind another port in 7860–7869, or a non-loopback
interface), then probe/healththere — e.g.curl http://<addr>:<port>/health
(note:/statusrequires auth). Bridge + phone must share the LAN (or Tailscale). - No cmux workspaces: cmux only mirrors when the bridge runs inside cmux
(cmux-iphone statusshows the runner). Without cmux you still get hook sessions. - Watch/phone can't find the bridge (Bonjour): check, in order — the app's iOS
Local Network permission; both devices on the same network; the router's
AP / client isolation is off; mDNS isn't blocked; then fall back to entering
the IP manually (fromcmux-iphone status). - Permission prompts don't appear: confirm hooks in
~/.claude/settings.json
and that a device is paired (cmux-iphone pair --list).
How it works
Event flow (Mac → phone)
Claude Code runs a tool → a PostToolUse/PreToolUse hook POSTs to the bridge →
the bridge pushes an SSE event → the app renders it.
Permission flow (Mac → phone → Mac)
Claude hits a permission prompt → the PermissionRequest hook blocks → the
bridge pushes a permission-request SSE event → the phone shows the options →
your choice is POSTed back → the bridge returns the decision to Claude.
(For codex exec-approvals, the bridge types the answer into the pinned cmux
terminal, guarded by a screen hash — it refuses if the screen changed.)
Hooks installed (loopback listener, secret-gated): PostToolUse, PreToolUse,PermissionRequest (blocking, up to 10 min), SessionStart, SessionEnd,Stop, error events.
Security
By default the bridge listens on 127.0.0.1:<port> (loopback-only); exposing it to
your phone is an explicit opt-in via bindAddress / the HOST env / setup --lan
(prefer a Tailscale IP — encrypted). Requests carrying a foreign Host header are
rejected (DNS-rebinding defense). Auth is the pairing code + per-device token; the
hook listener is loopback-only and secret-gated.
Secrets live outside the repo at 0600. Trusted LAN or Tailscale use is recommended —
do not expose the bridge directly to the public internet. Full model + reporting inSECURITY.md.
License
MIT — see LICENSE.
Cmux iPhone is a fork of shobhit99/claude-watch
(MIT); original-author copyright is preserved. The app ships neutral icons — no
Claude/Anthropic or OpenAI/Codex logo assets are bundled; "Claude" and "Codex" are
trademarks of Anthropic and OpenAI respectively, used only as text labels. This is an
independent community tool, not affiliated with or endorsed by Anthropic or OpenAI.
See NOTICE.md for full attribution.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found