Open-source project
alexeygrigorev/pocketshell avatar
alexeygrigorev/pocketshell

PocketShell: an SSH client for driving tmux and coding agents from an Android phone

Voice-first, tmux-native, agent-aware Android SSH client

39 stars6 forksKotlinNOASSERTION

At a glance

What is it?
PocketShell is a voice-first, tmux-native Android SSH client that attaches to tmux in control mode and reads AI coding agents in the visible pane. It is a single-user tool with a matching Python helper on the dev box, and the version pairing between the two is strict.
Who is it for?
Adopt PocketShell if you already run long-lived tmux sessions on a dev box, you are comfortable installing a Python helper on that box, and you want to dictate prompts and move between panes from a phone. Do not adopt it if you need iOS, if you want a general-purpose SSH app with per-session terminal multiplexing on the phone itself, or if you cannot keep the app and the helper at the same version.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

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

Editorial analysis

The problem PocketShell targets: a dev box you can only reach from a phone

The premise is narrow. You have a workstation where the real work happens, tmux sessions that stay alive across disconnects, and a phone as the only screen available. Most SSH clients for Android treat the phone as a small terminal. They give you a keyboard, a scrollback buffer, and whatever layout the remote side renders. PocketShell takes the opposite position: the phone should not try to display a tiled tmux layout at all. The README states it attaches with tmux -CC control mode and renders one pane at a time in a real terminal emulator. That is a deliberate reduction in information density in exchange for legibility on a small screen.

The second target is agent work. Claude Code, Codex, OpenCode, and Grok Build all run inside a pane and emit turns, tool calls, and output as text. PocketShell detects those agents in the visible pane and opens a Conversation view of that agent's turns instead of raw terminal output. The reply composer stays on screen and sends back into the pane. So the intended user is someone who already delegates work to a coding agent on a remote box and wants to check on it, answer it, or redirect it without sitting at a desk.

The third piece is voice. A composer with OpenAI Whisper and the Android speech recognizer turns dictation into commands or agent prompts, with a key bar for Esc, Tab, Ctrl, Alt, and arrows above the keyboard. Dictating a prompt to an agent is a different ergonomic bet than typing one. It assumes prompts are long enough that thumb typing is the bottleneck.

How the tmux control mode attachment and the server-side helper divide the work

The architecture splits state between the phone and the box, and the split is the interesting design decision. Long-lived state lives on the box in tmux and a small server-side helper named pocketshell. The app reconnects when it is brought back to the foreground. Nothing important is supposed to survive on the phone.

The helper is a Python program installed on each dev box. According to the README, it handles provider usage and quota, the session tree, repo browsing, env files, jobs, and QR sharing. The app talks to it over the same SSH connection. The stated consequence is that provider credentials never move onto the phone. That is a real security property, and it is the main reason the helper exists rather than the app calling provider APIs directly. The usage panel's default command is pocketshell usage --json, and the host form lets you override it with a custom command.

Session discovery is a two-layer thing. tmux control mode gives the app the pane stream and the ability to move between panes and sessions. The helper supplies the folder and session tree that the app shows after you tap a host, covering watched projects and live sessions. Swipe or tap moves between panes and sessions. Agent detection then runs against the visible pane's text to decide whether to offer the Conversation view.

Host management is local to the app: saved SSH hosts, imported or generated keys, biometric unlocking of key passphrases, and QR import. Passphrases are inspected locally and prompted for when needed, and the README says they are not stored.

Installing the APK and the pocketshell helper, then adding a first host

There are two installs, and they must match. Start with the app. The README points at the GitHub Releases page and a debug APK named pocketshell-<version>-debug.apk. Android 8.0 (API 26) or newer is required. If you prefer adb, the README gives this command:

bash
adb install -r pocketshell-<version>-debug.apk

On the dev box, install the helper at the same version as the app. The README shows uv and pipx, and it shows pinning to the release tag:

bash
uv tool install pocketshell
uv tool install 'pocketshell==0.4.44'
pipx install pocketshell

One detail matters more than it looks. The app does not open a login shell, so ~/.local/bin has to be on PATH for non-interactive SSH. If the helper is installed but the app cannot find it, the failure will look like a broken usage panel rather than a PATH problem.

If you want to generate host QR codes from the box, the README adds the QR extra:

bash
uv tool install pocketshell --with "qrcode[pil]"

For the first host, QR import is the shortest path. On the box, generate a code from an SSH config alias, which resolves host, port, user, and identity file through ssh -G:

bash
pocketshell qr-share dev

Or pass the details explicitly and skip ~/.ssh/config:

bash
pocketshell qr-share \
  --host dev.example.com \
  --user ubuntu \
  --port 22 \
  --key ~/.ssh/id_ed25519 \
  --name "dev box"

qr-share prints the QR inline on a TTY, or writes a numbered PNG sequence with --png --out-dir <dir>. Large keys are split across several codes and the helper pauses between them. On the phone, go to Settings, Import host, Scan QR, and point the camera at the code or codes. The scanner reassembles multi-part codes and imports once every part has arrived. If you would rather type it, the manual form asks for name, hostname or IP, port (defaults to 22), username, an SSH key from your saved keys, and an optional usage command. The README warns that the QR payload can include your private key, which is a visible secret on screen, so generate and scan in private and delete the PNGs afterwards.

The version pairing rule and other places PocketShell will bite you

The sharpest constraint is stated plainly: keep the Android app and the host pocketshell helper on the same version, because a newer app talking to an older helper can hang on connect. A hang is a worse failure than an error, since it gives you nothing to read. This is not a project that tolerates drift between the two halves.

The second constraint is the release policy. The README says releases take hard cuts on breaking changes rather than carrying compatibility shims, with a locked decision referenced as D22, on the grounds that there is no install base to keep happy. Read that as a warning about upgrade discipline rather than a defect. If you pin a working pair, you should expect to re-pin both sides together.

Third, the scope is deliberately small. It is Android-only and single-user. There is no iOS client and no multi-user story in the README. If your team needs shared access to a box, or you carry an iPhone, this is the wrong tool regardless of how well the tmux integration works.

Fourth, the QR path carries a genuine secret. The README's own note about private keys being visible on screen and the advice to prefer passphrase-protected keys is the project acknowledging that convenience and exposure sit on the same feature. Multi-part codes also mean the import is not atomic from the user's side: you scan several images before anything happens.

Finally, the README references docs/README.md, docs/server-setup.md, docs/ssh-qr-import.md, and tools/pocketshell/README.md for architecture, agent awareness, the usage panel, the design system, and testing. Those documents are where the depth lives. The README itself is a tour, not a specification, so anything you need to know about the QR payload format or the pocketshell://import deep link has to come from docs/ssh-qr-import.md.

How PocketShell differs from a general-purpose Android SSH client

The obvious alternative is a conventional Android SSH client such as Termux paired with an SSH client, or a dedicated terminal app that gives you a full shell and lets you run tmux yourself. The difference in approach is where the multiplexing decision is made. A general SSH client hands you a raw terminal and leaves tmux rendering to the remote side, so you see whatever the pane layout produces, scaled down. PocketShell instead speaks tmux control mode and takes responsibility for rendering exactly one pane, which means it can build a session tree, offer a Conversation view, and place a key bar and composer around a known single-pane context. You trade the ability to see a tiled layout for a UI that knows what it is looking at.

That trade has a cost. Control mode is a specific tmux interface, and the app's whole session model depends on it. A general client does not care which multiplexer you run, or whether you run one at all. If you use screen, zellij, or no multiplexer, the PocketShell model has nothing to attach to.

The agent-awareness layer is the second difference and has no equivalent in a plain SSH client. Parsing the visible pane for Claude Code, Codex, OpenCode, or Grok Build and re-presenting turns and tool calls is a feature that only makes sense if the client is opinionated about what runs in the pane. A general client shows you the same bytes and lets you read them.

The third difference is the helper. Installing a Python package on every box you connect to is a real cost that a plain SSH client never imposes. In exchange, provider credentials stay on the box and the usage panel, session tree, repo browsing, and env file access come from a program that knows the host's layout. Whether that is worth a per-box install depends on how many boxes you actually use.

Editorial conclusion

Adopt PocketShell if you already run long-lived tmux sessions on a dev box, you are comfortable installing a Python helper on that box, and you want to dictate prompts and move between panes from a phone. Do not adopt it if you need iOS, if you want a general-purpose SSH app with per-session terminal multiplexing on the phone itself, or if you cannot keep the app and the helper at the same version. Before installing, verify three things: that your tmux build handles control mode the way the project expects, that ~/.local/bin is on PATH for non-interactive SSH, and that the release tag you plan to use has both a debug APK and a matching PyPI helper, since the README states a newer app talking to an older helper can hang on connect.

Frequently asked questions

What is PocketShell and what does it do?

It is a voice-first, tmux-native, agent-aware SSH client for Android. It connects to your dev box over SSH, attaches to tmux sessions in control mode, and renders one pane at a time, with a Conversation view for Claude Code, Codex, OpenCode, and Grok Build sessions detected in the visible pane.

How do I install PocketShell?

Download the latest debug APK from the GitHub Releases page and install it on Android 8.0 (API 26) or newer, or use adb install -r on the APK. On the dev box, install the matching Python helper with uv tool install pocketshell or pipx install pocketshell, keeping the helper version the same as the app version.

What does it mean that PocketShell is tmux-native?

The README states the app attaches with tmux -CC control mode and renders one pane at a time in a real terminal emulator rather than trying to display a tiled tmux layout on a small screen. You swipe or tap to move between panes and sessions, and a folder and session tree shows watched projects and live sessions.

Do my provider credentials get stored on the phone?

No. Provider usage and quota, the session tree, repo browsing, env files, jobs, and QR sharing all run through the pocketshell helper on the box, and the README states provider credentials never move onto the phone. The QR import path is the exception to watch: the payload can include your private key, which is visible on screen.

Does the Android app version have to match the helper version?

Yes. The README says to keep the Android app and the host pocketshell helper on the same version, because a newer app talking to an older helper can hang on connect. Releases take hard cuts on breaking changes rather than carrying compatibility shims.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alexeygrigorev-pocketshell.svg)](https://hysenlabs.com/projects/alexeygrigorev-pocketshell)