clustermux
A small, dependency-free TUI for managing tmux sessions spread across SSH hosts — HPC login nodes, cloud dev boxes, GPU clusters — from a single terminal window.
clustermux discovers every remote tmux session in parallel, shows you what's running where, and lets you attach, create, rename, kill, or hand off sessions without juggling terminal tabs or remembering which machine hosts which session.
Features
- One dashboard for every host — parallel SSH discovery of all remote tmux sessions, with reachability, latency, running command, and working directory
- Persistent connections — each attached session lives in a hidden local tmux window; detach and re-attach without disturbing the remote work
- Split workspace — a navigator sidebar plus a remote terminal pane, inside one local tmux session
- iTerm2 integration (macOS) — opens the manager, or any single session, in a new tab without disturbing your current one; standalone tabs auto-reconnect after transient SSH drops
- Session management — create empty sessions, rename, and kill remote tmux sessions from the TUI
- Codex fork — fork a running Codex CLI session into a new tmux session (finds the live rollout thread via
/procand runscodex fork <thread-id>) - One-command setup —
clustermux --initscans your SSH config, installs your key, and writes the hosts file;clustermux --checkverifies the whole setup - Plain output mode —
clustermux --listfor scripts and quick checks - Zero dependencies — a single Python file using only the standard library
Requirements
- Local: Python ≥ 3.9, tmux, and (for tab features) macOS with iTerm2
- Remote hosts: SSH access (key-based, non-interactive) and tmux
- The full-screen dashboard (
--here) and--listwork on any terminal; the default tab-based flow requires iTerm2
Install
pipx / pip
pipx install clustermux
# or
pip install clustermux
# or straight from the repo
pipx install git+https://github.com/lyttttt3333/clustermux.git
Single-file script
clustermux is self-contained — download the file anywhere on your PATH:
curl -L -o ~/.local/bin/clustermux \
https://raw.githubusercontent.com/lyttttt3333/clustermux/main/clustermux.py
chmod +x ~/.local/bin/clustermux
First-time setup
On a fresh machine, one command walks you through everything:
clustermux --init
The wizard will:
- SSH key — use your existing
~/.sshkey, or offer to generate an ed25519 one - Discover hosts — scan
~/.ssh/config(Hostaliases, includingIncluded files) and any unhashed entries in~/.ssh/known_hosts - Probe connectivity — test every candidate in parallel with
BatchModeSSH, classifying each as reachable / key-rejected / unreachable - Install your key — for hosts that reject key auth, offer to run
ssh-copy-id(you type the password once per host) - Write the config — reachable hosts are added to
~/.config/clustermux/hosts.jsonwith sensible group/label defaults (existing entries are kept, and the old file is backed up); you can review the result in$EDITOR
Then verify the whole setup at any time:
clustermux --check
This checks Python, tmux, ssh, iTerm2, your SSH key and config file, then probes every configured host and reports sessions and latency per node.
Configuration
clustermux --init writes this file for you, but you can also create ~/.config/clustermux/hosts.json by hand (see examples/hosts.json):
[
{ "group": "GPU", "label": "login-01", "target": "me@gpu-login-01.example.com" },
{ "group": "GPU", "label": "dev-01", "target": "gpu-dev-01", "connect_timeout": 20 },
{ "group": "CPU", "label": "login", "target": "me@cpu-login.example.com" }
]
group— shown as the cluster name in the UIlabel— per-host display nametarget— anythingsshaccepts (host alias from~/.ssh/config, oruser@host)connect_timeout— optional per-host SSH timeout in seconds (default:--timeout, 8s)
Hosts are validated at startup; SSH is always invoked with BatchMode=yes, so a host that needs a password simply shows up as offline instead of blocking the UI.
Usage
clustermux # open the manager workspace in a new iTerm tab
clustermux --init # first-time setup: scan SSH config, install keys, write hosts.json
clustermux --check # verify local requirements and probe every host
clustermux --workspace # run the split navigator/terminal workspace here
clustermux --here # full-screen dashboard with pane previews, in this terminal
clustermux --list # print one snapshot as a table and exit
clustermux --refresh 60 # change the auto-refresh interval (seconds; 0 disables)
Navigator keybindings (default workspace)
| Key | Action |
|---|---|
↑/↓ |
move between clusters and sessions |
Enter |
attach the selected session in the right pane |
b |
open a remote Bash shell for the selected cluster |
t |
create a new empty tmux session on the selected cluster |
f |
fork the selected Codex session into a new tmux session |
e / x |
rename / kill the selected session |
o |
hand the session off to a standalone iTerm tab (auto-reconnects) |
r |
refresh all hosts |
Shift+← |
jump back to the sidebar from the remote pane |
q |
close the workspace (remote sessions keep running) |
Inside an attached remote tmux session, the remote prefix is Ctrl-b as usual; the local workspace uses Ctrl-a.
Dashboard keybindings (--here)
↑↓ select · Enter attach here · t new tab · r refresh · p preview · q quit
How it works
- Discovery runs
tmux list-panes -aon every host in parallel over SSH and parses a sentinel-separated format that survives older remote tmux builds. - Attaching creates (or reuses) a hidden window in the local
clustermuxtmux session running a supervisedssh -t host tmux attach-session ...; the pane is swapped into the visible slot. Killing the workspace only disconnects local SSH clients — remote sessions and their processes keep running. - The iTerm handoff moves a session into its own tab and respawns the workspace pane as a placeholder, so you can later pull it back into the workspace.
License
Metadata
Release files for clustermux 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| clustermux-0.2.0.tar.gz | 25.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| clustermux-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.5 kB
Release files / clustermux-0.2.0.tar.gz
| Download URL | clustermux-0.2.0.tar.gz |
|---|---|
| Size | 25.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dfda75d46b31d83fb8e2effcd08a425bf630b49409d4d8d2412d22556b4cf1c7
|
|
BLAKE2b-256 checksum How to use checksums |
17045ade3b14626e33bf0fcd2b341ccdbee530084f43a5bf2e9f278150c0396f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / clustermux-0.2.0-py3-none-any.whl
| Download URL | clustermux-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a3eb86905f92b706c22141fa6331c1d0116e767c5ef063dae42cb6ca6598ce83
|
|
BLAKE2b-256 checksum How to use checksums |
f4669e5fa5aa4cab326aa181d485b81a25493740a34cab5d8d6e2acd5c1d4d01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|