Expediter puts all your Claude Code sessions one phone tap away. It is a companion app that minimizes the amount of time and friction it takes to switch between many active agent sessions, thereby enabling you to increase your throughput and steer more coding agents. When you are planning a spec with an agent that spends two minutes thinking while your third agent is awaiting a response while your fifth agent is requesting permission to delete a branch under active development, it should take you seconds to course correct your agents. Expediter makes this trivial!
How it works once installed:
- You run
expediterin your terminal - Use your phone to scan the QR code
- Start/resume interacting with your claude sessions (in tmux)
- Once an agent replies, the app will show you tickets, each linked to a unique session
- Each ticket shows the name, working folder, and status of linked claude session
- Red ticket = permission request
- Yellow = awaiting further instructions
- Green and shining = the agent is working
- Light grey = waiting for permission for too long / stale session
- Each ticket shows the name, working folder, and status of linked claude session
- You can tap the ticket to immediately jump to the linked session
- (optional) Are all your tickets green? Start a new session and further parallelize your work!
Software engineering in languages with abundant training data is an increasingly low touch job. The software architect of today is more like the chef who manages a bunch of line cooks. Coding agents are incredible at cooking ... their work done per unit time is magnitudes higher than that of humans. This makes agent-minutes extremely valuable. An agent stuck on a request or veering onto an unproductive path is costly, especially when executing a long spec because each delay piles up. If we want to optimally increase our throughput while retaining varying but non-zero levels of oversight over a fleet of agents, it makes sense to minimize the amount of time it takes to switch from one agent to another. Even if you aren't optimizing but simply babysitting many agents, it is beneficial to have a simple tool that makes it easy to access any of your agent sessions.
I hope that the expediter helps you manage more agents or manage few of them better by putting you in a loop with them. I have been using it and it has helped eliminate the time it takes hopping from agent number one to five to three to four (I am also someone who always has too many tabs and windows open) + enabled me to manage more agents than I otherwise would have.
I don't know if this is the optimal shape for a multi-agent manager, so at the moment, I want to see if the core UX resonates with others. Give it a go and share what you think of it!
--
Needless to say, I built this because I was unhappy with all the existing agent management interfaces. Claude Code's official remote control feature demands telemetry. The open-source spin-offs are fine but they also try to be a terminal on your phone, which serves a purpose, but not the problem I was facing.
The human-in-the-loop does impose some inherent constraints; there are some who expect humans will be RL-ified from software engineering altogether. Even if that comes to pass, there will still be those who would exercise their agency, orchestrate many talking machines, and find value in building.
macOS only for now. The installer is interactive but the happy path is two prompts.
git clone https://github.com/AsteroidHunter/expediter.git
cd expediter
./install.shThe installer will ...
- Check for Claude Code and offer to install it if missing.
- Check for tmux, Homebrew, and Bun, and offer to install whatever's missing in one go. (Homebrew's installer prompts for your Mac password -- that's normal and unavoidable.)
- Build the app (
bun install+bun run build). - Write
~/.config/expediter/configso the shims can find your clone (EXPEDITER_HOMEpoints at the repo path). - Drop two commands into
~/.local/bin/, and add that directory to~/.zshrcif it isn't already on yourPATH:expediter-- starts the daemon (if it's not already running) and prints the URL + a scannable QR code for your phone.claudex-- opens a fresh tmux session withclaudeandexpediterin side-by-side panes, so you can start a session with one command.
- Offer to merge Expediter's hook entries into
~/.claude/settings.json(with a timestamped backup). - Offer to apply Expediter's tmux styling via
source-filein~/.tmux.conf(with a backup if you already have one).
First, make sure your phone and your Mac are on the same Wi-Fi network.
If you're an opinionated tmux user, just run:
expediterA QR code shows up in your terminal. Scan it with your phone's camera, open the link in Safari, and you're connected.
However, there's another command if you want to start a fresh Claude Code session along with the Expediter daemon:
claudexThat opens a tmux session with claude and expediter in side-by-side panes.
If you're new to tmux or Claude Code, try:
claudex unoThat starts the daemon, prints the QR, and walks you through four numbered onboarding steps below it.
Expediter needs your phone to reach your Mac at its LAN IP. That's fine on home Wi-Fi and most office or coworking networks. Two situations where it won't work:
- Wi-Fi with client isolation. Some hotel and airport Wi-Fi, and some company guest networks, block peer-to-peer traffic at the access point. Your phone can't reach your Mac no matter what the QR says.
- Captive portals. HTTP requests get intercepted until you sign in. Complete the sign-on on both devices first, then re-run
expediter.
If you switch networks (say, coffee shop to home), your Mac gets a new IP and the old QR points at the wrong address. Re-run expediter to get a fresh one.
Expediter trusts your local network, like Plex, Sonos, or a Philips Hue bridge. Anyone on the same Wi-Fi can reach the daemon's HTTP port; a per-session token gate stops them from doing anything once they reach it.
The token is 16 cryptographically random bytes, base64url-encoded (~22 characters), held only in the daemon's process memory -- there is no token file on disk. The QR you scan encodes the token in the URL fragment (http://<host>:5179/#<token>); browsers never transmit URL fragments to servers, so the token stays out of request logs, server access logs, and proxy logs. Your phone's inline page script reads the fragment, stashes it in sessionStorage, and immediately clears the address bar.
Every time you stop and restart the daemon (Mac reboot, manual stop+start, crash + relaunch, expediter re-invocation), a fresh token is minted in the new process. The old QR stops working; your phone will prompt you to re-scan. There is no rotation ceremony beyond "restart the daemon."
What this stops: uninvited devices on the same Wi-Fi (no token, can't reach /api/*), borrowed-phone access creep (the token dies when you stop the daemon), and post-session token replay (the new daemon process knows nothing about the old token).
What this does not stop: packet sniffing on the same network. Expediter sends ticket data over plain HTTP, so a packet sniffer on your Wi-Fi could read it. With a captured token they could also briefly pop your Terminal window forward, until the daemon restarts and mints a new one. Stick to trusted Wi-Fi; full transport encryption is on the roadmap.
The daemon also trusts processes on your own Mac -- anything running as your user account can POST hook events without a token (via 127.0.0.1) and can fetch the current token from a loopback-only /api/token endpoint. This is the same trust boundary the operating system already enforces around your home directory, Anthropic API keys, and SSH keys; the token gate's job is to extend that trust selectively to your phone.
expediter runs the production build (bun ./build/index.js) under the hood. SvelteKit's built-in CSRF check is production-only, so the production build is the supported deployment surface. bun run dev is for contributors changing the code; don't use it as your everyday daemon.
Already installed? Pull the latest and rebuild in place with one command -- no need to uninstall and reinstall:
expediter updateOr run it directly from the clone:
./update.shAfterwards, restart the daemon (Ctrl-C the expediter terminal and re-run it) to load the new build.
The updater will ...
git pull --ff-onlythe current branch -- skipped if you pass--dev/--no-pull, your checkout has local changes, or the branch can't fast-forward. It never forces or merges; in those cases it just rebuilds what's on disk.- Rebuild the app (
bun install+bun run build). - Rewrite the
expediter/claudexshims and config, and re-copy thecc-clock/cc-datesstatus-bar helpers. - Re-merge Expediter's hook entries into
~/.claude/settings.json(timestamped backup first), so any newly added events register.
Contributors working on a branch can skip the pull with expediter update --dev (or ./update.sh --dev) to rebuild the current checkout as-is.
./uninstall.shThe uninstaller will ...
- Check that the daemon isn't running (abort if it is, so it doesn't leave an orphaned
bunprocess). - Ask for one top-level confirmation.
- Remove
~/.local/bin/expediterand~/.local/bin/claudex. - Remove
~/.config/expediter/config(and the parent directory if it ends up empty). - Splice Expediter's hook entries out of
~/.claude/settings.json(timestamped backup first). - Splice the
source-fileline forexpediter.tmux.confout of~/.tmux.conf(timestamped backup first; deletes the file if it ends up empty). - Remove
~/.expediter-install.log.
It does NOT touch the cloned repo, Claude Code, Homebrew, tmux, Bun, your PATH, or any install-time backups.

