Stream Claude Code, Codex, Gemini CLI, and any terminal session to your phone in real time. Approve tool calls from the couch. Browse and edit files on your dev machine from anywhere.
You kick off Claude Code on a large refactor. You go make coffee. You come back 20 minutes later and discover it's been blocked on a tool approval since minute two.
This happens constantly with AI coding assistants. They're powerful but need a human in the loop. That human doesn't need to be chained to a desk.
MobileCLI streams your terminal to your phone over a network path you control. When your AI assistant asks a question, requests tool access, or finishes a task, you get a push notification. Tap it, read the context, approve or deny, and go back to what you were doing.
The terminal stream is served by a local daemon over WebSocket. Mobile clients pair with auth-v2 QR credentials and then prove possession with a challenge-response handshake before the daemon sends sessions, terminal output, filesystem data, or push-token registration. There is no MobileCLI terminal relay or account system, but push notifications are delivered through Expo's push service, and the daemon should still only be reachable from a trusted LAN, Tailscale network, or protected custom endpoint.
curl -fsSL https://mobilecli.app/install.sh | bashThis macOS/Linux installer downloads the matching GitHub Release archive, verifies it against that release's SHA256SUMS.txt manifest before extraction, and puts the binary on your PATH. Windows users should install from the GitHub Releases .zip or with Cargo. The checksum protects against a corrupted or tampered archive relative to the published release manifest; for stronger supply-chain assurance, inspect the source or build from source with Cargo.
Other install methods
# From crates.io cargo install mobilecli # From source git clone https://github.com/MobileCLI/mobilecli.git cd mobilecli/cli && cargo install --path . # Pre-built binaries (Linux x86_64/aarch64, macOS x86_64/arm64) # → https://github.com/MobileCLI/mobilecli/releases
mobilecli setup
This starts the daemon, saves your connection mode, creates a fresh mobile credential, and displays a QR code. Open the MobileCLI iOS app, tap Scan QR Code, and you're connected. The QR encodes the ws:// or wss:// URL, device id/name metadata, credential id, server id, and one-time pairing token. The desktop stores only a derived verifier, not the raw token.
mobilecli claude # Claude Code mobilecli codex # OpenAI Codex mobilecli -n "DB Migration" claude # Named session mobilecli bash # Plain shell mobilecli # Your default $SHELL
Your phone now shows the terminal output in real time. Walk away.
MobileCLI has two components: a Rust daemon that runs on your dev machine, and a React Native app on your phone.
Your Machine Your Phone
┌─────────────────────────────────┐ ┌───────────────────────────┐
│ mobilecli daemon (Rust) │ WebSocket │ MobileCLI App │
│ ┌────────────────────────────┐ │◄────────────►│ │
│ │ PTY Manager │ │ LAN or │ ┌─ Sessions tab │
│ │ session 1: claude code │ │ Tailscale │ │ Live xterm.js │
│ │ session 2: codex │ │ │ │ Touch keyboard │
│ │ session 3: bash │ │ │ │ Push notifications │
│ └────────────────────────────┘ │ │ │ │
│ ┌────────────────────────────┐ │ │ ├─ Files tab (Pro) │
│ │ File System Bridge │ │ │ │ Browse, edit, search │
│ │ read / write / search │ │ │ │ Create, delete, copy │
│ │ git status integration │ │ │ │ │
│ └────────────────────────────┘ │ │ └─ Config tab │
│ ┌────────────────────────────┐ │ │ Theme, notifications │
│ │ CLI Detection Engine │ │ │ Connection settings │
│ │ claude, codex, gemini, │ │ │ │
│ │ opencode — auto-detected │ │ └───────────────────────────┘
│ └────────────────────────────┘ │
└─────────────────────────────────┘
│
Port 9847 (default)
Trusted network required
Protect from untrusted clients
The daemon allocates a PTY (pseudo-terminal) for each session, streams the byte output over WebSocket, and relays keyboard input from your phone back to the PTY. The mobile app renders the stream using a bundled xterm.js instance — full ANSI color, cursor positioning, and alternate screen buffer support.
Run multiple AI assistants simultaneously. The Sessions tab shows all active and historical sessions with live status indicators. Long-press to rename or close sessions. Tap the + button to spawn a new CLI directly from your phone — Claude Code, OpenAI Codex, or a plain shell.
Sessions persist across daemon restarts. If you close the app and come back, your sessions are still there with full scrollback history.
The daemon automatically identifies which AI assistant is running in each session and parses its output to detect wait states — tool approval prompts, plan reviews, questions.
| CLI | Wait-state Detection | What Gets Detected |
|---|---|---|
| Claude Code | ANSI output parsing | Tool calls, plan reviews, questions, completion |
| OpenAI Codex | Output pattern matching | Approval prompts, completion signals |
| Gemini CLI | Prompt detection | Yes/No prompts, input requests |
| Shell | Generic | Full terminal with manual interaction |
When a wait state is detected, the daemon fires a push notification to your phone. You don't need to keep the app open or watch the session — you'll be alerted the moment your attention is needed.
The terminal view is a full xterm.js 5.3 instance running inside a WebView:
- 256-color ANSI rendering with correct cursor positioning
- Scrollable history — scroll up through output, auto-scroll follows new content at the bottom
- Touch keyboard with a toolbar providing Esc, arrow keys (for CLI history), paste, and file attachment buttons
- Responsive resize — terminal dimensions adapt to your phone/tablet screen and send the new size to the PTY so output reflows correctly
- Desktop-safe by default — mobile resizing changes the child PTY dimensions without forcing your desktop terminal window to physically resize (
MOBILECLI_DESKTOP_RESIZE_POLICY=mirrorrestores legacy mirroring) - Low latency — WebSocket streaming over LAN is typically sub-10ms
The Files tab gives you direct access to your dev machine's filesystem:
- Browse directories with breadcrumb navigation, file sizes, and modification times
- Search files by name across your entire project tree
- Edit files with a built-in editor featuring Save/Undo/Redo, Markdown formatting shortcuts (Bold, Italic, Code, H1, List, Link), and syntax awareness
- Create new files and folders from your phone
- Destructive actions stay opt-in — delete and rename are disabled by default in the daemon config and must be explicitly enabled during setup or config review
- Upload photos, files, or camera captures from your phone to your dev machine — the daemon saves them and returns the desktop path so you can paste it into your terminal
- Git integration — file listings show git status indicators
Notifications are delivered through Expo's push notification service for the current iOS app. The daemon sends a push when:
- An AI CLI enters a wait state (tool approval, plan review, question)
- A session finishes or exits
- A long-running command completes
The push token is registered over the WebSocket connection and then used by the daemon to call Expo's push API. Notification payloads include the notification title/body and session id, not the full terminal stream.
MobileCLI keeps the terminal streaming path self-hosted, but the current iOS push-notification path uses Expo's cloud push service.
- No MobileCLI terminal relay. Your terminal output is served by the daemon over your configured network path.
- No accounts. No sign-up, no email, no OAuth.
- No telemetry. The daemon collects nothing.
- Auth-v2 pairing. Each mobile app stores a pairing token in SecureStore and authenticates with a challenge-response proof before receiving sessions or terminal data. Use
mobilecli pair --rotateormobilecli credentials revoke <credential_id>to replace or revoke mobile access. - Network isolation still matters. Keep port
9847on a trusted LAN, Tailnet, firewall allowlist, or protected custom endpoint. Do not expose it directly to the public internet. - Bounded resources. The daemon limits concurrent connections, channel buffer sizes, and session counts to prevent resource exhaustion.
Your terminal stream does not go through MobileCLI-operated servers. If push notifications are enabled, Expo receives the notification title/body and session id. If you configure Tailscale or a custom remote URL, traffic follows that network provider or endpoint.
| Mode | How it works | Setup |
|---|---|---|
| LAN | WebSocket over your trusted WiFi/ethernet. Fastest and simplest. | Auto-detected during mobilecli setup |
| Tailscale | WireGuard-based mesh VPN. Access from your Tailnet without opening the daemon to the public internet. | mobilecli setup → select your Tailscale IP |
| Custom URL | Your own protected ws:// or wss:// endpoint, such as a private reverse proxy or TLS terminator. |
Provide the URL during setup |
For most users, LAN mode is all you need. Open a terminal, scan the QR, done.
mobilecli [OPTIONS] [COMMAND]
Session commands:
mobilecli Start default shell with streaming
mobilecli <command> Run any command with streaming
mobilecli -n "Name" <command> Name the session for easy identification
mobilecli link [session-id] Attach to an existing session (tmux-like)
Setup and management:
mobilecli setup Interactive setup wizard (generates QR code)
mobilecli pair Show QR code for pairing additional devices
mobilecli pair --rotate Revoke existing mobile credentials and pair again
mobilecli credentials list List paired mobile credentials without secrets
mobilecli credentials revoke <id> Revoke one paired mobile credential
mobilecli status Show daemon status, active sessions, connections
mobilecli stop Stop the daemon
Daemon lifecycle:
mobilecli daemon [--port PORT] Start daemon manually (default port: 9847)
mobilecli autostart install Auto-start daemon on login
mobilecli autostart uninstall Remove auto-start
mobilecli autostart status Check auto-start status
Shell integration:
mobilecli shell-hook install Auto-launch mobilecli in every new terminal
mobilecli shell-hook uninstall Remove the shell hook
mobilecli shell-hook status Check shell hook status
The daemon can register itself to start automatically when you log in:
| Platform | Mechanism | Command |
|---|---|---|
| Linux | systemd user service | mobilecli autostart install |
| macOS | launchd agent | mobilecli autostart install |
| Windows | Task Scheduler | mobilecli autostart install |
Windows Note: See docs/WINDOWS_SETUP.md for important details about running in user session for visible terminal windows.
To automatically wrap every new terminal session:
mobilecli shell-hook install
This adds a one-liner to your .bashrc, .zshrc, config.fish, or PowerShell $PROFILE. Every new shell you open will be streamed to your phone automatically. Bypass it temporarily:
MOBILECLI_NO_AUTO_LAUNCH=1 bash
| Platform | Architecture | Status |
|---|---|---|
| Linux | x86_64, aarch64 | Fully supported |
| macOS | Intel, Apple Silicon | Fully supported |
| Windows | x86_64 | Fully supported |
| Platform | Status |
|---|---|
| iOS (iPhone + iPad) | Available on the App Store — Download MobileCLI |
| Android | In development |
The CLI daemon is open source and free forever (MIT license).
The mobile app has a free tier and an optional Pro upgrade:
| Free | Pro | |
|---|---|---|
| Live terminal streaming | Unlimited sessions | Unlimited sessions |
| Push notifications | Included | Included |
| Multi-session management | Included | Included |
| Spawn sessions from phone | Included | Included |
| Rename / close sessions | Included | Included |
| Multiple themes | Included | Included |
| File browser & editor | — | Included |
| Full-text file search | — | Included |
| Photo / file upload to desktop | — | Included |
| Free | 19ドル.99/yr or 29ドル.99 lifetime |
All config lives in ~/.mobilecli/:
| File | Purpose |
|---|---|
config.json |
Device identity and connection mode/URL |
sessions.json |
Persisted session metadata (names, history) |
daemon.pid |
Running daemon's process ID |
daemon.port |
Active WebSocket port (default: 9847) |
daemon.log |
Debug log output |
cd cli cargo build # Debug build cargo run -- setup # Run setup wizard RUST_LOG=debug cargo run # Verbose logging cargo test # Run tests cargo clippy # Lint
The daemon is ~7,000 lines of async Rust built on tokio. Key modules:
| Module | Lines | Role |
|---|---|---|
daemon.rs |
2,700 | WebSocket server, session lifecycle, file system bridge |
protocol.rs |
550 | All client/server message types (serde JSON) |
shell_hook.rs |
530 | Cross-platform shell integration (bash/zsh/fish/PowerShell) |
autostart.rs |
560 | systemd / launchd / Task Scheduler registration |
pty_wrapper.rs |
490 | PTY allocation, I/O streaming, signal handling |
detection.rs |
390 | AI CLI fingerprinting and wait-state parsing |
setup.rs |
570 | Interactive wizard, QR generation, network detection |
main.rs |
450 | CLI argument parsing and command dispatch |
The mobile app is in a separate repository:
cd mobile npm install npx expo start # Dev server (press 'i' for iOS simulator) npx eas-cli build --platform ios --profile production # Production build
Key technologies: Expo Router (navigation), xterm.js 5.3 (terminal rendering in WebView), expo-secure-store (credential storage), RevenueCat (subscriptions).
MobileCLI/
├── cli/ # Rust daemon + CLI wrapper
│ └── src/
│ ├── main.rs # Entry point, clap argument parsing
│ ├── daemon.rs # WebSocket server, PTY management, filesystem ops
│ ├── protocol.rs # Client ↔ Server message types
│ ├── pty_wrapper.rs # PTY spawning and byte-level I/O
│ ├── detection.rs # AI CLI detection + wait-state parsing
│ ├── setup.rs # Interactive setup wizard + QR code
│ ├── shell_hook.rs # Shell auto-launch integration
│ ├── autostart.rs # OS-level daemon autostart
│ ├── link.rs # Session attachment (tmux-style)
│ ├── session.rs # Session metadata structures
│ ├── platform.rs # Cross-platform utilities
│ └── qr.rs # QR code rendering
├── mobile/ # React Native app (separate git repo)
├── website/ # Marketing site (Astro + Tailwind)
├── install.sh # One-line installer script
├── .github/workflows/ # CI, release packaging, Claude Code review
└── docs/ # Architecture docs + screenshots
Can't connect from mobile app
- Same network? Your phone and machine must be on the same WiFi/LAN, or both on Tailscale.
- Daemon running? Run
mobilecli statusto check. If not running,mobilecli daemonstarts it. - Firewall? Ensure port
9847(or whatever~/.mobilecli/daemon.portsays) allows inbound TCP. - Re-pair: Run
mobilecli pairto show a fresh QR code and scan it again. - Check logs:
~/.mobilecli/daemon.logwill show connection attempts and connection errors.
No push notifications
- Verify notifications are enabled for MobileCLI in iOS Settings.
- The push token registers automatically after the WebSocket auth-v2 handshake completes — check the Config tab shows "connected" status.
- Notifications require the daemon to be running. If you restart your machine, make sure the daemon is back up (
mobilecli autostart installhandles this automatically).
Terminal display issues
- MobileCLI uses xterm.js with full ANSI 256-color support. Ensure your CLI sets
TERM=xterm-256color(this is the default). - The terminal auto-resizes to fit your phone screen. TUI applications (like
htoporvim) should adapt automatically. - Desktop terminal geometry is preserved by default. If you explicitly want mirrored desktop window resizing, launch with
MOBILECLI_DESKTOP_RESIZE_POLICY=mirror. - On Linux, tmux mouse mode is disabled by default so desktop terminals like Konsole keep normal drag-select clipboard behavior. Re-enable tmux mouse features with
MOBILECLI_TMUX_MOUSE=on mobilecli. - If a session looks garbled after switching tabs, tap the session to re-enter it — the terminal refits on activation.
Session not appearing on phone
- Sessions only appear when the daemon is running and your phone is connected.
- Check
mobilecli statusto see active sessions and connected clients. - If you started a command without
mobilecliwrapping it, it won't appear. Usemobilecli <command>or install the shell hook.
Contributions are welcome. The CLI daemon is open source under the MIT license.
# Fork, clone, and create a feature branch git clone https://github.com/YOUR_USERNAME/mobilecli.git cd mobilecli/cli # Build and test cargo build cargo test cargo clippy -- -D warnings # Open a PR against main
Claude Code review is enabled on this repository — your PR will receive automated feedback.
MIT — see LICENSE for details.
Stop babysitting your AI assistant. Start it, walk away, and get a push when it needs you.