mpx

the transparent terminal multiplexer

Your terminal emulator talks directly to the shell. mpx just owns the PTY and forwards bytes. It is not in the way. It has no opinions about your escape sequences, your scrollback, or your font.

$ curl -fsSL https://mpx.capocasa.dev/install | sh

linux amd64·linux arm64·macos universal·termux

early alpha: expect breakage, actively developed

the loop

detach with one key, come back to the exact screen

Start a session, work inside it, leave with Ctrl-G. Attach again later, from the same terminal or a different one, and the session is exactly where you left it, scrollback included.

ghostty no status line. mpx has no UI.
~ $ 

every client is the same client

type in one, both see it. detach one, both live on.

mpx is primaryless: every attached client sees the same output and every client can type. Detach a client and it stops seeing new bytes. Attach again and ttty, the side cache, hands back the current screen plus scrollback. Try it: type a command, switch who is typing, detach and reattach a pane.

laptop · ghostty
desktop · ghostty

Both panes are attached to session demo. Detached panes show what they missed when you attach them again, because attach serves the full model: ttty scrollback plus the live screen.

negative space

what mpx never does to your terminal

no
re-rendering
bytes flow verbatim. What the program drew is what you see.
no
escape sequence mangling
colors, italics, hyperlinks, sixel: all pass through untouched.
no
scrollback theft
your emulator keeps its scrollback, mouse, clipboard, fonts.
no
status line
mpx has no UI at all. It is invisible by design.
no
config file
everything is a flag, on any subcommand, before or after arguments.
no
prefix key
detach is Ctrl-G. One key, the same key on every keyboard layout.

architecture

how it works

who owns what
ghostty, kitty, alacritty          mpx                    the session
your terminal emulator              daemon                 zsh, htop, vim
┌──────────────────────┐          ┌──────────────┐          ┌────────────┐
│ scrollback, font,    │ bytes     │              │ bytes     │            │
│ mouse, clipboard     │<-------->│  owns the    │<-------->│  PTY       │
│ rendering: all yours │ verbatim  │  PTY master  │ verbatim  │            │
└──────────────────────┘          └──────┬───────┘          └────────────┘
                                         │ watches, never in the data path
                                  ┌──────┴───────┐
                                  │   ttty        │
                                  │ side cache.  │
                                  │ read on      │
                                  │ attach only  │
                                  └──────────────┘

day one

cheat sheet (the whole manual)

mpx new
Start a session running your shell. The default action, so mpx or mpx main does the same. No name: the directory's name, with a counter on collision. Rerunning on an active session just attaches.
mpx attach
Attach to a running session, newest unspecified: the oldest. Re-running mpx new main also attaches if it exists.
mpx ls
List sessions. A session lives exactly as long as the program inside it.
mpx kill
End a session. mpx k main works too: any unambiguous command prefix is accepted. mpx n, mpx a, mpx l.
-l host:port
Also listen on TCP. Base port: each session takes the first free port at or above it. -p overrides the port.
--log
Append to $XDG_DATA_HOME/mpx/mpx-YYYY.log. Without it, mpx logs nothing. Unknown flags are errors, not guesses.
Ctrl-G Detach. One key, no prefix, the same key on every layout. (A German keyboard needs Ctrl-AltGr-\ for tmux's key, which is not a key, it is a finger exercise.) Ctrl-D is not the detach key: it is EOF, and it reaches the program, so shells, REPLs and pagers behave normally.

elsewhere

attach from another machine

Run the daemon on the host where the work happens, attach from anywhere that can reach the TCP port. No SSH involvement, no SSH dependency. Over wireguard recommended, the traffic is otherwise unencrypted.

remote
# on 10.0.0.4, the host where the work happens ~ $ mpx daemon -l 10.0.0.4:4534 work # on your laptop, from the kitchen ~ $ mpx attach -l 10.0.0.4:4534 work # clients scan up from the base port and pick their session by name

Session names gate TCP access, but that is convenience, not a security boundary. Keep the listener on a private interface and put real authentication in front if you need it.