I run my work in tmux: builds, logs, servers, and lately a lot of AI coding agents. The thing about an agent in a pane is that it stops and waits for me. "May I run this?" "Which of these three?" "Done." And I am never at that keyboard when it asks. I am in the kitchen, on the train, on a walk.
So I built muxway: a small Go agent next to tmux on each machine, a hub, and clients. The clients got out of hand. There is a browser one, an Android one with a Wear OS watch face, one for Even Realities G2 glasses, and a Java ME MIDlet that runs on a Nokia 6310i from 2002.
That phone has a 96 by 65 pixel screen, GPRS, and cannot do modern TLS. It reads Claude Code and answers it. This post is about why the Nokia was the useful one to build, not the silly one.
The agent calls you
The part I use most is the notification. Claude Code, Codex and Antigravity tell muxway, through their hooks, when they ask a question, want a permission, go idle, or finish. The pane lights up in every client, the phone and the watch buzz, the glasses show a banner at the foot of whatever I am reading. Then I answer from wherever I am: a tap, Enter, y, a number, a few words, or I hold the microphone and say it. The hub transcribes, the words land on the input line, and nothing is sent until I confirm.
In the browser I get up to four tiles from any mix of machines, all live and typable. Drag a header to swap, drag a divider to resize, and tiles that are one tmux window's panes move that window on the host as I rearrange them.
A lens for tiny screens
A terminal does not fit on a watch or a pair of glasses, and certainly not on 96 by 65 pixels. What does fit is the conversation. A lens knows what an agent's screen looks like and reshapes it: the box drawing, the status line and the spinner go, the question and the prompt stay. On the glasses that is eight short lines. On the Nokia it is whatever the screen holds, and you scroll with a key. Whatever the agent suggests in its input box is offered as the first answer, so most of the time the reply is one key.
The lens is also why the Nokia was worth doing. If the API is small enough that a MIDP 1.0 phone can be a client, in under 30 KiB of JAR, then anything can. The protocol has a plain text mode: one authenticated GET returns a pane wrapped to the width you ask for. A phone of that age cannot speak current HTTPS, so it goes through a small relay that terminates TLS for it. The MIDP 2.0 build, on a Nokia 7310 from a few years later, adds colour, Unicode and the camera: take a photo of a whiteboard, it lands in an inbox on the host, and the path is typed into the reply for the agent to read.
It is a remote shell, so build it like one
Whoever can type into a tmux pane owns that machine. I did not want a "trusted network" bypass or a convenience mode that becomes the default.
- Panes are opt-in. Nothing is reachable until its owner marks it with
muxway expose. - A token names which hosts and panes it may read, and separately which it may type into. Read and write are different grants.
- Input is text and a fixed grammar of named keys. Clients never send raw escape sequences.
- Every authentication step is rate limited and locked out. Secrets are hashed, compared in constant time, never logged.
- Every write to a pane is audit logged on the host: who, when, which pane, how many bytes.
- The agent dials out to the hub over a signed, encrypted WebSocket. Nothing listens on your machines, and clients never reach them directly.
- One static Go binary per role, one third party dependency, no cgo.
The hub signs people in with OpenID Connect if you have an identity provider, or with tokens if you do not. It serves the web client from files embedded in the binary, so there is nothing else to deploy.
Getting it running
go install github.com/notmarkopadjen/muxway/cmd/muxway@latest
# on the hub
muxway hub serve --listen 127.0.0.1:7600 --public-url https://hub.example.com --trust-proxy &
muxway hub pair-code --host alice-laptop
# on the machine with tmux
muxway agent pair <code>
muxway agent run &
muxway expose -t work:1.0 --write --name build
muxway hooks claude-code
# back on the hub: a token for a client
muxway hub token create --name phone --read 'alice-laptop/*' --write 'alice-laptop/@build'
Open the hub in a browser and paste the token. For a script or your own client, a pane is one request away:
curl -H "Authorization: Bearer $TOKEN" -H "Accept: text/plain" \
"https://hub.example.com/v1/panes/alice-laptop/@build?width=40&lines=20"
Build your own client
That last request is the whole point. The protocol is documented with examples and a diagram for every flow: bearer tokens, JSON and text mode, long polled events, the key grammar, rate limits, error codes. The four clients I wrote are proof that it holds up from a React app down to a feature phone. If you have a device I do not, a Kindle, an e-ink badge, a Game Boy with a link cable, the API will not be what stops you.
Where it is
It is young and I use it every day. Everything is Apache 2.0:
- muxway: hub, agent, web client and the protocol. First tagged release v0.1.0, static binaries for Linux and macOS.
- muxway-android: phone and Wear OS, APKs on the releases page.
- muxway-glasses-even: the Even Realities G2 app.
- muxway-midp: the Nokia, MIDP 1.0 and 2.0 JARs on the releases page.
Claude Code, Codex and Antigravity are the agents I have tested the hooks and the lens with. Another CLI needs its hooks to call muxway notify on the host and a lens for its screen, and that is a pull request I would be glad to see. If you try it, the thing I most want to hear is where the security model gets in your way, because that is where I would rather hear it from you than find out later.



Top comments (0)