Model or dataset
my-claude-utils/clsh avatar
my-claude-utils/clsh

clsh: a real PTY on your Mac, streamed to a phone browser

Access your terminal and your AI agent from any device — phone, tablet, desktop.

527 stars54 forksTypeScriptMIT

At a glance

What is it?
clsh is a TypeScript tool that runs an agent on your machine, spawns node-pty sessions, and exposes them over a tunnel to a PWA. It is aimed at developers who want to drive Claude Code or a shell from a phone, and its security model is the part worth reading before you install it.
Who is it for?
Adopt clsh if you already run Claude Code or tmux on a machine you control and you want a phone client that renders a genuine PTY rather than a chat wrapper. Do not adopt it if you cannot accept that a single-use bootstrap token is the only thing standing between a leaked URL and a shell on your laptop, or if you need Windows support, since the README states macOS or Linux.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 88 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap clsh fills between SSH clients and chat apps

A phone SSH client gives you a terminal, but the interaction model assumes a physical keyboard. Terminal emulators built for mobile tend to be thin wrappers around a shell that was never designed for a 6-inch screen. Meanwhile the AI coding tools that have appeared over the past year mostly present a chat surface, so you watch output rather than drive a process. clsh sits in the space between: it keeps the real PTY and adds a mobile input layer on top. The README is explicit that this is not a simulation, describing it as a real PTY on your machine, streamed to your pocket. The target user is someone who already runs Claude Code or a long-lived shell on a Mac or Linux box and wants to check on it, or start it, from a phone without carrying a laptop. The topics list on the repository includes claude-code, tmux, xterm and node-pty, which matches that positioning. It is not a hosted service, and it is not a way to reach a machine you do not already control.

The agent, the PTY pool and the three-tier tunnel

The architecture diagram in the README is short enough to read in full. A phone, tablet or browser connects over HTTPS with a WebSocket to a tunnel, which forwards to a clsh agent running on your machine. That agent owns a pool of PTYs: the diagram shows PTY 0 as zsh, PTY 1 as claude, PTY 2 as an ellipsis, and a note that the ceiling is 8 sessions. Sessions are spawned through node-pty, so what the browser sees is a genuine terminal process, not a command runner. The frontend is React and renders with xterm.js. When tmux is installed on the host, the agent wraps sessions in it, which is what makes them survive an agent restart; the README describes this as auto-detected with a graceful fallback when tmux is absent. The tunnel layer has three tiers in a fixed order: ngrok first, then localhost.run over SSH, then local Wi-Fi. The default path requires no account, which is why the zero-config quickstart works at all. The trade-off is visible in the ordering: the tier that gives you a stable URL is the one that asks for a token, and the tier that asks for nothing gives you a URL that changes.

Getting it running from npx to a scanned QR code

The README states Node.js 20 or newer and macOS or Linux. The quickstart is a single command, `npx clsh-dev`, after which a QR code prints to the console and you scan it with your phone. That command starts both the backend agent and the React frontend, then brings up a tunnel. For a URL that persists across restarts, which is what you want if you plan to install the PWA to a home screen, the documented path is `npx clsh-dev setup`, with a referenced guide at docs/ngrok-setup.md. The ngrok route is documented as `brew install ngrok` followed by `ngrok config add-authtoken YOUR_TOKEN`, with a free static domain created at dashboard.ngrok.com/domains. The README marks ngrok as recommended for the permanent-URL case and describes localhost.run as the free SSH tunnel that needs no signup and no tokens. Two configuration facts matter more than they look. First, the bootstrap token is passed in the URL hash fragment, which the README says is never sent to servers, and the WebSocket authenticates via a first message rather than a query string. Second, session count is capped at 8 concurrent PTYs, so the agent is not intended to host a large fleet of shells.

What the security section actually commits to

The README opens its security section by acknowledging the stakes: remote terminal access means a vulnerability could mean full machine compromise. The listed controls are specific enough to evaluate. Authentication uses one-time bootstrap tokens with a 5-minute TTL, scrypt password hashing at N=16384 with a 64-byte key and a random salt, and WebAuthn for biometric auth. Tokens are JWTs issued via HS256. Password comparison uses crypto.timingSafeEqual for constant-time checks. Rate limiting on auth endpoints is stated as 5 to 10 requests per 15 minutes. WebSocket upgrades validate origin, cap payloads at 64KB, and bounds-check resize dimensions. Transport relies on HTTPS from the tunnel plus security headers including X-Frame-Options, X-Content-Type-Options and CSP, with CORS restricted to known origins. The PWA adds a lock screen with Face ID plus password, and biometric credentials are synced server-side for cross-context restoration. The disclosure process is a security advisory or security@clsh.dev with a stated 48-hour response. One thing the README does not do is publish a threat model for the tunnel tiers. If you fall back to local Wi-Fi, the transport guarantees are those of your network, not ngrok's.

The mobile input layer is where most of the work went

Reading the feature list, the keyboard is the most developed part of the project, which makes sense given the problem it is solving. There are two layouts: an iOS Terminal layout with 6 rows and larger keys, and a MacBook layout with 5 rows and a compact arrangement. Sticky modifiers let you tap Shift, Ctrl, Opt or Cmd once and have it apply to the next key, which is the correct behaviour for a touchscreen and the opposite of what a physical keyboard does. Key repeat is documented at a 400ms delay and a 60ms interval when you hold a key. A context strip exposes esc, F1 through F5, commit, diff, plan and Ctrl+C as quick access, which is a set of shortcuts tuned to a coding agent workflow rather than general shell use. There are 6 skins: iOS Terminal, MacBook Silver, Gamer RGB, Custom Painted, Amber Retro and Ice White. On the mobile side the PWA installs to the home screen and runs fullscreen, the system iOS keyboard is suppressed in favour of the custom one, and safe-area insets handle Dynamic Island and notch devices. A demo mode plays scripted terminal animations when no backend is reachable, which is presumably what powers the live demo at clsh.dev. None of this is a substitute for a physical keyboard during long editing sessions, and the README does not claim otherwise.

Where clsh is the wrong tool, and what to use instead

The obvious failure mode is the one the security section names: this is remote shell access, and the auth story rests on a single-use token with a 5-minute TTL plus a JWT afterwards. If that JWT leaks, the holder has a shell. The rate limits and origin checks reduce the attack surface but do not change the shape of the risk. A second limitation is platform: the README states macOS or Linux, so Windows users are out unless they run a VM or WSL and treat that as the host. A third is the tunnel ordering. Defaulting to localhost.run means the URL changes between runs, which breaks the PWA home-screen use case until you configure ngrok, and the ngrok path requires a free account and an authtoken. For a straight comparison, consider mosh plus a mobile SSH client such as Termius or Blink. Mosh handles roaming and intermittent connectivity at the protocol level and runs over plain SSH with your existing keys, no tunnel broker and no browser. clsh takes a different approach: it terminates the connection in a browser tab, which buys you the custom keyboard, the session grid with live previews and the agent-oriented context strip, at the cost of introducing a token-issuing server and a third-party tunnel into the path. If your only goal is to reach a shell from a phone on a network you trust, mosh is fewer moving parts. If your goal is to watch Claude Code work and tap commit without a laptop, the browser surface is the point.

Release cadence, licence and what to verify before adopting

The releases tell a short story. v0.1.0 landed on 2026-03-15 with the tagline about your Mac in your pocket, v0.1.8 on 2026-03-16 covered security, PWA auth and session persistence, and v0.1.9 on 2026-03-17 added native keyboard support. Three releases in three days, then a gap to the most recent push in June 2026. That is a very young project by any measure, and the version number still sits below 0.2, so API and config surface should be treated as unstable. The licence is MIT, which is permissive and imposes no copyleft obligation on your own code; if you fork and redistribute, you carry the MIT notice, and if you run it as a service, the licence does not require you to publish changes. That is a description of the licence text, not legal advice. Maintenance cost is low in the sense that there is no server to keep patched on your side beyond the agent itself, but the dependency chain includes node-pty, xterm.js and a tunnel client, and node-pty is a native module, so Node major upgrades are the likely breakage point. Before adopting, read SECURITY.md rather than the README summary, decide which tunnel tier you will actually run and whether its URL stability meets your needs, and confirm tmux is installed on the host if you expect sessions to outlive a restart. The repository is not archived, and the disclosure address is a working one as of the last push.

Editorial conclusion

Adopt clsh if you already run Claude Code or tmux on a machine you control and you want a phone client that renders a genuine PTY rather than a chat wrapper. Do not adopt it if you cannot accept that a single-use bootstrap token is the only thing standing between a leaked URL and a shell on your laptop, or if you need Windows support, since the README states macOS or Linux. Before installing, read SECURITY.md, confirm which tunnel tier you will land on, and check whether tmux is present so you know if sessions will survive a restart.

Official sources

  1. License: MIT
  2. my-claude-utils/clsh on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes