# Muxin docs > All your machines, one app. For you and your AI agents. Every page of the docs at https://muxin.dev/docs, in order. # Introduction > Muxin is one app for all your machines: the Macs, Linux boxes, Windows PCs and cloud servers you work on, for you and your AI agents. From one window you run AI agents and shells on any of your machines, see and use their screens, open their dev servers in your browser, follow their logs, look after their services and containers, move files between them, work on your GitHub issues there, and run commands on several at once or on a schedule. Your AI agents can do all of it too, through MCP or the command line. ![Muxin's overview: a card for each machine with what's running on it, its CPU, memory and disk, and what needs a look.](https://muxin.dev/images/shots/overview-dark.png?v=dfb32ae3) *The overview: each machine, what's running there, and what needs a look.* ## How it works Muxin runs on your computer and reaches each of your machines with your own `ssh`: the keys and `~/.ssh/config` you already have. There's no account and no server of ours in between. *Diagram: Muxin reaches each machine with your own ssh, then talks to its small agent there: over that ssh connection, or directly once you pair them. Away from home it goes over Tailscale.* The first time you use a machine for more than a check, Muxin copies its small agent there (a few MB, in `~/.muxen`). The agent keeps agent sessions running when you close the app, shows the machine's screen, lists its services and ports, and runs your schedules. Muxin keeps it up to date. Muxin talks to the agent over one ssh connection it keeps open. You can pair a machine for a [direct connection](https://muxin.dev/docs/connections.md) instead: faster, especially for desktops, and still only between your computer and your machine. ## What you can do - [Agent sessions](https://muxin.dev/docs/sessions.md): Claude Code, Codex, OpenCode, Gemini CLI, Antigravity, Amp, Pi, Copilot CLI, Cursor Agent, Qwen Code, Droid, Kimi Code or a shell, kept running on the machine, with what each one changed. - [Boxes](https://muxin.dev/docs/boxes.md): hand a task to an agent that works on it by itself, in a container on one of your machines. - [Hand off and move](https://muxin.dev/docs/handoff.md): give a session’s work to another agent, or move it to another machine. - [Desktops](https://muxin.dev/docs/desktops.md): watch a machine's screen and take the mouse and keyboard. - [Servers](https://muxin.dev/docs/servers.md): open a machine's dev server at `localhost` on your computer. - [Logs, services and Docker](https://muxin.dev/docs/logs-services.md): read logs live, start and stop services, containers and Compose projects. - [VMs](https://muxin.dev/docs/vms.md): make a Windows or Linux VM on a machine you have, use it, and destroy it. - [Schedules](https://muxin.dev/docs/schedules.md): a command or an agent session that runs at set times, even with Muxin closed. - [GitHub and workspaces](https://muxin.dev/docs/github.md): hand an issue to an agent in a worktree or a fresh clone. - [For AI agents](https://muxin.dev/docs/agents.md): everything above, through MCP and the CLI. ## Platforms The app runs on macOS (12 or later), Linux and Windows 11. The machines it manages are Macs, Linux machines and Windows PCs you can reach with ssh: on your desk, in the cloud, or across Tailscale. Source: https://muxin.dev/docs --- # Getting started > Install Muxin, add your first machine, and start an agent on it. ## Install Download Muxin for your computer from the [download links](https://muxin.dev#platforms), or the [latest release on GitHub](https://github.com/LumaryLabsLLC/muxin/releases/latest). It's free and open source. - **macOS**: a signed app for macOS 12 or later, on Apple silicon and Intel. Drag it to Applications. - **Windows 11**: an installer, for Intel and AMD PCs or Windows on Arm. It installs for you (no administrator needed), and can add `muxin` to your PATH for terminals and AI agents. It isn't signed yet: if Windows warns you, choose **More info**, then **Run anyway**. - **Linux**: the same app, for Intel and AMD or Arm (Ubuntu 22.04, Debian 12, Fedora 36, openSUSE Tumbleweed, RHEL 10 or newer). Pick the package for your system: - Debian and Ubuntu: the `.deb`, then `sudo apt install ./Muxin-*.deb`. - Fedora, openSUSE and RHEL: the `.rpm`, then `sudo dnf install ./Muxin-*.rpm` (or `sudo zypper install`). - Arch: `yay -S muxin-bin` from the AUR, or the `.pkg.tar.zst` with `sudo pacman -U`. - Any distribution: the AppImage. Make it executable and run it. It needs no FUSE 2. - Without root: the `.tar.gz`. Unpack it and run `./Muxin/install.sh`. It installs for you, with Muxin in your app menu. Or install it with Homebrew, on macOS and Linux: ``` brew install --cask lumarylabsllc/tap/muxin ``` The `muxin` command, for your terminal and your AI agents, comes with Homebrew and the Linux packages. Otherwise, **Settings › General › Command line** installs it. > **Note:** Updating from Muxen > > Muxin was called Muxen before 0.5.1. Updating keeps your settings, machines and sessions. The `muxen` command still works too. On a Mac, the old Muxen app goes to the Trash the first time Muxin opens. ## Make sure ssh works Muxin reaches machines the way you would from a terminal: `ssh` with a key, no password prompt. If `ssh my-machine` works in your terminal without asking for a password, Muxin can add it. - **A Mac**: turn on **Remote Login** in System Settings › General › Sharing. - **Linux**: install and start the ssh server (`sudo apt install openssh-server` on Ubuntu and Debian). - **Windows**: turn on **OpenSSH Server** in Settings › System › Optional features. See [Windows](https://muxin.dev/docs/windows.md). Then give it your key once, with your password there: ``` ssh-copy-id you@my-machine.local ``` > **Note:** Muxin uses your `~/.ssh/config`: aliases, users, ports, keys and jump hosts all work as they do in your terminal. ## Add a machine Click **Add machine** (`⌘N`). Give it a name and its ssh destination: `you@host`, an alias from your ssh config, or `local` for the computer you're on. Muxin suggests your ssh aliases, the computers on your Tailscale network and the ones it finds on your local network. ![The Add a machine dialog: a name, an ssh host, and suggestions from the ssh config, the tailnet and the local network.](https://muxin.dev/images/shots/addmachine-dark.png?v=5ede0c65) *Suggestions come from your ssh config, your tailnet and your local network.* Muxin checks the machine right away: a read-only look at its CPU, memory, disk, what's running and what needs attention. Nothing is installed by a check. The machine shows up in the sidebar and on the overview. Once it answers, Muxin connects to it [directly](https://muxin.dev/docs/connections.md#direct), without ssh in between, so terminals and the desktop respond faster. Its agent runs there as a service of yours. To keep it on ssh, uncheck **Connect to it directly** in the dialog. ![A machine's page: its CPU, memory, disk and uptime, its sessions, servers, connection and git.](https://muxin.dev/images/shots/beacon-dark.png?v=74644470) *A machine's page: how it's doing, what's running, its servers and how Muxin reaches it.* ## Start an agent Click **New session** (`⌘T`), pick the machine, the agent and the folder, and optionally what it should work on. The agent runs on that machine and keeps going when you close Muxin; come back to it from the sidebar. ![The New session dialog: the machines (VMs under the one they're in), the agents installed there, and the folder.](https://muxin.dev/images/shots/newsession-dark.png?v=ceebb778) *Machines, then the agents installed on the one you pick, then where it works.* ## Closing the window Muxin keeps running when you close its window. It goes on checking your machines and holding your connections and port forwards. An icon in the menu bar or tray brings the window back. A dot on the icon means a session is waiting for you. Its menu has: - A line on how things stand, like “3 machines online · 2 working · 1 needs you”. - The sessions that need you or are done. Click one to open it. - **Show Muxin**, **Settings…** and **Check for Updates…**. When a new version is out, that one says so. - Muxin’s version, and the version of Muxin’s agent on this computer. **Copy Versions** copies them with your system’s version, for a bug report. - **Quit Muxin**. Your agent sessions keep running on their machines. Open Muxin again to get back to them. - **Mac**: the Dock icon brings the window back too. `⌘Q` quits. - **Windows**: click the icon for the window, or right-click it for the menu. Point at it to see how things stand. Windows 11 may put a new icon under the **^** arrow by the clock. Drag it out to keep it in view. - **Linux**: the window comes back on the same page, with its terminals reattached. Open dialogs and half-typed text don’t come back. On a desktop with no tray, closing the window quits Muxin. On GNOME, the AppIndicator extension adds a tray. Opening Muxin again brings the running copy forward. To quit from a terminal, run `muxin quit`. ## Next - [Machines](https://muxin.dev/docs/machines.md): what the overview and a machine's page tell you. - [Agent sessions](https://muxin.dev/docs/sessions.md): splits, waiting agents, opening a folder in your editor. - [MCP for your agents](https://muxin.dev/docs/agents.md): let Claude Code or Codex use Muxin. Source: https://muxin.dev/docs/getting-started --- # Machines > What the overview and a machine’s page tell you, how the sidebar is organized, and what each state means. Every computer you add is a machine in Muxin: a Mac on your desk, a Linux server, a Windows PC, a cloud droplet, or a VM running on one of them. Muxin checks each one now and then and shows how it’s doing in three places: the overview, the machine’s own page, and the sidebar. ## The overview The overview (`⌃1`) has a card for each machine: what’s running on it (agent sessions, its desktop, its runners), and its CPU, memory and free disk. Click a card to open the machine. Above the cards, a short list says what needs a look: a runner that stopped, a job no runner can take, a disk running low, a GitHub scope Muxin can’t read. Each item has a button that goes where you can fix it. Machines that can’t be reached aren’t repeated there: their cards already say so, and why. ![The overview: a heads-up list of what needs a look, then a card for each machine with its sessions, runners, CPU, memory and disk.](https://muxin.dev/images/shots/overview-dark.png?v=dfb32ae3) *sandbox and win-test are VMs: a container on Forge and a Windows VM on Beacon.* ## A machine’s page Open a machine from the sidebar, a card, or `⌘P`. From the top: - **Its header**: how Muxin reaches it, its system, and buttons for a new session, its desktop and sharing it. Then its **Logs**, **Services** and **Files**. The **···** menu at the end installs a runner or removes the machine. - **CPU, memory, disk and uptime**, from the last check (and its GPU when it has one). - **Runs here**: the VMs and containers that run on it, with Start and Stop. See [VMs on your machines](https://muxin.dev/docs/vms.md). - **Agent sessions** running there, and which agent CLIs it has. - **Servers**: what’s listening, web servers first. See [Servers and ports](https://muxin.dev/docs/servers.md). - **Connection**: over ssh or direct, which network, and how fast. See [Connections](https://muxin.dev/docs/connections.md). - **Git**: whether commits and pushes work there, with a button to set up your GitHub identity. - **Runners**, **Diagnostics** (what a check found worth knowing, with a button for the likely fix) and **Agent workspaces**. ![A machine's header: its name, online state, host, system and buttons, then cards for CPU, memory, disk and uptime.](https://muxin.dev/images/shots/health-dark.png?v=54315791) *The top of a machine’s page: what it is, how it’s doing, and what you can do with it.* ## The sidebar The sidebar lists every machine, and under each one what’s open on it: its agent sessions, its desktop, its logs and services pages, ports you opened, and its runners. Click the arrow beside a machine to fold it. - **Put machines in any order.** Drag one onto another to take its place. A line shows where it will land. Or right-click it and point at **Move** for **Up**, **Down** and **To the top**. The order is saved in `config.toml`, so `muxin status` lists them the same way. New machines go at the end. - **Favorites** get a star and go to the top. Star a machine on its page or in its right-click menu. - **Right-click a machine** for what you can do there. Related items open beside the menu: **New session** (one per agent), **Desktop**, **New** (a runner, a schedule, a VM), **Move** and **Power**. - `⌘1` to `⌘9` go to the first nine machines, in the sidebar’s order. Hold `⌘` to see which is which. Settings › Keyboard changes the modifier, or turns them off. - **VMs sit under their machine.** A VM or container that runs on another of your machines is indented under it, with a line from its host, and its subtitle says so (“Windows 11 · VM”). It moves with its machine, and you can reorder the VMs under it. - `⌘F` searches machines and sessions; the list shows only what matches. ## What each state means A machine’s dot and subtitle say how it is. Gray means nothing’s wrong; amber or red means something needs fixing. - **Online**: the last check reached it. - **Offline**: it didn’t answer. It’s shut down, asleep or off the network, and there’s nothing to fix. Its page says when it was last seen, and offers **Wake** when Muxin knows its network card. - **Can’t connect**: it answered, but ssh didn’t work. The subtitle gives the reason in a few words (“Not accepting ssh”, “ssh key not accepted”, “Host key changed”), and its page says what to do. See [Troubleshooting](https://muxin.dev/docs/troubleshooting.md). - **Disconnected**: you disconnected it on purpose. Muxin leaves it alone until you connect it again; its sessions keep running there. - **Installing**, **Stopped**, **“Beacon is offline”**: a VM that’s still setting itself up, whose container is stopped, or whose host is off. - **Powered off**: a cloud machine you powered off. It’s still billed. ![An offline machine's page: Harbor is offline, shut down, asleep, or off the network, with Wake and Try again.](https://muxin.dev/images/shots/offline-dark.png?v=8a1cb25a) *An offline Mac: Wake sends a Wake on LAN signal, Try again checks it now.* ## Waking a machine **Wake** sends a Wake on LAN signal from this computer, and from your other online machines on the same network (so it works when you’re away from home too). It works once Muxin has seen the machine’s network card while it was on, and when the machine is set up to wake that way. Muxin checks it again after 20 and 40 seconds. ## Checks A check is a short, read-only script over ssh: CPU, memory, disk, uptime, what’s running, runners, Docker, whether updates want a reboot, failed services. Nothing is installed by a check. - Muxin checks every machine every 15 minutes. Change that in **Settings › General › Machine checks** (0 means only when you ask). - The refresh button on a machine’s page checks that one now; `⌘R` checks them all. - The overview says when the last check finished. ## Ignoring a warning Some machines are meant to have a warning. A NAS’s system volume is small by design, so it’s always “low on disk”. Click **Ignore** on the warning. It goes from the machine’s page and from what needs attention. The machine’s page lists what’s ignored. Click one there to warn about it again. Low disk, a reboot waiting and failed services have the button. You can also write `ignore_warnings = ["low-disk"]` on the machine in `config.toml`, or run `muxin ignore beacon low-disk` (`--undo` warns again). ## Renaming and removing Right-click a machine for **Rename…**, **Disconnect** and **Remove from Muxin…**. Renaming keeps its id, so its sessions, favorites and history stay with it. Removing takes it out of `config.toml`; nothing changes on the machine, and its runners stay registered. > **Warning:** For a cloud machine or a VM Muxin made, the last item is **Destroy…** instead: it deletes the droplet, or the VM’s container and disk, with everything on it. Source: https://muxin.dev/docs/machines --- # Connections > How Muxin reaches your machines: one ssh connection, or a direct one over QUIC, on your local network or through Tailscale. Muxin reaches each machine with your own ssh, installs its small agent there, and from then on talks to that agent over **one live connection**. Requests take milliseconds, terminals open at once, and the sidebar changes the moment a session does. You don’t set any of this up: it happens when you add a machine. *Diagram: Muxin reaches each machine with your own ssh, then talks to its small agent there: over that ssh connection, or directly once you pair them. Away from home it goes over Tailscale.* ## Over ssh By default each machine has one ssh connection, kept open and opened again when it drops. Everything goes through it: checks, terminals, the desktop, files, servers you open in your browser. Anything `ssh` accepts works as a machine’s host: an alias from `~/.ssh/config`, `user@host`, a Tailscale name. Muxin uses your keys and your ssh config, so jump hosts, ports and identity files you’ve set up there apply. ## Direct connections Machines you add are connected to directly once they answer. Muxin pairs with the agent there by itself. For a machine you already had, use **Connect directly** in the Connection card on its page. Pairing works like this. Each side trusts only the other’s certificate, swapped over ssh, and the agent’s listener runs as a user service on the machine: systemd on Linux, launchd on a Mac, a scheduled task at sign-in on Windows (with a firewall rule). - Direct connections use **QUIC on UDP port 47821**. There’s no ssh in between, which helps the desktop and busy terminals most. - When the direct connection is down, Muxin falls back to ssh on its own, and goes back to direct when it can. - **Use ssh only** in the same card turns it off again. - **To keep a new machine on ssh**, uncheck **Connect to it directly** when you add it, or use `muxin add-machine --ssh-only`. - **Settings › General › Connections** turns it off for every new machine. - **Muxin offers it for the others.** When a machine is reached over ssh on your local network or your tailnet, the Overview asks “Connect to it directly?”. **Keep ssh** stops the question. 1. **Add a machine**: Or Connect directly in a machine’s Connection card. 2. **Pairing over ssh**: The app and the agent swap certificates; the listener starts as a user service. 3. **QUIC on UDP 47821**: Muxin connects directly, and falls back to ssh whenever that’s down. *Pairing happens once per machine.* > **Warning:** On a Mac, direct connections need the **Local Network** permission. If the card says the machine is “not reachable on this network”, allow Muxin in **System Settings › Privacy & Security › Local Network** and reopen it. When the machine is a Mac, allow **Muxin Agent** (`muxen-agent` before Muxin 0.10.0) there on that Mac too. If direct doesn’t connect and neither of those is the reason, the card says “Direct didn’t connect (UDP 47821 blocked?), so it’s ssh.” A firewall between you and the machine is the usual cause. [Muxin for iPad](https://muxin.dev/docs/ipad.md) uses direct connections too, with a key of its own. It uses ssh only to add a machine. ## On a slow network Over a direct connection, each terminal has its own lane to the machine. A busy agent printing a lot doesn’t hold up the terminal you’re typing in. - The terminal you’re typing in goes first. In a split, that’s the pane with the keyboard. - A terminal you’re not looking at that keeps printing is let go for now. Its session keeps running. Open it again and it comes back with its screen and recent history. Over ssh, everything shares one connection, so only the second part helps there. ## Local network and Tailscale If [Tailscale](https://tailscale.com) is on this computer, Muxin uses it to reach your machines away from home. It only reads Tailscale’s status and never changes its settings. - **Home network first.** A paired machine is tried at its local-network address first, and at its Tailscale address a moment later; the first to answer wins. - **Moving.** When you change networks, connections that stopped working are rebuilt the best way from where you are. Open terminals and desktops carry on (“Reconnecting…”). - **ssh too.** If a machine’s host only works at home (a local IP), ssh goes to its tailnet address when the usual one doesn’t answer. - **Peer-to-peer or relay.** Through Tailscale, the card says whether traffic goes straight to the machine or through one of Tailscale’s relays, which is slower. The Connection card shows all of this: Direct or Over ssh, then Local network or Tailscale, and the round trip in milliseconds. Below that, whether the machine is on your tailnet. On a Linux machine that isn’t, **Set up Tailscale** types the install command into a shell there for you to run. ![Beacon's page with a web server open at localhost:5173, and the Connection card below: direct, local network, a few milliseconds.](https://muxin.dev/images/shots/servers-dark.png?v=643a32f5) *The Connection card on a machine’s page, under its servers.* ## A forwarded port If a machine is behind a router or NAT and you forward a UDP port to it, tell Muxin where direct connections reach it with `direct_address` in `config.toml`: ``` [[machine]] name = "NAS" host = "nas" direct_address = "nas.example.com:47822" ``` VMs Muxin makes get one automatically: their host forwards a UDP port to each VM, and the card says “QUIC through Beacon’s forwarded port 47822”. ## Machines reached through another A machine you reach through another one, with `ProxyJump` in your ssh config (or `-J`), is shown under that machine in the sidebar. Its Connection card says “One ssh connection through Beacon”, and “Through Beacon: reachable wherever Beacon is.” When it can’t be reached, Muxin says whether the machine in front of it is off, or up with nothing answering behind it. ## Disconnecting **Disconnect** (in the Connection card, or a machine’s right-click menu) stops everything for that machine: Muxin closes its connection and stops checking it and reading its sessions. The sessions keep running there. - It shows as **Disconnected** until you **Connect** it again, from its page, its menu, or search. - It’s kept in `config.toml` as `disconnected = true`. - Anything that would reach it fails with “Connect to it first.” ## From the command line ``` muxin connection beacon # how it's reached, and how fast muxin connection beacon --direct on # pair for direct connections muxin disconnect beacon muxin connect beacon ``` Source: https://muxin.dev/docs/connections --- # Muxin for iPad > Your machines and their agents on an iPad: add them by their address or pair it from your Mac, then watch, answer and start sessions, and get an alert when an agent needs you. Muxin for iPad shows your machines and the agents on them, away from your desk. Watch a session, answer what an agent asks, type into its terminal, or start a new one. Open a machine’s desktop, files, logs and services. The iPad talks to each machine directly: your Mac doesn’t have to be on. ![Muxin for iPad’s Overview: the machines in the sidebar with their sessions, desktops and runners; what needs attention at the top; and a card for each machine with what runs there and its CPU, memory and disk.](https://muxin.dev/images/shots/ipad-dark.png?v=c94d9812) *The Overview on an iPad: your machines, what runs on each, and what needs you.* > **Note:** Get [Muxin for iPad on the App Store](https://apps.apple.com/app/muxin-for-ipad/id6829937152), or see [what it does](https://muxin.dev/ipad). It needs iPadOS 18 or later. The demo is free. Reaching your own machines takes a subscription, Muxin Monthly: $15 a month in the US. ## Add a machine by its address Tap **+** next to **Machines** in the sidebar, then **Add a machine**. Type your account there and the machine’s name or address, like `adib@192.168.1.50`, `adib@studio.local` or a Tailscale name, and its ssh port if it isn’t 22. 1. **The first time**, Muxin shows the machine’s key, like `SHA256:5SzP…`. Check it on the machine with `ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub` (on Windows, the file is in `C:\ProgramData\ssh`), then tap **Trust it**. 2. **The iPad signs in with a key of its own.** The first time, its key isn’t there yet, so Muxin asks for your password there, once. It uses it to put the iPad’s key in `~/.ssh/authorized_keys`, and doesn’t keep it. 3. **Muxin installs its agent** and sets up a direct connection, as the Mac does. From then on the iPad reaches the machine directly. A machine that doesn’t take passwords over ssh needs the iPad’s key added by hand, as a line in `~/.ssh/authorized_keys`. On Windows, an administrator’s keys go in `C:\ProgramData\ssh\administrators_authorized_keys`. **Settings › General › This iPad’s SSH key** copies it. After that the iPad reaches the machine directly, over UDP port 47821. If a firewall there blocks it, the iPad says so when you add the machine. Muxin on an iPad can’t start the `ssh` program, so it has an ssh client of its own. It doesn’t read an ssh config: name the machine by its address. It works with Macs, Linux and Windows. ## Or pair it with your Mac If Muxin on your Mac already has your machines, pair the iPad once and it reaches the ones you pick. 1. On the Mac, open **Settings › Mobile** (**Settings › iPads** before Muxin 0.14.0). Tick the machines the iPad should reach, then click **Pair an iPhone or iPad**. A QR code shows. 2. On the iPad, tap **Pair with your Mac** and scan the code. 3. Both show the same 6-digit code. Check that they match, then click **Allow** on the Mac. The iPad makes a key of its own, and each machine you picked trusts it. From then on the iPad connects to them directly, over your network or [Tailscale](https://muxin.dev/docs/connections.md#networks), the same way a [direct connection](https://muxin.dev/docs/connections.md#direct) works on the Mac. A machine without direct connections yet gets them as you pair, so it has to be online then. To add machines later, pair again. To take an iPad off every machine, click **Unpair** next to it in **Settings › Mobile**. An iPad that’s connected at the time is let go within seconds. From a terminal: `muxin ipad pair`, `muxin ipad ls` and `muxin ipad rm `. To look around before pairing, tap **Try the demo** on the iPad’s first screen. ## Sessions on the iPad Sessions work as they do on the Mac. Tap one in the sidebar to see its terminal, with its agent, folder and branch above it. When the agent asks something, its question and choices show under the terminal: tap one to answer. ![A Codex session on the iPad, asking to run a test command. Under the terminal, the question again with three buttons: Yes, proceed; Yes, and don’t ask again for this command; No, and tell Codex what to do differently.](https://muxin.dev/images/shots/ipad-session-dark.png?v=b56f4eb1) *Codex wants to run a command. The answers are buttons under its terminal.* - **Type** with the on-screen keyboard and its bar of esc, ctrl and the arrows, or with a hardware keyboard. - **Pinch** a terminal to change its text size. - **Two fingers left or right** go to the next or previous session. - **Side by side.** Split a session’s page to watch two or more at once, or open one in a window of its own, in Split View or Stage Manager. From version 1.2, sessions in [Claude’s desktop app](https://muxin.dev/docs/sessions.md#claude-desktop) show too. Tap one to open it in Claude on its machine, with that machine’s desktop in front. A machine’s warnings have **Ignore**, as on the Mac. From version 1.4: - **Long lists fold.** A machine with many sessions lists the first five, plus any that need you. Tap **more** for the rest. - **Hide a session** by swiping it, or by touching and holding it. It stays hidden until it needs you. **hidden**, at the bottom of a machine’s list, shows those sessions again. - **Snippets** are commands you save once. The **Snippets** menu on a session’s page types one into its terminal. On the **Run** page, one tap runs one on the machines you picked. The iPad keeps its own hidden sessions and snippets, apart from the Mac’s. ## Agents and machines in the sidebar From version 1.2, the sidebar has what the Mac’s has. - **Every agent in one list.** Under the machines, **Agents** lists every agent session on all of them, the ones that need you first. Tap one to open it. Tap **Agents** to fold the list. **Settings › General › Agents** turns it off. - **Your order.** Touch and hold a machine for **Move Up**, **Move Down** and **Move to Top**. Until you move one, your favorites come first. The order is the iPad’s own: it doesn’t follow your Mac’s. ## A machine’s desktop Tap **Desktop** under a machine to see its screen and use it, with touch, the on-screen keyboard or a hardware keyboard. It works as [Desktops](https://muxin.dev/docs/desktops.md) do on the Mac. From version 1.2, **Keys** in the bar above the screen sends a shortcut with a tap: a Mac’s Spaces, Mission Control and app switcher, the Windows key and Task Manager, Ctrl+Alt+Del on Linux. iPadOS keeps `⌘Tab` and `⌘Space` for itself, so a keyboard can’t send those. ## Alerts With alerts on, your machines tell the iPad when an agent needs you, even while Muxin is closed: - **Needs you or done.** An agent asks something or wants a permission, or it finished. The alert says which. - **Rang the bell.** - **Exited with an error.** Turn them on in the iPad’s **Settings › General › Alerts**, and allow notifications when the iPad asks. Each kind has its own switch. Under them, each machine says whether it took the change. **Send a test alert** asks each one for an alert now. An alert says what happened, in which session, on which machine: “Claude Code needs you”, “Checkout fix · Forge”. Tap it to open that session. While you’re already looking at a session, its alerts don’t show. > **Tip:** A machine that says **Needs a newer Muxin** runs an agent from before alerts. Update Muxin on your Mac: it updates a machine’s agent the next time it reaches it. 1. **On your machine**: The agent sees a session waiting, and seals the alert with a key only your iPad and your machines have. 2. **muxin.dev passes it on**: It hands the sealed alert to Apple’s push service. It can’t read it, and doesn’t keep it. 3. **On your iPad**: Muxin opens it with its key, and shows what happened and where. *Alerts are encrypted from your machine to your iPad.* ## How it stays secure - **Keys of its own.** The iPad makes its keys itself, and keeps them in the app: one for its direct connections, and one for ssh when it adds a machine. A backup you make of the iPad may include them. Nothing else a machine trusted changes. - **Host keys you checked.** The first time the iPad signs in to a machine, you check its key. If it changes later, the iPad refuses to connect. - **Your password, once.** It’s used to put the iPad’s key on the machine, and isn’t kept. - **You allow it.** Pairing shows the same 6-digit code on the Mac and the iPad, and nothing is trusted until you click **Allow**. - **Straight to your machines.** Sessions, desktops and files go from the iPad to each machine over an encrypted connection (QUIC), checked against each machine’s certificate. They never go through muxin.dev. - **Alerts only it can read.** Each alert is encrypted on the machine with the iPad’s key. muxin.dev and Apple only carry it, and see just when it was sent and the session’s short id, such as `claude-a1b2`. The id the machines send alerts to is the iPad’s push token, encrypted by muxin.dev, so nothing about your iPad is stored there. - **Removing ends it.** Remove a machine from the iPad, or unpair the iPad on the Mac, and the machine forgets the iPad’s keys and stops sending it alerts. ## What stays on the Mac The iPad reaches the machines you added or paired, directly. These stay on the Mac: - Making [VMs](https://muxin.dev/docs/vms.md) and [cloud machines](https://muxin.dev/docs/cloud.md), and opening a folder in your editor. - Machines named by an ssh config alias or reached through another (a jump host). - The [command line](https://muxin.dev/docs/cli.md) and the [MCP server](https://muxin.dev/docs/agents.md) for your agents. - Sharing. The iPad can join a share someone made, but it doesn’t share anything itself. Source: https://muxin.dev/docs/ipad --- # VMs on your machines > Make a Windows or Linux VM on a machine you already have, use it like any other machine, and destroy it when you’re done. Need a clean Windows to try an installer, or a throwaway Linux for an agent to work in? **New VM** makes one on a machine you already have, sets it up with your ssh key, and adds it to your machines, under the one it runs on. From then on it’s a machine like the others: sessions, files, servers, workspaces and its desktop all work. *Diagram: Each VM is a Docker container on a machine you already have, and one of your machines in Muxin, shown under it.* ## What you can run, and where - **Windows**: Windows 11, Windows 10, Windows Server 2025 or Windows Server 2022. It runs in Docker with KVM ([dockur/windows](https://github.com/dockur/windows)), so its host must be a **Linux machine (x86-64) with Docker and `/dev/kvm`**, like a mini PC or a server, with about 30 GB free. - **Linux**: Ubuntu 26.04, Ubuntu 24.04, Debian 13, Fedora, Alpine or Arch Linux (Arch on x86-64 only). It’s a container with ssh, on **any machine with Docker**, this Mac included. It’s ready in under a minute and shares its host’s kernel, so there’s no systemd inside. A VM can’t run inside another VM. If none of your machines can run what you picked, the dialog says what it needs. ## Making one Open **New VM** from any of these: - **New VM…** in the Add machine dialog (`⌘N`). - **New VM…** in the command palette (`⌘⇧P`). - **New VM here…** in a machine’s right-click menu, on machines that can run one. - The **New VM** choice in the New session dialog (`⌘T`): it makes an Ubuntu VM and starts the session in it, for an agent you want to keep off your real machines. Pick a name, a system, the machine it runs on (with its free memory), and a size: 2, 4 or 8 CPUs, 4, 8 or 16 GB of memory, and for Windows a 64, 128 or 256 GB disk. The defaults are 4 CPUs, 8 GB and 64 GB. ![The New VM dialog: a name, the system (Windows 11 picked), the machine it runs on (Beacon), and its CPUs, memory and disk.](https://muxin.dev/images/shots/vmnew-dark.png?v=cada6737) *Windows 11 on Beacon: the dialog says how long it takes, and what the host needs.* ## What a Linux VM comes with Under **Comes with**, pick the agent CLIs to install: Claude Code (on by default), Codex, Gemini CLI and OpenCode. They’re installed with Node.js as the VM starts, which adds a few minutes, and sign in the first time you use them. On Ubuntu, Debian and Fedora the GitHub CLI comes too. ## The Windows install Windows downloads itself (about 6 GB) and installs on its own: **15 to 30 minutes** the first time. Then a first-boot script turns on OpenSSH with your key, and Muxin installs its agent. - It joins your machines as soon as its container starts, and shows as **Installing…** in the sidebar until Windows answers ssh. - **Watch the install** on its page shows its screen in your browser, at `localhost`. - It runs unactivated until you enter a key. - Muxin makes its Windows account’s password and keeps it in your Keychain. **Copy password** on its page copies it, for signing in on its screen. > **Tip:** The dialog closes as soon as the VM starts being made, so you can carry on. Its progress, Docker’s output included, is in Activity (`⌘J`). ## Using it A VM’s page starts with a card that says where it runs (“Virtual machine on Beacon”, or “Container on Forge”) and whether its container is running, with: - **Stop** and **Start**. Stop gives Windows two minutes to shut down cleanly; Start waits until it answers ssh. Both are in its right-click menu too. - **Copy password** (Windows) and **Open Beacon**, its host. - **Destroy…** Its host forwards a UDP port to each VM, so **Connect directly** works on a VM like on any machine. See [Connections](https://muxin.dev/docs/connections.md). ![win-test's page: a Virtual machine on Beacon card with Stop, Copy password, Open Beacon and Destroy, and the sidebar with win-test under Beacon.](https://muxin.dev/images/shots/vm-dark.png?v=ad2b12fa) *A Windows VM on Beacon, and in the sidebar under it.* When a VM can’t be reached, it says why: “win-test is stopped” (start it), or “Beacon is offline” when its host is off. ## Destroying it **Destroy…** deletes its container and its disk on the host (under `~/.muxen/vms/`), and takes it out of Muxin. Everything in it is gone, so copy out anything worth keeping first. To keep a VM without it using memory, **Stop** it instead. > **Warning:** Destroy can’t be undone. Muxin asks first. ## From your agents and the command line Your AI agents can do the same through [MCP](https://muxin.dev/docs/agents.md): `vm_options` says where VMs can run and what, `vm_create` makes one (for Windows, with `wait: false`, then poll the operation), `machine_power` starts and stops one, and `vm_destroy` deletes it. Make a Windows VM for a test, use it, destroy it. ``` muxin vm options # where VMs can run, and what muxin vm create win-test --system windows-11 --on beacon muxin vm create scratch --system ubuntu-24.04 --install claude,codex muxin power win-test off muxin vm destroy win-test ``` Without `--on`, it goes on the machine with the most free memory that can run it. `--cpus`, `--memory` and `--disk` (in GB) set its size. Source: https://muxin.dev/docs/vms --- # Cloud machines > Make a DigitalOcean droplet from Muxin, set up and added to your machines, and keep an eye on what it costs. Need a machine you don’t have? Muxin can make one in your DigitalOcean account: a droplet with your user and ssh key, the tools you picked, and Muxin’s agent, added to your machines. Then it’s like any other machine: terminals, agent sessions, files, workspaces, runners. > **Warning:** A cloud machine costs money every hour it exists, powered on or off. Only **Destroy** stops the charges. ## Connecting your DigitalOcean account In **Settings › Cloud**, sign in one of three ways: - **Browser**: **Sign in with DigitalOcean** opens DigitalOcean’s sign-in page and comes back to Muxin. - **API token**: create a token with read and write access on DigitalOcean and paste it in. It’s kept in the Keychain on a Mac, and in Credential Manager on Windows. - **doctl**: if you use DigitalOcean’s command line tool, run `doctl auth init` in a terminal, then **Check again**. Settings › Cloud then says which account you’re connected as, with **Sign out**. ## Making one Pick **New cloud machine…** in the Add machine dialog (`⌘N`) or the command palette. Give it: - **A name**, which is also its name in Muxin. - **A region.** The nearest one is picked for you. - **A size**: CPUs, memory and disk, each with its monthly price. The button says what you’re about to pay (“Create · $24/mo”). - **What it comes with.** Tools (Docker, the GitHub CLI), languages (Node.js, Python, Go, Rust and others), agent CLIs (Claude Code, Codex, Gemini CLI, OpenCode, Amp, Pi) and Tailscale. By default: Docker, the GitHub CLI, Node.js with Claude Code and Codex, and Tailscale. Muxin creates the droplet (Ubuntu 24.04), sets up your account and ssh key, installs what you chose, and adds it to your machines. Follow along in Activity (`⌘J`). The defaults for new machines (region, size, what they come with) are in **Settings › Cloud › New machines**. > **Tip:** With Tailscale picked, save a **Tailscale key** in Settings › Cloud and new machines join your tailnet by themselves. Without one, Muxin opens Tailscale’s approval page for each new machine. ## Its page A cloud machine’s page starts with a card: its region and size, whether it’s running (and how long it’s been idle), and what it costs: its hourly rate, this month so far, since it was created, and what this month comes to if you keep it. The card has **Power on** or **Power off**, and **Destroy…**. ![The dev-1 cloud machine's page: DigitalOcean, its region and size, running, with its hourly rate, this month, since created and the month's total, and Power off and Destroy.](https://muxin.dev/images/shots/cloud-dark.png?v=e47ec87e) *dev-1, a DigitalOcean droplet: what it costs, and the buttons that change that.* ## How billing works DigitalOcean bills a droplet by the second while it exists, **powered on or off**, up to its monthly price. - **Power off** shuts it down, but it’s still billed. Its sidebar entry says “Powered off”. - **Destroy…** deletes the droplet and everything on it, and takes it out of Muxin. That stops the charges. Muxin asks first and says what it has cost so far. - **Remove from Muxin** isn’t offered for a cloud machine, since removing it alone would leave it running, and billed. > **Warning:** Push your work before you destroy one. Nothing on it can be brought back. ## When one sits idle Muxin can notice a cloud machine nobody is using: no busy agent session, no running job, and no CPU use. In **Settings › Cloud › When one sits idle**, pick what happens: - **Nothing.** - **Tell me**: it shows on the overview, under what needs a look (the default). - **Power off**: it stops, but is still billed. - **Destroy**: it’s deleted, with everything on it. Then pick after how many hours, from 1 to 72 (3 by default). Muxin has to be open to notice. ## Usage and cost **Settings › Cloud › Usage and cost** adds it all up: what you’re paying per hour right now, this month so far (machines destroyed this month included), what the month comes to if nothing changes, and your whole DigitalOcean bill this month, with **Open billing**. The bill needs permission to read it: sign in with the browser, or use a token with `billing:read`. ## From the command line and MCP ``` muxin cloud login --token dop_v1_... muxin cloud options # regions, sizes and prices muxin cloud create dev-1 --size s-2vcpu-4gb muxin cloud usage # what they cost muxin cloud power dev-1 off # still billed muxin cloud destroy dev-1 ``` Your agents have the same through MCP: `cloud_options`, `cloud_create`, `cloud_usage`, `cloud_power` and `cloud_destroy`. They’re told to say the size and price and get your OK before creating one. See [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/cloud --- # Windows > Manage Windows PCs from Muxin over OpenSSH, run Muxin itself on Windows, and make Windows VMs. Windows shows up in Muxin three ways: Windows PCs you manage like your other machines, the Muxin app running on a Windows PC, and Windows VMs that Muxin makes on one of your Linux machines. This page covers all three. ## Setting up a Windows PC Muxin reaches a Windows PC over ssh, like any other machine. Windows comes with an ssh server; it just isn’t on yet. 1. On the PC, turn on **OpenSSH Server** in **Settings › System › Optional features**. 2. Start it, and have it start with Windows. In PowerShell as administrator: ``` Start-Service sshd Set-Service -Name sshd -StartupType Automatic ``` 3. Set up key login from this computer, so Muxin can connect without a password. 4. Add it in Muxin (`⌘N`) with its `user@host`, like any machine. > **Note:** For an account in the Administrators group, Windows’ OpenSSH reads keys from `C:\ProgramData\ssh\administrators_authorized_keys`, not the usual `~\.ssh\authorized_keys`. If Muxin says the PC “doesn’t know this Mac yet” after you added your key, that’s the usual reason. Muxin installs its agent in `%USERPROFILE%\.muxen\bin` and works with PowerShell or cmd as sshd’s shell. Use an administrator account if you want to manage services or install runners there. ## What works on a Windows PC - **Agent sessions and terminals** keep running after Muxin closes, like on a Mac or Linux. - **The desktop and the clipboard**: the screen, mouse and keyboard of the account Muxin connects as, while it’s signed in. Muxin starts its helper in that session through a one-off scheduled task, so no window flashes. With nobody signed in, use **Open with Remote Desktop**: see [Desktops](https://muxin.dev/docs/desktops.md#nobody-signed-in). - **Services**: Windows services, where “at boot” is the startup type. Starting and stopping them needs an administrator account. - **Processes** and GPUs. - **Logs**: the System, Application and Security event logs, a service’s events, and log files. See [Logs, services and Docker](https://muxin.dev/docs/logs-services.md). - **Servers**, **Copy files**, **git** and **Usage**. - **Run**: commands on several machines at once run in PowerShell on Windows. - **Workspaces**. Syncing copies through the agent, and doesn’t mirror deletions. - **Schedules** run through Task Scheduler, in a `\Muxen\` folder, so they run even when Muxin isn’t open. See [Schedules](https://muxin.dev/docs/schedules.md). - **Runners** install as Windows services. - **Direct connections**: the agent’s listener runs as a scheduled task at sign-in, with a Windows Firewall rule. See [Connections](https://muxin.dev/docs/connections.md). Checks on a Windows PC also report whether the account has admin rights, Docker, its network card (for Wake on LAN), a pending reboot, and failed services. ## Not on Windows yet - **Docker runners** and **Docker workspaces**. Runners there install as services instead. - **Virtual monitors.** The desktop shows the monitors the PC has. - **VMs on a Windows PC.** Muxin makes VMs on Linux machines and Macs, not on Windows. ## Muxin on Windows Muxin itself runs on Windows 11, on Intel and AMD PCs and on Windows on Arm, with an installer for each. The installer puts it in for your user only, with no administrator needed: - It goes in `%LOCALAPPDATA%\Programs\Muxin`, with a Start menu entry and an uninstaller. - An option adds `muxin` to your PATH, for the [command line](https://muxin.dev/docs/cli.md) and `muxin mcp`. - Started from the Start menu or Explorer, it opens with no console window. From a terminal, `muxin` is the same CLI as everywhere else. - Secrets, like a DigitalOcean token, go in Windows’ Credential Manager instead of the Keychain. - Its config lives in `%APPDATA%\muxin`. Keyboard shortcuts use `Ctrl` where a Mac uses `⌘`, and `Alt` for the pages (`Alt+1` for the overview). ## Windows VMs No Windows PC? Muxin can make a Windows 11, Windows 10, Server 2025 or Server 2022 VM on one of your Linux machines (x86-64, with Docker and KVM). It installs itself in 15 to 30 minutes, turns on OpenSSH with your key, and joins your machines, where everything above works the same. Its account password is kept for you: **Copy password** on its page. ![win-test's page: a Virtual machine on Beacon card with Stop, Copy password, Open Beacon and Destroy, and the sidebar with win-test under Beacon.](https://muxin.dev/images/shots/vm-dark.png?v=ad2b12fa) *win-test, a Windows 11 VM on Beacon.* See [VMs on your machines](https://muxin.dev/docs/vms.md) for making one. Source: https://muxin.dev/docs/windows --- # Agent sessions > Run Claude Code, Codex or a shell on any of your machines, and come back to it whenever you like. An agent session is a terminal on one of your machines running an AI agent or your shell. It lives on that machine, not in the app: close Muxin, sleep your laptop or lose the network, and it keeps working. Open it again and you see its screen as it is now, with its recent scrollback. ![A Claude Code session called Checkout fix on the machine Forge, with the sidebar listing each machine's sessions.](https://muxin.dev/images/shots/session-dark.png?v=71800777) *A Claude Code session on Forge. The sidebar lists each machine’s sessions under it.* > **Tip:** Want someone to watch a session, or type in it? Share it by link. See [Sharing by link](https://muxin.dev/docs/sharing.md). ## The agents Muxin starts any of these, when they’re installed on the machine: - **Claude Code** (`claude`) - **Codex** (`codex`) - **OpenCode** (`opencode`) - **Gemini CLI** (`gemini`) - **Antigravity** (`agy`) - **Amp** (`amp`) - **Pi** (`pi`) - **Copilot CLI** (`copilot`) - **Cursor Agent** (`cursor-agent`) - **Qwen Code** (`qwen`) - **Droid** (`droid`) - **Kimi Code** (`kimi`) - **Shell**: your login shell, for anything else. Muxin finds which ones each machine has. They start in your login shell, in the folder you pick, so nvm, fnm, asdf and each CLI’s own sign-in work as they do in your terminal. ## Start one Click **New session** (`⌘T`), or right-click a machine in the sidebar. Pick: 1. **The machine.** VMs and containers are listed under the machine they run in. **New VM** makes a Linux one for this session; see [VMs on your machines](https://muxin.dev/docs/vms.md). 2. **The agent.** The ones installed there say so. 3. **The folder.** Recent folders and checkouts on that machine are suggested, and you can browse its folders as you type. 4. **Where**, when the folder is a git checkout. **A folder** starts the agent right there. **New worktree** gives it a folder and a branch of its own, in `~/muxen/workspaces`. Use a worktree when you’re working in the checkout yourself, or to run several agents on one repository at once. 5. **A first message** (optional, not for Shell): what the agent should work on. Started from a GitHub issue or pull request, it’s filled in for you. ![The New session dialog: machines, with a container and a VM under the machines they run in, the agents with which are installed, then Where: New worktree or A folder, for the checkout folder.](https://muxin.dev/images/shots/newsession-dark.png?v=ceebb778) *The folder is a git checkout, so Muxin offers a new worktree of it.* A worktree is a workspace, so it shows under **Agents’ workspaces** on the Boxes page too. Deleting it there removes the folder and keeps the branch. See [Workspaces](https://muxin.dev/docs/github.md#workspaces). ## What it changed When a session works in a git checkout, a line under its name shows what the work changed: - **The branch**, marked **worktree** when it is one. - **The lines** added and removed, in how many files, and how many commits, all counted from the default branch. - **Uncommitted** files, if there are any. - **The pull request** for the branch: its number, whether it’s open, a draft or merged, and its checks. Click it to open it. Muxin looks again when the agent stops working, and every minute while it runs. The same line shows on the session’s row in lists and on its workspace. ## Actions The **Actions** button in a session’s header asks the agent to do the usual next step for you. Right-click a session for the same list. ![A Claude Code session’s header: its branch fix-coupon-total, +86 −23 in 4 files, 2 commits, 1 uncommitted, pull request #142 with checks running, and the Actions menu open with Commit, Commit and push, Update pull request #142, Review the changes, Fix the review comments, Resolve conflicts, Write a recap and Edit the prompts.](https://muxin.dev/images/shots/actions-dark.png?v=aeb6c114) *The branch has an open pull request, so the menu offers to update it.* - **Commit**: commit the changes with a clear message, without pushing. - **Commit and push**: the same, then push the branch. - **Open a pull request**: push the branch and open one with the GitHub CLI. Once there is one, this updates its description. - **Review the changes**: review the branch like a careful reviewer would, and list what it finds. It doesn’t change code. - **Fix the review comments**: read the pull request’s comments, fix them, reply to each one and push. - **Resolve conflicts**: bring the branch up to date with the default branch, fix the conflicts and run the tests. - **Write a recap**: what changed, what’s left, and what to check. The menu only lists what makes sense. Outside a checkout, there’s only the recap. On the default branch, there’s no pull request to open. **Fix the review comments** needs an open pull request. Each action types a prompt into the agent, as if you had. The agent still asks before it runs a command you haven’t allowed. Change any prompt in [Settings › Prompts](https://muxin.dev/docs/settings.md#prompts). > **Note:** A worktree keeps its git history in your checkout’s `.git` folder. So an agent with a sandbox, such as Codex, asks before it commits there. ## Hand off to another agent **Hand off**, in a session’s header, gives its work to another agent: on the same machine, or on another one with the work moved there. The new agent starts with a note of what’s been done. See [Hand off and move](https://muxin.dev/docs/handoff.md). ## It keeps running Sessions are kept by Muxin’s agent on the machine (`~/.muxen/bin/muxen-agent`), the way tmux keeps them. Muxin only attaches to them. Closing the app detaches; the session goes on until you end it. On a Mac, the agent is a small app of its own, Muxin Agent, with no window or Dock icon. When a program in a session wants the camera, the microphone, your contacts or another app, the Mac asks you once on its screen, as Muxin Agent, and says it’s for a program in a Muxin session. Your answer covers every session on that Mac. Change it in System Settings › Privacy & Security. ## After a restart Sessions come back when their machine restarts. Muxin’s agent saves each one on the machine as it goes. After a reboot, a crash, or **Restart** from Muxin, the next time Muxin looks at the machine they’re back: the same name, folder and recent scrollback. - **Claude Code, Codex, Copilot CLI, Qwen Code and Kimi Code** continue their conversation, right where it was. Their first task isn’t sent again. - **Other agents** start fresh in the same folder. - **A shell** is a new shell in the same folder. A line in the terminal says it, and the session’s header says **Continued after a restart**. Programs that were running in a shell, like a dev server, don’t start again. A box pauses instead; send it a message to go on. See [Boxes](https://muxin.dev/docs/boxes.md). > **Note:** To have agents start fresh instead, turn off **Continue agents’ conversations after a restart** in **Settings › General › Agents**, on your Mac or your iPad. Sessions still come back. > **Note:** Updated from Muxin 0.9 or earlier? Sessions that were already running keep running, but they aren’t saved yet. A machine starts saving its sessions once the ones open there have all ended, or after it restarts once. From then on, they come back. ## Helpers An agent in a session can start another session to help with its task. Say Claude Code asks Codex to run the tests. Codex starts beside it, on the same machine and in the same folder. - **In the sidebar**, a helper shows under the session that started it. Its header says **Helper of** that session, and the session’s header lists its helpers. - **It ends with it.** When the session that started it ends, so does the helper. An agent can ask to keep one going. - **It waits for the answer.** The agent that started it gets the helper’s answer when it’s done, or its question when it needs someone. Agents start helpers through Muxin’s [MCP tools](https://muxin.dev/docs/agents.md) or [command line](https://muxin.dev/docs/cli.md). They don’t need you to set anything up. > **Note:** To stop agents from starting helpers, turn off **Agents may start helper sessions** in **Settings › General › Agents**, on your Mac or your iPad. Muxin then says no when an agent asks. ## Peek at another session A session’s id in a terminal, like `beacon/codex-3f9a`, is a link. Agents print it when they start a helper. - **On a Mac**, `⌘`-click it (Ctrl-click on Linux and Windows). A small window shows that session live, over the one you’re in. You can keep typing in yours. - **On an iPad**, tap it. A sheet shows its screen, read again every few seconds. A peek only watches. It doesn’t type into the other session or change its size. **Open** goes to it. ## In the sidebar Each machine lists its sessions under it, with what each agent is doing: - **A spinner**: it’s working. - **An amber dot**: it needs you. It asks something, or wants a permission. The dot stays until you answer. - **A purple dot**: it’s done. The dot goes when you open the session. - **A red dot**: it exited with an error. A folded machine shows its most urgent session. Overview and the menu bar show the same across all your machines. A machine with many sessions lists the first five, plus any that need you. Click **more** under them to see the rest. A folded machine still lists what you have open from it, like its desktop or a session, and hides the rest. ### Hiding sessions Right-click a session and pick **Hide**, or click **Hide** on its row on the machine’s page. It leaves the sidebar, the Agents list and the machine’s page, but keeps running. It comes back by itself when it needs you. To find hidden sessions, search the sidebar, or click **hidden** at the bottom of the machine’s list. Pick **Show** to list one again. This works for sessions in Claude’s desktop app too. Under your machines, **Agents** lists every agent session in one place. The ones that need you come first, then the ones working, then the rest. Click one to open it. Shells stay under their machine. To hide the list, turn off **Show agents in the sidebar** in **Settings › General › Agents**. ## Notifications When a session needs you, stops with an error or finishes, your computer shows a notification. Click it to open the session. - It goes away once you open the session. The ones left still wait for you. - The session you’re looking at doesn’t notify. - Turn them off with **Notify me when a session needs me or is done** in **Settings › General › Menu bar** (**Tray** on Windows and Linux). On a Mac, **System Settings › Notifications › Muxin** sets how they look. The menu bar menu lists the same sessions, each with its agent’s logo. Click one to open it. ## Claude’s desktop app If you use Claude Code in Claude’s desktop app, Muxin lists those sessions too, beside its own. They have their titles from Claude. They show working, needs you or done, and they notify like the rest. - **Click one** to open it in Claude. On another machine, Muxin opens it in Claude there and shows that machine’s desktop. - **Right-click one** for **Open in Claude**, or to open its folder in your editor. - A finished one you’ve looked at in Claude isn’t new anymore. One you archive in Claude goes away. - Muxin’s hooks need to be on: **Settings › General › Agents**, on unless you turn it off. Not on Windows yet. ## How Muxin knows Claude Code, Codex, Copilot CLI, Qwen Code and Kimi Code tell Muxin what they’re doing. Muxin adds a small hook to their settings on each machine. It does nothing outside a Muxin session, except in [Claude’s desktop app](#claude-desktop), and it can’t break the agent. Other tools’ hooks stay as they are. Other agents are read from their output and their screen. Muxin knows how their questions look, and checks muxin.dev once a day for newer ways they draw them. Any program can say it too, with this escape code: `printf '\e]7501;state=blocked\e\\'`. The states are `working`, `blocked`, `done` and `idle`. `clear` goes back to guessing. > **Note:** To take the hooks out, turn off **Settings › General › Agents**, on your Mac or your iPad. Each machine keeps the newest choice. ## The terminal - Everything you type goes to the agent: Esc, Ctrl-C, Tab, the arrows, and Option- or Shift-Enter for a new line. `⌘C` copies a selection and `⌘V` pastes. - On a Mac, Option types what your keyboard puts on it when the layout needs that, like `@` on a German keyboard. On layouts that don’t, like US, Option stays Meta. - `⌘D` splits the terminal to the right and `⇧⌘D` below it: a new shell on the same machine, in the same folder. `⌥⌘←` and `⌥⌘→` move between panes. `⇧⌘↵` shows one pane alone (again for the whole split), and `⇧⌘W` closes it. Each pane is a session of its own, and splits come back when you reopen Muxin. - On a slow network, the terminal you’re typing in goes first, and a hidden one that keeps printing is let go until you open it again. See [On a slow network](https://muxin.dev/docs/connections.md#slow-networks). - **Desktop** in a session’s header shows the machine’s screen beside the terminal, to check what the agent did. See [Desktops](https://muxin.dev/docs/desktops.md). ## Open in your editor The `` button in a session’s header lists the editors on this computer (Zed, Cursor, VS Code) and opens the session’s folder in the one you pick, over ssh. The one you choose in **Settings › General › Editor** comes first. From a terminal, `muxin edit beacon:~/code/api` does the same. ## Rename, restart, end - **Rename**: right-click the session. The name is kept on the machine, so every Muxin that looks at it sees it. - **Restart** starts an exited session again, in the same folder. The agents that continue after a restart continue their conversation here too, as [after a restart](#restart). - **End** stops it for good. ## On Windows On a Windows PC a session runs in PowerShell (PowerShell 7 when it’s installed) and keeps running there like anywhere else. See [Windows](https://muxin.dev/docs/windows.md). ## From a terminal and from other agents Your AI agents can start sessions, read their screens, see what an agent is asking and answer it. The MCP tools are `session_start`, `session_read`, `session_wait`, `session_question`, `session_answer`, `session_send`, `session_action`, `session_handoff` and `session_stop`; `session_list` includes what each session changed. The CLI has the same: ``` muxin session start beacon claude --cwd ~/code/api --prompt "fix the failing test" muxin session read beacon/claude-3f9a # what’s on its screen muxin session wait beacon/claude-3f9a # until it’s done or needs you; what it said muxin session question beacon/claude-3f9a # what it’s asking, and the options muxin session answer beacon/claude-3f9a 1 # pick one muxin session do beacon/claude-3f9a pull_request # an action: commit, review, recap, … muxin session attach beacon/claude-3f9a # open it in this terminal muxin session handoff beacon/claude-3f9a codex # Codex takes over ``` From inside a session, an agent leaves out the machine to start a [helper](#helpers) beside it: ``` muxin session start codex --prompt "run the tests and list what fails" muxin session wait beacon/codex-8k2p # its answer ``` See [MCP for your agents](https://muxin.dev/docs/agents.md) and [The command line](https://muxin.dev/docs/cli.md). Source: https://muxin.dev/docs/sessions --- # Boxes > Hand a task to an agent. It works on it by itself, in a container of its own on one of your machines. A box is one task for an agent. Muxin makes a fresh checkout of your repository on a new branch, in a Docker container on one of your machines, and starts the agent on the task. The agent works by itself, with its permission prompts off: the container is its sandbox. When it’s done, it can push its branch and open a pull request. ![The Boxes page: Add rate limit headers, working with Claude Code on Beacon, and Fix flaky webhook retry test, paused, with Codex. Each shows its task, branch, changes and pull request. Below them, the agents’ workspaces.](https://muxin.dev/images/shots/boxes-dark.png?v=3e618d4f) *One box is working and one is paused. Agents’ workspaces are listed below them.* > **Tip:** A box or a session? Use a [session](https://muxin.dev/docs/sessions.md) to work with an agent. Use a box to hand it a task and come back later. ## Start one Open **Boxes** (`⌃3`) and click **New box**. Then pick: 1. **The code.** A GitHub repository (type to search yours), or a folder on a machine. A folder’s box starts from the checkout as it is, uncommitted changes included, and your checkout isn’t touched. 2. **The task.** What the agent should do. Ask it to open a pull request when it’s done. 3. **The agent.** Claude Code, Codex, Amp, OpenCode, Gemini CLI or Pi. 4. **Where it runs.** **Best one** picks the online machine with Docker and the most free memory. ![The New box dialog filled in from an issue: the repository acme/api, the task to fix the GitHub issue and open a pull request that closes it, Claude Code picked as the agent, and Best one as the machine.](https://muxin.dev/images/shots/boxdlg-dark.png?v=efaebb18) *New box, filled in from a GitHub issue.* The first box on a machine builds Muxin’s box image there, which takes a few minutes. Later boxes start in seconds. If the repository has an `.agents/setup` script, it runs first. ## From a GitHub issue Every issue has **Hand off in a box**. It opens New box filled in: the repository, a task to fix the issue and open a pull request that closes it, and a branch named for the issue. The issue’s title and description go to the agent too. ![The issue Coupon total is wrong after tax, number 412 in acme/api, with the buttons Work on it with an agent, Hand off in a box, Open on GitHub and Copy link.](https://muxin.dev/images/shots/issue-dark.png?v=317737ab) *Work on it with an agent opens a session. Hand off in a box gives the issue to a box.* 1. **Pick an issue**: Click **Hand off in a box**, then **Start**. 2. **A box starts**: A fresh clone, on a branch like `issue-412-coupon-total-wrong-after`. 3. **The agent works**: By itself, with the issue as its task. 4. **A pull request**: One that closes the issue. Review it on GitHub. ## Watch it Click **Open** to see the agent’s terminal, like any session. Type in it to ask more. `⌘D` opens a shell in the box beside it, with the same checkout and tools. ![A box’s agent: Claude Code working on Add rate limit headers, marked Box, in a container on Beacon, with Actions, Hand off and Pause in its header.](https://muxin.dev/images/shots/boxsession-dark.png?v=146a66c9) *A box’s agent. Pause stops the box; its files and conversation stay.* The Boxes page shows each box working, needing you, done or paused, with its branch, what it changed and its pull request. ## It pauses by itself When the agent has printed nothing for 15 minutes, or has quit, the box stops. Its files, branch and conversation stay. Ask it something more, or click **Resume**, and it picks up where it left off. This works with Muxin closed. Muxin’s agent on the machine does it. ## Already signed in A box uses the machine’s own sign-ins. If the agent is signed in on that machine, it’s signed in in the box, with your settings and MCP servers. If not, sign in once from a box’s terminal (`/login`). Every box on that machine has it from then on. > **Note:** On a Mac, Claude Code keeps its sign-in in the Keychain, which a container can’t read. Sign in once from a box’s terminal there. ## Change its agent On a box’s page, **Hand off** gives the task to another agent in the same box, with a note of the work so far. See [Hand off and move](https://muxin.dev/docs/handoff.md). ## Where it lives A box is a folder on its machine, `~/muxen/boxes/`: its checkout and the agent’s home. **Delete** removes the folder and the container, with any work that wasn’t pushed. Its branch on GitHub stays. > **Warning:** The agent works as you, with your GitHub login, and its network isn’t closed off. Give boxes tasks for code you trust. ## Machines that run boxes Linux machines, and Macs with Docker Desktop, OrbStack or Colima. Not Windows yet. ## Agents’ workspaces Below the boxes, the Boxes page lists agents’ workspaces: folders on your machines that AI tools you use elsewhere work in through Muxin. See [Workspaces](https://muxin.dev/docs/github.md#workspaces). ## From a terminal and from other agents Your AI agents can start boxes too. The MCP tools are `box_create`, `box_list`, `box_send`, `box_pause` and `box_destroy`. The CLI has the same: ``` muxin box new acme/api "Add rate limit headers, with tests, and open a pull request" muxin box new ~/code/app "Finish this refactor" --on beacon --agent codex muxin box ls # each box, and what it changed muxin box send box-7k2m9q "Also update the docs" # starts it again if it's paused muxin box attach box-7k2m9q # its agent, in this terminal muxin box shell box-7k2m9q # a shell in the box muxin box pause box-7k2m9q muxin box rm box-7k2m9q ``` See [MCP for your agents](https://muxin.dev/docs/agents.md) and [The command line](https://muxin.dev/docs/cli.md). Source: https://muxin.dev/docs/boxes --- # Hand off and move > Give a session’s work to another agent, or move it to another machine, with what’s been done so far. Started with Claude Code and want Codex to finish? Ran out of usage halfway? Want the work to keep going on a server? **Hand off** gives a session’s work to another agent, on the same machine or another one. The new agent starts with a note of what’s been done. ![The Hand off menu on the session Checkout fix: Hand off to Codex, Hand off to OpenCode, A fresh Claude Code session, and Move to Orbit, Beacon and the other machines.](https://muxin.dev/images/shots/handoff-dark.png?v=a4864fba) *Hand off to another agent here, start fresh with the same one, or move to another machine.* ## Hand off to another agent On a session’s page, click **Hand off** and pick an agent. 1. **A note**: Muxin writes `.muxin/handoff.md` in the session’s folder. 2. **The new agent starts**: In the same folder, asked to read the note first. 3. **The old one ends**: Once the new one is up. **A fresh … session** does the same with the same agent. Use it when a conversation has grown too long. ## What the note has - **Where the work stands:** the git status, the branch’s commits and what changed. - **The agent’s to-do list**, when it kept one. - **The conversation so far:** what you asked, what the agent said, and a line for each tool call. Muxin reads the conversation from the agent’s own transcript on the machine. So it works even when the agent ran out of usage or quit. Claude Code, Codex, Gemini CLI and Pi keep a transcript. For OpenCode and Amp, the note has what the terminal showed instead. The note stays out of git: `.muxin/` goes in the checkout’s own ignore list. ## Move to another machine **Hand off › Move to …** moves the work first, then hands it off there. Pick the agent on that machine and click **Move**. ![The Move to Orbit dialog: Claude Code or Codex as the agent, the branch fix-coupon-total with an uncommitted file going along, a fresh clone of acme/shop on Orbit, and a box to keep the session running on Forge too.](https://muxin.dev/images/shots/movedlg-dark.png?v=2b35c8a2) *Moving Checkout fix from Forge to Orbit.* 1. **Packs the work**: Commits that aren’t on GitHub yet, uncommitted changes and new files. 2. **Copies it**: Through Muxin. The machines don’t need to reach each other. 3. **A new folder**: A worktree of your checkout there, or a fresh clone, on the same branch. 4. **The agent starts**: There, with the note. - The folder you left stays as it was. - A branch there with other commits isn’t touched. The work goes on `-2`. - Work on the default branch gets a branch of its own, like `muxin/claude-7f3a`. - The new folder shows under **Boxes › Agents’ workspaces**. Delete it there when you’re done, after pushing anything worth keeping. > **Note:** Only git checkouts move, and not to Windows machines yet. ## In a box A [box](https://muxin.dev/docs/boxes.md) changes agents in place. Its container and checkout stay, and the new agent starts there with the note. A box stays on its machine. ## Good to know - The new agent may ask to trust the folder the first time. Answer it in the terminal. - **Keep this session running** leaves the old session going too. - Only what you asked counts as a request. The note tells the new agent so. ## From a terminal and from other agents The MCP tool is `session_handoff`. The CLI: ``` muxin session handoff forge/claude-7f3a codex # Codex takes over here muxin session handoff forge/claude-7f3a codex --on orbit # the work moves to Orbit muxin session handoff forge/claude-7f3a claude --keep # a fresh Claude Code, the old one kept muxin session handoff box-7k2m9q codex # a box changes agents ``` Source: https://muxin.dev/docs/handoff --- # Sharing by link > Show someone a session or a whole machine. They join from a browser or Muxin, straight to your computer, and do only what you allow. Need a second pair of eyes on what an agent is doing? Share it. Muxin makes a link for a session, or for a whole machine. Whoever opens it joins from a browser or from Muxin, and connects straight to your computer. You let each person in, and you decide what they can do. *Sharing Beelink: Sam opens the link, you let them in, they watch, then type, then look at the desktop.* ## Share a session On a session’s page, click **Share**. The link is made and copied, ready to paste into a chat. It looks like `https://muxin.dev/s#1.…`. Out of the box, you let each person in, they can only watch, and the share lasts an hour. Change any of that in the same window, while it runs: - **Ask me before letting someone in.** On by default. Turn it off and anyone with the link can watch. - **They can type.** Their keys go to the session, as you. Only for people you let in. - **How long.** 15 minutes, an hour, 8 hours or a day. ## Share a machine On a machine’s page, **Share** does the same for the whole machine. Guests see its sessions, including ones started later, and open any of them. In the same window you can also share: - **Its desktop.** **View** shows them the screen. **Control** lets the people you choose use its mouse and keyboard. - **Its servers.** Pick which of the web servers running there they can open. They open in Muxin, at `localhost` on their computer. - **Starting and ending sessions.** Off by default. Turned on, the people you let in who can type can start a terminal or an agent there, and end or restart sessions. Nothing else is shared: no files, no other ports, no shell of its own. > **Warning:** A terminal runs anything, as you. Let someone start sessions, or type in a shell, only if you’d hand them your keyboard. ## Let people in When someone opens the link, a card shows over whatever page you’re on: their name, whether they’re in a browser or in Muxin, and a 6-digit code. They see the same code. Ask them to read it out, then click **Let in**, or **Deny**. A link that leaked gets someone a code nobody reads to you, so it gets them nowhere. ## While you share The **Share** button turns into **Shared · Sam watching**, or how many are there. Click it to: - Let someone type, use the desktop, or start and end sessions, or stop them. - Remove someone. - Copy the link, add an hour, or change the options. - **Stop sharing.** A shared session has an eye next to it in the sidebar. A dot means someone is waiting to be let in. ## Join a share **In a browser.** Open the link, type your name, and click **Join**. Nothing to install. You see the sessions, and the desktop when it’s shared. Pick its quality under it: Low, Medium, High or Max. **On a phone or tablet.** The same link, in its browser. The page fits the screen: one header row, the session below it. On a tablet a session’s text fits its width; on a phone it’s as wide as it can be read, and you swipe sideways for the rest (or turn the phone). On a shared desktop you’re let use, touch works like a mouse: - **Tap** to click, **touch and hold** to right-click. - **Drag** with one finger to drag (select text, move a window). - **Two fingers** up or down to scroll. - **Keyboard**, under the screen, brings up your keyboard: what you type goes to their screen. While you’re only watching, touch scrolls and zooms the page as usual. **In Muxin.** Click **+** next to **Shared with you** in the sidebar and paste the link. **Machines › Join a Share…** in the menu bar and `⇧⌘P` › **Join a share…** do the same, and a share link pasted into **Add a machine** is joined too. A shared machine then sits in your sidebar like one of your own, its sessions, desktop and servers under it. Right-click any of them for what you can do there: open a session, start a terminal or an agent, end one, set the desktop’s quality, open a server here, or leave. What you aren’t allowed to do shows dimmed, with who to ask. Sessions show at the size the sharer’s terminal is. Your window doesn’t resize theirs. ## Peer to peer 1. **The link**: It carries the share’s secret after the #. Browsers never send that part to a server. 2. **muxin.dev introduces you**: Two short messages so the two computers can find each other. It never sees the secret or what’s shared. 3. **Straight to your computer**: An encrypted connection (WebRTC), checked against the certificate in the link, so nobody can sit in the middle. *An encrypted relay carries it only when no direct path works.* The two computers connect directly: over your network or Tailscale when they share one, across the internet otherwise. ## How it stays secure - **The secret stays in the link.** It’s after the `#`, the part browsers never send to a server. muxin.dev only passes two messages between the computers, and never sees the secret, the session or the screen. - **Encrypted end to end.** The connection is encrypted between the two computers (WebRTC, DTLS). When a relay carries it, the relay only forwards bytes it can’t read. - **Nobody can sit in the middle.** The link names your computer’s certificate for this share. A guest refuses any other, so not even the server introducing them can stand in. - **Proof of the link.** A guest proves it has the secret, bound to this exact connection. A wrong or copied proof gets nowhere, and a share that sees many wrong ones stops answering. - **You let each person in.** You both see the same 6-digit code, made from the secret and their connection. Ask them to read it out before you click **Let in**. - **Your computer decides what gets through.** Guests never reach the machine itself. Muxin on your computer passes only what you allow: keys while you let them type, the mouse while you let them use the desktop, the servers you picked. The machine’s agent also gives watchers a view that can’t type or resize. - **It doesn’t last.** A share ends when its time runs out, when you stop it, or when you close or quit Muxin, and its link never works again. Every link is new: sharing again makes a new one. - **Nothing to sign up for, nothing kept.** No accounts. The only cookie is Cloudflare’s, which tells people from bots. muxin.dev keeps the two messages only for the minutes it takes to connect. > **Warning:** Anyone you let type, use the desktop or start sessions acts as you on that machine. Give those only to people you trust with your keyboard. ## When it ends A share ends when its time runs out, when you click **Stop sharing**, or when you close or quit Muxin. Everyone is let go and the link stops working for good. > **Note:** Your computer hosts the share, so Muxin needs to be open and your computer awake while it lasts. ## Your own server To introduce the two sides through a server of your own instead of muxin.dev, run `share-server/` from Muxin’s repository and add it to `config.toml`: ``` [settings.share] server = "https://share.example.com" ``` Source: https://muxin.dev/docs/sharing --- # Desktops > See a machine’s screen live, next to its terminal, and use its mouse and keyboard. **Show desktop** on a machine’s page (or its right-click menu) shows its screen live and sends your mouse and keyboard to it. An open desktop is listed under its machine in the sidebar and keeps streaming while you look elsewhere; close it there. ![A terminal on Beacon running a Vite dev server, and beside it Beacon's live screen with Chrome showing the app.](https://muxin.dev/images/shots/desktop-dark.png?v=0c6dc847) *A dev server running in a session on a Linux machine, and that machine’s screen beside it, showing the app in Chrome.* ## Which machines - **A Mac.** The first time, the Mac asks, on its own screen, to allow **Muxin Agent** under Privacy & Security › Screen Recording (to see it) and Accessibility (to control it). Muxin 0.9 and earlier asked for `muxen-agent`, so after updating, the Mac may ask again. See [Troubleshooting](https://muxin.dev/docs/troubleshooting.md#mac-permissions). - **Linux** with an X11 desktop. Wayland-only desktops can’t be shown yet. - **Windows**, while the account Muxin connects as is signed in to it. See [Windows](https://muxin.dev/docs/windows.md). On Windows and Linux, `⌘` works as Ctrl; on a Mac it stays `⌘`. See [Your keyboard](#keyboard). ## When nobody is signed in Muxin shows the screen of the account it connects as, so that account has to be signed in. Servers often have nobody signed in. A Remote Desktop window closed without signing out leaves no screen either. Muxin says so right away. Then it offers the machine’s own remote desktop, which shows the sign-in screen: - **Open with Remote Desktop** on Windows. It opens in Windows App on a Mac, or Remote Desktop Connection on Windows. - **Open with Screen Sharing** on a Mac. - **Open with RDP or VNC** on Linux, in Remmina or FreeRDP. It’s in the machine’s right-click menu too. It goes through Muxin’s connection to the machine, so it works away from home. Nothing has to be opened in a firewall. On your computer it’s at `localhost:3390` (VNC: `localhost:5901`), listed under Servers. The machine needs it turned on. When it’s off, Muxin says where: - **Windows:** Settings › System › Remote Desktop, or Server Manager › Local Server on Windows Server. Windows Home can’t be reached this way. - **Mac:** System Settings › General › Sharing › Screen Sharing. - **Linux:** xrdp, GNOME’s Remote Desktop, or a VNC server such as x11vnc. From a terminal: ``` muxin desktop rdp beacon # Remote Desktop muxin desktop vnc beacon # VNC, or Screen Sharing on a Mac ``` ## Apps in windows of their own **Apps** above a machine’s desktop lists the apps open there. Pick one, and it opens on your computer in a window of its own, as if it ran here. It works with Windows, Macs, and Linux on X11. - Nothing of Muxin’s goes around it. Drag the app’s own title bar to move the window, and double-click it to zoom. - Click and type as usual. The app comes to the front there first, so your keys never land in another app. - Resize either window and the other follows. When you close it here, the app goes back to its size there. - The pointer takes the app’s shapes: a text cursor over text, a hand over links. - Text stays sharp. Once the picture is still, it’s sent again at full quality. Close it with `⌘W` on a Mac, or `Ctrl+Shift+W` on Windows and Linux. The app keeps running there. If you quit the app there, its window here closes too. > **Tip:** It works even while other windows cover the app there. When nothing covers it, its menus and dialogs show too. ## Beside a session In an agent session, **Desktop** in its header puts the machine’s screen next to the terminal. Drag the divider to resize. It’s the quickest way to check what an agent did in a browser or an app without leaving it. ## Show it to someone Share the machine by link and turn its desktop on: they watch the screen from a browser or Muxin, and use it only if you let them. See [Sharing by link](https://muxin.dev/docs/sharing.md#machine). ## Size and sharpness Pick 720p, 1080p, 1440p, 4K or Native from the bar above the screen. On your local network it starts at the screen’s own size, further away at 1080p. Only the parts of the screen that change are sent, so a still screen costs nothing. On Macs and Linux you can also change the monitor itself: right-click it in the sidebar and point at **Resolution** for its sizes, with a check by the one it has. On Linux desktops that offer it, you can change its scale too. At 200% a 4K monitor reads like 1080p and stays sharp. The size the monitor had before you changed it stays in the bar, so you can always go back. **Open in window** gives the desktop a window of its own. ## More monitors, real and virtual A machine with several monitors gets a picker above its desktop. On Macs and Linux, **Add monitor** plugs in a virtual one: pick a name and a size, and it joins the desktop to the right of the others, as if you’d plugged in a screen. Windows move onto it and the machine’s own settings see it. - Handy on a machine with no screen, or to give an agent a monitor of its own. - It stays until you remove it or the machine restarts. - On Linux it takes root: when sudo wants your password, Muxin asks for it, keeps it in memory only, and sends it over its encrypted connection. ## Your keyboard Keys type what your keyboard puts on them, even when the machine uses another layout. Shortcuts stay shortcuts. - **From a Mac**: Option types its characters, like `@` on a German keyboard. Alt goes through when something needs it, like Alt+Tab. - **To a Mac**: keys go by that Mac’s own layout, so it doesn’t have to be US. - **From a Mac to Windows or Linux**: `⌘` works as Ctrl, so `⌘C` copies there. `⌘Tab` is Alt+Tab, `⌘Q` is Alt+F4, and `⌘Space` is the Windows key. - **From Windows or Linux to a Mac**: the Windows key is `⌘`. Alt+Tab is `⌘Tab`, and Alt+F4 is `⌘Q`. ## Your computer’s own shortcuts Your computer keeps some shortcuts for itself: `⌘Tab` and Mission Control on a Mac, Alt+Tab and the Windows key on Windows, the window manager’s on Linux. While a machine’s desktop has the keyboard, Muxin sends them to the machine instead. Muxin’s own shortcuts go there too, like `⌘W`. - The bar above the screen has a switch for it. It says **Send ⌘Tab to Beacon** (with your machine’s name) while they’re yours, and **⌘Tab goes to Beacon** while they go there. Click it to change that. On Windows and Linux it says Alt+Tab. - Press `Ctrl+Alt` by themselves (`⌃⌥` on a Mac) to get them back. Press them again to send them to the machine again. - They’re yours again when you click outside the desktop or switch apps. - **Settings › General › Desktops** turns it off. > **Warning:** On a Mac, Muxin needs your OK first. Click the switch and macOS asks to allow Muxin under **Privacy & Security › Accessibility**. On Linux with Wayland, your desktop may ask too. It’s for a machine’s whole desktop, not for an app in a window of its own. And no program can take Ctrl+Alt+Del or Win+L on Windows, or `⌘⌥Esc` on a Mac. ## Send a shortcut with a click **Keys** in the bar above the screen sends a combination for you. It’s there for the ones your keyboard can’t send. - **A Mac**: previous and next Space, Mission Control, an app’s windows, the app switcher, Spotlight and Force Quit. - **Windows**: Start, the window switcher, Task view, Show desktop, Task Manager and Close window. Windows takes Ctrl+Alt+Del and Win+L from its own keyboard only. - **Linux**: Super, the window switcher, Close window and Ctrl+Alt+Del. ## The clipboard Text you copy on your Mac can be pasted on a Linux or Mac desktop, and what you copy there comes back. It’s off until you turn it on, in **Settings › General › Clipboard**. Passwords copied from a password manager aren’t shared. See [Files and the clipboard](https://muxin.dev/docs/files.md). ## Making it smooth A desktop works over ssh, but it’s smoother with a [direct connection](https://muxin.dev/docs/connections.md). The bar above the screen says how it travels: direct or over ssh, and on which network (your local network, Tailscale or the internet). > **Tip:** On your local network, pair the machine (**Connect directly** on its page). Away from home, Tailscale’s peer-to-peer path is faster than its relay; the Connection card says which one you’re on. ## For your agents Agents can look at a screen and use it too: `desktop_screenshot` returns an image, and `desktop_input` clicks, types and scrolls, in that image’s pixels. It’s the real screen, so they should only do it when you ask. A key can be one of the machine’s own shortcuts: `ctrl+right` goes to a Mac’s next Space, and `super` opens Start on Windows. `desktop_windows` lists the apps’ windows. Pass `window:` as the display to see and use just one, even while it’s covered. ``` muxin desktop shot beacon -o screen.jpg muxin desktop windows beacon # its apps' windows muxin desktop shot beacon --display window:58720260 muxin desktop input beacon '[{"type":"click","x":100,"y":200},{"type":"text","text":"hello"}]' muxin desktop add beacon --size 2560x1440 # a virtual monitor ``` Source: https://muxin.dev/docs/desktops --- # Servers and ports > See what’s listening on a machine, and open its web servers at localhost on your computer. A dev server running on another machine is usually a pain to look at: it listens on `localhost` there, and you’re here. Muxin lists what each machine is serving and puts any of it at `localhost` on your computer with one click. No desktop, no ssh tunnel to remember, nothing opened on the network. ![Beacon's page: its Servers list with a Vite dev server on port 5173 open at localhost:5173, a noVNC container and a shop app, and 8 other ports folded away.](https://muxin.dev/images/shots/servers-dark.png?v=643a32f5) *The dev server on port 5173 runs only on Beacon. Here it’s open at localhost:5173, and listed under Beacon in the sidebar.* ## What’s listening The **Servers** section on a machine’s page lists every port something listens on there. - **Web servers come first**, with the title of the page they serve (a dev server, a Docker container’s site), the program or container behind them, and their HTTP status. With more than five, the list shows the first five. **Show more** opens the rest, with the other ports. - **Everything else** is folded under “N other ports”: databases, system services, apps’ helpers. - “Only on Beacon itself” means the server listens on the machine’s own `localhost`. You can still open it from here. The list is read again while the page is open, and the refresh button next to it asks right away. ## Open one here **Open** on a web server puts it on your computer at `localhost`, on the same port number when that’s free here, and opens it in your browser. Other ports have **Forward** instead: the same, without the browser, for a database client or an API tool. 1. **localhost:5173 here**: Your browser connects to a port Muxin listens on, on your computer only. 2. **The machine’s connection**: Muxin carries it over the live connection it already has to that machine, ssh or direct. 3. **Port 5173 there**: The machine’s agent connects to the server, as if you were on the machine. *Nothing is opened to the network on either side.* Because it goes through Muxin’s own connection to the machine, it works the same over ssh, over a direct connection, at home or through Tailscale. ## Open ports in the sidebar - An open port is listed under its machine in the sidebar, as `localhost:5173`. Click it to open it in your browser again. - **×** next to it (or **Close** on the machine’s page) stops it here. The server on the machine keeps running. - Open ports come back when Muxin starts. - When the server on the machine stops, Muxin closes it here and tells you. ## Any port Something not in the list yet, say a server you’re about to start? Type its number into **Open a port** above the list and press Return. > **Tip:** Looking at it in a browser on the machine itself instead? That’s what [Desktops](https://muxin.dev/docs/desktops.md) are for. For a web app you’re building, opening it here is usually quicker and sharper. ## Let someone else open it Share the machine by link and pick the server: whoever you let in opens it in Muxin, at `localhost` on their computer. See [Sharing by link](https://muxin.dev/docs/sharing.md#machine). ## On Windows Windows’ own web server holds a few ports for its services (device discovery on 5357, remote management on 5985) and answers anything else with an error page. Muxin doesn’t list those as servers. ## From a terminal and from agents ``` muxin ports beacon # what’s listening there, web servers first muxin forward beacon 3000 # its port 3000 at localhost:3000 here, until Ctrl-C ``` Agents get the same list with `machine_ports`. To check a server from the machine itself, they can run `curl -sS localhost:3000` there with `workspace_exec`. See [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/servers --- # Logs, services and Docker > Read a machine’s logs live, and start, stop and restart its services, Docker containers and Compose projects. When something on a machine isn’t right, you usually want two things: its logs, and a way to restart it. Both are on the machine’s page, as **Logs** and **Services** (also in its right-click menu, and in `⌘P`). Each stays under the machine in the sidebar until you close it. ## Logs **Logs** lists what the machine has to read: - **System:** the systemd journal and the kernel’s messages on Linux, the unified log on a Mac, the event logs on Windows. On Linux, without the `systemd-journal` group you see only your own entries; Muxin says so. - **Files:** `/var/log`, `~/Library/Logs`, and log files written lately under your home folder (an app’s `storage/logs`, a runner’s `_diag`), newest first. Or type any path. Root-only files are marked. - **Docker containers** and running **services**, yours and the system’s. Pick one and you get its last 500 lines, then new ones as they’re written. - **Filter** shows only the lines with what you type. - **Pause** holds the view and counts what’s arrived meanwhile. **Follow** keeps the newest line in view; scrolling up stops it. - **Copy** takes the selection (`⌘C`), or every line shown. - Errors are red and warnings amber. ![A Compose project's logs on Beacon: lines from db, cache, web and api, each service in its own color, with chips to show one service, a filter, Pause and Follow.](https://muxin.dev/images/shots/logs-dark.png?v=66732c07) *A Compose project’s logs: every service’s lines in time order.* ## Services **Services** lists the machine’s services, failed ones first, then running ones. **Find** narrows the list. - **Linux:** systemd services, the system’s and your own (“yours”). **Start**, **Stop**, **Restart**, and **At boot** to change whether it starts with the machine. - **A Mac:** Homebrew’s services (`brew services`: Postgres, Redis, nginx and so on). - **Windows:** its services. - Each running service shows its CPU (percent of one core) and memory. Sort by them to find what’s busy. > **Note:** The system’s services need root. When sudo wants your password, Muxin asks for it in the app, once, keeps it in memory only and forgets it when you quit. > **Warning:** Stop, Restart, Remove and Down ask first. They say so when the thing you’re stopping (ssh, Tailscale, the network) could cut Muxin off from the machine. ## Docker On a machine with Docker, the **Containers**, **Compose** and **Images** tabs cover the rest. - **Containers:** **Run a container** (image, name, ports, environment, volumes, restart policy, command), then start, stop, restart or remove one, open a shell inside it (a terminal session), or read its log. - **Images:** **Pull** one, run it, remove it, or **Remove unused**. - Pulls, runs and Compose up and down run as operations: their output shows as it comes, and in Activity (`⌘J`). ## Compose projects The **Compose** tab lists each project Docker knows, with **Up**, **Down**, **Restart**, **Pull**, its log, and **Edit** (its compose file in your editor). **New project** makes `~/compose//compose.yaml` to start from. Click a project to see it three ways: - **Picture:** its services as boxes, with each one’s image, state, health, CPU and memory. An arrow points to what a service waits for, green when it waits until that’s healthy. Ports it opens on the machine, its networks as colored tags, the files it mounts, and its volumes at the right. - **List:** the same as a table, with Start, Stop and Restart for each service, then its volumes, mounted files and networks. - **Logs:** every service’s lines in time order, each in its color, with a chip to show one service’s. ![The Picture of a shop’s Compose project: web, api, worker, db and cache as boxes, arrows to what each waits for, and the db-data and cache-data volumes.](https://muxin.dev/images/shots/compose-dark.png?v=fa65a711) *What waits for what, and what’s healthy, at a glance.* ## Processes The **Processes** tab lists the machine’s busiest few hundred processes: CPU (percent of one core), memory, how long each has run, and who runs it. **Stop** sends SIGTERM and **Kill** SIGKILL; both ask first. Another user’s process needs root, as system services do. GPUs show above the list, with how busy each is and how much memory it uses: NVIDIA, AMD on Linux, and Apple’s. ## From a terminal ``` muxin logs beacon --list # what there is muxin logs beacon --unit nginx -n 100 # a service’s last lines muxin logs beacon --file '~/app/storage/logs/laravel.log' --grep error muxin logs beacon --container postgres --follow # keep printing (Ctrl-C to stop) muxin services beacon # services and containers muxin services beacon restart nginx muxin services beacon stop postgres --container muxin ps beacon # its busiest processes and its GPUs muxin kill beacon 4242 [--force] # --force: SIGKILL ``` Agents have the same through MCP (`logs_read`, `machine_services`, `service_action`, `compose_project`, `machine_processes` and more). They’re told to read a failing service’s log before suggesting a fix, and to change things only when you ask. See [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/logs-services --- # Files and the clipboard > Copy files and folders between any two of your machines, and share the clipboard with their desktops. Moving a build from one machine to another usually means `scp` through a third, or setting up keys so the two can talk. In Muxin the two machines don’t need to reach each other at all: the files go through Muxin, which already talks to both. ## Copy files **Files** on a machine’s page (or **Copy files…** in its right-click menu) opens two panes: where the files are on the left, where they go on the right. Each is a folder you can browse. 1. Pick the machine and folder to copy from, and tick the files and folders you want. **Hidden files** shows the dotfiles. 2. Pick the machine and folder to copy into. The arrow between the panes swaps them, to copy the other way. 3. Click **Copy to …**. ![The Copy files dialog: a docs folder and README.md picked in ~/code/checkout on Forge, to be copied into the home folder on Beacon.](https://muxin.dev/images/shots/copy-dark.png?v=8b63c27e) *Two files picked on Forge, going to Beacon’s home folder.* The copy runs in the background. Its progress, speed and **Stop** are in Activity (`⌘J`). ## How it travels - The files go as one stream from the agent on the first machine, through Muxin, to the agent on the second. The machines never need to reach each other or share ssh keys. - Folders come whole, with their permissions and links. - Both ends hold back to what the other can take, so a slow machine doesn’t pile data up anywhere. - Your Mac is a machine like the others, so the same dialog uploads and downloads. > **Warning:** Files with the same names in the destination folder are replaced. The dialog says how many before you copy. ## Drop from the Finder Drag files from the Finder onto a machine in the sidebar. The Copy files dialog opens with them picked, ready to send to that machine; choose the folder and copy. ## The shared clipboard Text you copy on your Mac can be pasted on your machines’ desktops (Linux and other Macs), and what you copy there lands on your Mac and on the other machines. - It’s off until you turn it on, in **Settings › General › Clipboard**. - It works for machines with a desktop that Muxin is connected to. Settings shows which ones are sharing right now. - Passwords copied from a password manager (marked private on the clipboard) aren’t shared. > **Tip:** The clipboard is for text you’re typing between screens. To move files, use Copy files. ## From a terminal and from agents ``` muxin files beacon:~/build # what’s in a folder muxin cp beacon:~/build/app.tar.gz forge:~/Downloads muxin cp forge:~/Projects/site beacon:~/www --no-wait ``` Agents use `list_files` and `copy_files`. They’re told to list the destination first and to ask you before replacing anything. See [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/files --- # Run a command everywhere > One command on several machines at once, with each one’s output side by side. Check the disks on every machine, update Homebrew on all your Macs, pull the same repo everywhere: **Run** (`⌃6`) runs one command on the machines you pick, at the same time, and shows each one’s output as it comes. ![The Run page: df -h / run on eight machines, each machine's output in its own card with a check mark and how long it took.](https://muxin.dev/images/shots/run-dark.png?v=fea085a2) *One command, eight machines, a second later.* ## Run one 1. Type the command. 2. Pick the machines. Every machine that’s online is picked to start with; click one to leave it out, or **None** (then **All**) to start over. Offline and disconnected machines are greyed out. 3. Click **Run on N**, or press Return. To start with a single machine, right-click it in the sidebar › **Run a command…**. ## Where it runs On each machine the command runs in your login shell, from your home folder, as you. Your PATH and tools are there as in your terminal. There’s no terminal and nothing to type into: a command that asks a question (a password, “Continue? \[y/N\]”) gets no answer and usually gives up. Pass the flag that skips the question, like `-y`. > **Warning:** It’s your real machines, not a sandbox. Read the command before you press Run on twelve of them. ## The output - Each machine gets a card, filled in as its output comes. The header says how it went: a check mark and how long it took, or why it failed (“Exit 1”). - Above the cards, “All done”, or how many failed. - The expand button on a card makes it bigger, with more of its output. All of it is in Activity (`⌘J`). - **Clear** clears the results. ## Recent commands Your last eight commands are listed under the box as **Recent**. Click one to put it back. They’re still there after you quit. The × forgets them. ## Snippets A snippet is a command you save once and run with one click. Give it a name, and a folder if you like. - **Save one:** type the command, then click the star next to **Run**. Or click **New snippet** under **Snippets**. - **Run it here:** the play button runs it on the machines picked. Click its name to put it in the box first, to change it before it runs. - **In a terminal:** on a session’s page, **Snippets** types one into its terminal and presses Return. Folders open as their own menus. - **From the palette:** press `⇧⌘P` and type its name. On a session’s page it goes into that terminal. On a machine’s page it runs there. Anywhere else it waits in Run for you to press Return. - **Change or delete one:** the pencil and the bin next to it. Snippets are kept in `config.toml`, so they survive a restart: ``` [[settings.snippets]] name = "Disk space" command = "df -h /" folder = "Checks" ``` A command can have several lines. They run one after another. ## From a terminal and from agents ``` muxin run --on beacon,mac-studio -- df -h / muxin run --all -- brew upgrade # every machine that’s online muxin run --all --timeout 1800 -- git -C ~/code/api pull ``` - It waits for all of them and prints each one’s output and exit status. It exits 1 when any of them failed, so it works in a script. - Each one may run 10 minutes by default; `--timeout` takes up to an hour (3600 seconds). Snippets work from a terminal too: ``` muxin snippet ls muxin snippet add "Disk space" --folder Checks -- df -h / muxin snippet run "Disk space" --on beacon,mac-studio # or --all muxin snippet rm "Disk space" ``` Agents use `run_on_machines(machine_ids, command, timeout_secs?)`, and `snippet_list` and `snippet_run(name, machine_ids)` for your snippets. They’re told to run it only when you ask, and to show you the command first. See [MCP for your agents](https://muxin.dev/docs/agents.md). > **Tip:** For something that should run at set times, not just now, make it a [schedule](https://muxin.dev/docs/schedules.md). Source: https://muxin.dev/docs/run --- # Schedules > Run a command or start an agent session on one of your machines at set times, even when Muxin isn’t open. A schedule runs a command, or starts an agent session, on one of your machines at set times: run the tests every night, check a disk every hour, have Claude Code go through new issues every weekday morning. It’s kept on the machine and run by the machine’s own scheduler, so it runs whether Muxin is open or not. ![The Schedules page: a Claude Code triage schedule on Forge, Nightly tests and Disk report on Beacon with the nightly run's test output open, and a failed Backups schedule on Vault.](https://muxin.dev/images/shots/schedules-dark.png?v=0d7421be) *Schedules by machine, each with its last run. Nightly tests is open on its last six runs and the newest one’s output.* ## How it works 1. **You save it**: In the New schedule dialog, from a terminal, or from an agent. 2. **Kept on the machine**: In `~/.muxen/schedules/`, and registered with cron, launchd or Task Scheduler there. 3. **At its time**: The machine’s scheduler runs it through Muxin’s agent, with or without Muxin open. 4. **Output kept there**: Each run’s output stays on the machine; the Schedules page shows it. *Muxin only edits the schedule. Running it is the machine’s job.* - **Linux:** cron. Muxin keeps its own block in your crontab and leaves the rest alone. - **A Mac:** launchd, as a LaunchAgent of yours. - **Windows:** Task Scheduler, in a `\Muxen\` folder, without a window popping up. Times are in the machine’s own time zone, not your computer’s. ## Make one Click **New schedule** on the Schedules page (`⌃7`), or right-click a machine › **New schedule here…**. ![The New schedule dialog: Name, On (the machine), Runs (A command or An agent session), Folder, and When, with Every day at 09:00 picked.](https://muxin.dev/images/shots/scheddlg-dark.png?v=06a2f848) *It’s kept and run on the machine itself.* - **Name**: what it’s called on the Schedules page. - **On**: the machine it runs on. - **Runs**: **A command**, run in your login shell there, or **An agent session**: pick an agent and a prompt, and at its time it starts a session like New session does. - **Folder**: where it runs. Your home folder when empty. - **When**: every 1 to 59 minutes, every hour (on the hour), every day, weekdays, or some days of the week, at a time like 09:00. ## Command or agent session? An **agent session** starts a real session, the same as one you’d start yourself. It shows up under the machine in the sidebar, and waits for you when it’s done. Good for work you want to look at and answer: “go through new issues and draft replies”. For an agent that should work on its own and just finish, use a **command** that runs the agent without a terminal, like `claude -p "label the new issues in acme/api"`. Its output is kept like any command’s. ## The Schedules page Schedules are grouped by machine, and each machine says what runs them (“Run by cron”, “Run by launchd”, “Run by Task Scheduler”). Each schedule shows when it runs and how its last run went. - **Run now** runs it once, now. - **Pause** stops it running until you **Resume** it. - The bin deletes it, with its runs. - **Click a schedule** to see its last runs, newest first, and pick one for its output: what it printed, how long it took and its exit status. For an agent session, the session it started, with **Open it**. ## Good to know - The last 30 runs of each schedule are kept. - A command that’s still running after 6 hours is ended. - If a run is still going when the next one is due, the next one is skipped. > **Warning:** On Linux, schedules need cron installed and running. Containers often have none. When a machine can’t run them, Muxin says why on the Schedules page, with what to do (for example `sudo systemctl enable --now cron`). ## From a terminal and from agents ``` muxin schedule add beacon --name "Disk report" --every weekdays --at 09:00 --command "df -h /" muxin schedule add beacon --name Triage --every day --at 08:30 --agent claude --prompt "Label new issues in acme/api" muxin schedule add beacon --name Backups --every 2h --command "restic backup ~/data" muxin schedule ls # every machine’s (--on beacon for one) muxin schedule run beacon s-ab12cd # run it now muxin schedule log beacon s-ab12cd # its last runs and output muxin schedule rm beacon s-ab12cd ``` `--every` takes `15m`, `2h`, `day`, `weekdays` or days like `mon,thu`. Agents use `schedule_list`, `schedule_save`, `schedule_run`, `schedule_log` and `schedule_delete`. See [The command line](https://muxin.dev/docs/cli.md) and [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/schedules --- # GitHub and workspaces > Your review requests, issues and repositories, the checkouts on your machines, and handing an issue to an agent. The GitHub page (`⌃4`) is built for one loop: see what needs you, hand an issue to an agent on one of your machines, and move on. It shows what’s waiting for you, your repositories, and where each one is checked out on your machines. ## Sign in Muxin uses the GitHub CLI’s login. If `gh auth status` works in your terminal, Muxin is already signed in. If not, **Settings › GitHub › Sign in with GitHub** runs the CLI’s browser sign-in for you. A `GITHUB_TOKEN` (or `GH_TOKEN`) in the environment works too. Each machine has its own `gh` login, which agents there use for issues and pull requests. A machine’s page shows whether it’s signed in and can sign it in. ## What needs you The top of the page is your inbox: - **Waiting for your review**: pull requests someone asked you to review. - **Assigned to you**: open issues with your name on them. - **Your pull requests**: the ones you opened that are still open. ![The GitHub page: review requests, issues assigned to you and your open pull requests, then the repositories.](https://muxin.dev/images/shots/github-dark.png?v=a346cbd0) *What needs you first, then your repositories.* Click any of them to read it in full: the description, the comments, and for a pull request its checks and reviews. `⌘⇧R` syncs GitHub now. ## Repositories Below the inbox is every repository you own, collaborate on, or reach through your organizations. Open one for its open issues, pull requests and recent GitHub Actions runs. - **Favorites**: star the repositories you work on and they stay at the top. Right-click a repository for **Add to favorites**. - **Forks**: a fork sits under the repository it came from. An issue on a repository you can’t push to goes through your fork, and the agent is told to open its pull request against the original. - **Grouped or not**: show one list, or group by owner (you, then your organizations, then repositories other people shared with you). ## Checkouts on your machines Muxin’s agent on each machine looks for git checkouts in your code folders (`~/Developer`, `~/code`, `~/src` and the like) and links them to their GitHub repository. A repository’s page lists where it’s checked out, with the branch, how many commits it’s ahead or behind, and any uncommitted files. **Fetch**, **Pull** and **Push** work from there. To look in other folders, add them in **Settings › General › Code folders**. ## Hand an issue to an agent Every issue has **Work on it with an agent**; every pull request has **Review with agent**. Either opens a new session, with the issue’s link, title and description as the agent’s first message. An issue also has **Hand off in a box**: an agent works on it by itself, in a container, and opens a pull request that closes it. See [Boxes](https://muxin.dev/docs/boxes.md#from-an-issue). Where the agent works depends on what’s on your machines: - **A new worktree**, when the repository is checked out on the machine (this computer first). The agent gets its own folder and branch, and your checkout stays as it is. - **A fresh clone**, when Muxin finds no checkout in your code folders, or when you right-click a pull request and pick **Review in a new workspace…**. - **The checkout itself**, if you pick **A folder** under Where. 1. **Pick an issue**: Click **Work on it with an agent**, and pick the machine. 2. **Its own branch**: In a new worktree or a fresh clone. An issue gets a branch like `issue-910-content-excalidraw`. 3. **The agent works there**: It starts with the issue as its first message. Watch it from the sidebar. 4. **You ship it**: Read what it changed, then use **Actions** to commit and open the pull request. *A pull request checks out its own branch instead, forks included.* See [Agent sessions](https://muxin.dev/docs/sessions.md) for following the agent once it’s running. ## Workspaces A workspace is a folder on one of your machines, kept for one task: a fresh git clone, or a worktree of a checkout that’s already there. The ones above are made for an issue; your AI agents make their own to run tests or try a change (with `workspace_create`, see [MCP for your agents](https://muxin.dev/docs/agents.md)). The [Boxes](https://muxin.dev/docs/boxes.md) page lists them all, under **Agents’ workspaces**. ![The Workspaces page: api and web on Beacon, a worktree called ios-app share-sheet on Orbit whose pull request #77 is merged, with a Clean up button, and desktop on Forge.](https://muxin.dev/images/shots/workspaces-dark.png?v=253593bb) *The share-sheet worktree’s pull request is merged, so Muxin offers to clean it up.* - Each one shows its machine, repository and branch, which agent made it, its last command with the exit code, and its folder. - A git line shows its branch, what changed, and its pull request with the checks, like a [session’s](https://muxin.dev/docs/sessions.md#git). - A **worktree** shares its checkout’s history, so it’s ready in a moment. Several agents can each have one on the same repository. Deleting it removes the worktree and keeps its branch. - When a worktree’s pull request is merged, its work is done. **Clean up** deletes it. - Click one for its details, with **New session** (an agent or a shell in its folder), **Open in editor**, **Copy shell command** and **Changes** (its `git status` and the uncommitted diff). - **New workspace** makes one yourself: a machine, and a repository to clone if you want one. Private repositories clone with your `gh` login. - A workspace runs directly on the machine, with its tools, or in a fresh Docker container of its own (the folder mounted at `/workspace`), for untrusted code or a clean toolchain. > **Warning:** Workspaces stay until you delete them, with the bin on the page. Push anything worth keeping first. ## Git on each machine For an agent to commit and push on a machine, git there needs a name, an email and a way to reach GitHub. A machine’s page has a Git card that shows all three. When something’s missing, one click fixes it: - **Use my GitHub identity** sets git’s name and email to your GitHub name and your private noreply address. - **Use the GitHub CLI** runs `gh auth setup-git`, so pushes use that machine’s `gh` login. Both change the machine’s global git config, so Muxin only does them when you click. ``` muxin git status beacon muxin git setup beacon --identity --credentials ``` ## More than one account Muxin uses one GitHub account at a time. Click your name at the top of the GitHub page to switch. The menu lists every account the GitHub CLI on this computer is signed in to, and each machine’s own `gh` login. Pick your work laptop’s login and Muxin shows that account’s repositories, inbox and runners; **Fix with agent** then prefers checkouts on that machine. A token from another machine is fetched over ssh when needed and kept in memory only. Switching doesn’t change which account `gh` uses in your terminal. **Add another account…** runs `gh auth login`. ## Permissions for organizations Reading your repositories and issues needs only the default `gh` login. Watching an organization’s runners needs the `admin:org` permission. **Settings › GitHub** shows when it’s missing; **Grant access** runs this in a terminal and finishes in your browser: ``` gh auth refresh -h github.com -s admin:org ``` See [GitHub Actions runners](https://muxin.dev/docs/runners.md) for what watching gives you. ## From the command line ``` muxin github inbox # what needs you muxin github repos # favorites first muxin github repo acme/api # issues, PRs, runs, and where it's checked out muxin github issue acme/api#632 # or the issue's URL muxin github favorite acme/api # --remove to unstar muxin github accounts muxin github use work-login # or: --machine work-macbook muxin checkouts --repo acme/api muxin checkouts --machine beacon --path ~/code/api --git pull muxin ws create --machine beacon --worktree-of ~/code/api --branch fix-login muxin ws ls # with each one's branch and pull request ``` Source: https://muxin.dev/docs/github --- # Runners and jobs > Install self-hosted runners on your machines, see which ones are busy, and find out why a job isn’t starting. Muxin installs GitHub Actions runners on your machines and shows them next to everything else running there. It downloads the runner, registers it with GitHub using your `gh` login, and starts it. You never copy a registration token. ## Watch an organization or a repository Runners register with an organization or a repository. Tell Muxin which ones you use in **Settings › GitHub › Watching**. It lists your organizations, so watching one is a click. Or from a terminal: ``` muxin watch acme # an organization muxin watch acme/api # one repository muxin unwatch acme ``` For what it watches, Muxin reads each runner’s live status from GitHub, and the queued and running jobs of the most recently pushed repositories. It asks every 20 seconds or so; unchanged answers don’t count against your rate limit. > **Warning:** An organization’s runners need the `admin:org` permission on your GitHub login. **Settings › GitHub** says when it’s missing and has a **Grant access** button. Or run `gh auth refresh -h github.com -s admin:org`. A repository’s runners need admin access to that repository. ## Install runners On a machine’s page, open the **···** menu and pick **Install runner…**. Pick: - **Register with**: one of the organizations or repositories you watch. - **How many**: up to 16 at once, and their **Names** if you want your own. - **Extra labels**, such as `gpu`. GitHub adds `self-hosted`, the OS and the architecture by itself. - **Run as**: how each runner stays running (below). Muxin picks the right runner build for the machine, downloads it, registers it and starts it. The progress shows in Activity (`⌘J`). ### Run as | Choice | What it does | |---|---| | **Auto** | The best fit for the machine: a service where it can, else Docker, else a background process. The default. | | **Service** | Starts at boot: launchd on macOS, a Windows service, systemd on Linux. On Linux this needs passwordless sudo. | | **Docker** | A container per runner that restarts with Docker. No sudo. Jobs are kept apart from the machine. | | **Background** | No root needed, but it stops when the machine restarts. | Docker runners can’t use the machine’s Docker unless you share its socket (`--docker-socket` from the CLI). That’s root on the machine for every workflow that runs there, so only do it for workflows you trust. ## Runner states Each runner is **working** (running a job), **idle**, **offline**, or **unknown**. Where the state comes from matters: - **GitHub**: live, for runners in what you watch. - **The last machine check**: whether the runner’s process or service is running, for runners GitHub doesn’t tell Muxin about. Right-click a runner to **Stop**, **Start** or **Restart** it, **Show logs** (its newest diagnostic log), open the job it’s running on GitHub, or **Remove runner…**, which deregisters it from GitHub. A runner that GitHub knows but no machine lists shows up on its own, so you can find and remove leftovers. When a runner falls behind, its diagnostic offers **Update**. Muxin downloads the new version and checks it first, and the runner keeps running until that has worked. Its registration and work folder stay. It’s refused while a job runs. ## Jobs The Jobs page (`⌃2`) shows self-hosted jobs that are **Queued** and **Running**, with how many runners are busy. ![The Jobs page: queued jobs, some with no runner that fits, and running jobs with the runner each is on.](https://muxin.dev/images/shots/jobs-dark.png?v=95b7f483) *A queued job no runner can take is flagged.* Right-click a job to show its runner or **Cancel run…**. GitHub cancels whole workflow runs, not single jobs, so that stops every job in the run. ## When a job doesn’t start A job waits for an online runner that has *all* of its labels. When none has, the Jobs page says how many jobs have “no runner that fits”. Usually the fix is one of these: 1. A runner with the labels is offline. Start it, or check its machine: an offline machine explains every runner on it. 2. No runner has one of the labels, say `gpu`. Install one with that label. 3. The runner is registered to a different organization or repository than the workflow. For a runner that won’t stay online, **Show logs** first. See [Troubleshooting](https://muxin.dev/docs/troubleshooting.md) for unreachable machines. ## From the command line ``` muxin runners [--machine beacon] [--state offline] muxin jobs muxin install beacon --count 2 --label gpu muxin install beacon --scope acme/api --mode docker muxin runner restart beacon/beacon-01 muxin runner logs beacon/beacon-01 muxin runner update beacon/beacon-01 muxin runner remove beacon/beacon-01 [--delete-files] muxin cancel-run 123456789 ``` Runner ids are `/`, such as `beacon/beacon-01`. A runner GitHub knows but no machine lists is `github/`. Runners also live in `config.toml` under their machine, so Muxin knows what each machine should host. For GitHub Enterprise Server, point Muxin at your server’s API: `muxin settings --api-url https://HOST/api/v3`. Source: https://muxin.dev/docs/runners --- # MCP for your agents > Let Claude Code, Codex or any MCP client see and work with your machines through Muxin. Everything you do in Muxin, an AI agent can do too. Muxin ships an [MCP](https://modelcontextprotocol.io) server with more than 90 tools: your machines, sessions, workspaces, files, logs, services, GitHub, runners, VMs, schedules and cloud machines. Ask your agent “which of my machines is low on disk?” or “run the tests on Linux” and it works it out with Muxin. 1. **Your agent**: Claude Code, Codex, Cursor or any MCP client, on this computer. 2. **muxin mcp**: Muxin’s MCP server, started by your agent. It speaks JSON over stdio. 3. **Muxin on this computer**: The same engine the app uses, with the same config, logins and keys. 4. **Your machines**: Reached over ssh or a direct connection, as the app reaches them. *The MCP server runs on your computer. Nothing new is opened on your machines for it.* ## Set it up First make sure the `muxin` command is installed: on a Mac, **Settings › General › Command line**; on Windows, the installer offers it. Then print setup snippets that point at your copy: ``` muxin mcp --print-config ``` ### Claude Code ``` claude mcp add muxin -- muxin mcp ``` ### Codex In `~/.codex/config.toml`: ``` [mcp_servers.muxin] command = "muxin" args = ["mcp"] ``` ### Claude Desktop, Cursor and other clients ``` { "mcpServers": { "muxin": { "command": "muxin", "args": ["mcp"] } } } ``` If your client can’t find `muxin` on its PATH, use the full path that `muxin mcp --print-config` prints. The app, the CLI and any number of MCP servers can run at once. They share the files in Muxin’s config folder and pick up each other’s changes. ## What to ask You don’t need to name tools. Some things that work well: - “What needs attention on my machines?” - “Why is the runner on beacon offline?” - “Run the test suite on Linux and tell me what fails.” - “Start Claude Code on mac-studio in ~/code/api and have it fix issue 632.” - “What is the Codex session on beacon asking?” - “Which container is using the most memory on the NAS?” - “How much did my agents use this week, at API prices?” - “Copy the build from beacon to my Downloads folder.” ## What it will and won’t do without asking The tools act on your real machines, as you. The MCP server hands every agent guidance when it connects: read freely, and confirm before changing things. - **Read-only**, fine to do any time: status and machine checks, lists, logs, ports, processes, screenshots, reading sessions, usage. - **Only when you asked for exactly that**: installing or removing runners, starting or stopping services and containers, killing processes, typing into sessions or desktops, running commands on several machines, git pushes, VMs and schedules. - **Costs money**: cloud machines bill by the hour. An agent should tell you the size and price and get your OK before `cloud_create`. Editing Muxin’s own list of machines (add, remove, rename, connect) only changes `config.toml`, never the machine. > **Warning:** Your agent client’s permission prompts still apply. Leave approval on for the tools that change things until you trust how your agent uses them. ## The tools | Area | Tools | |---|---| | Overview | `status` (start here), `get_machine`, `check_machines`, `get_settings`, `update_settings` | | Machines | `list_ssh_hosts`, `add_machine`, `remove_machine`, `rename_machine`, `connect_machine`, `ignore_warning`, `machine_connection`, `direct_connection`, `wake_machine`, `machine_power` | | Agent sessions | `session_list`, `session_start`, `session_read`, `session_wait`, `session_send`, `session_question`, `session_answer`, `session_action`, `session_handoff`, `session_rename`, `session_restart`, `session_stop` | | Boxes | `box_create`, `box_list`, `box_send`, `box_pause`, `box_destroy` | | Workspaces | `workspace_create`, `workspace_list`, `workspace_get`, `workspace_exec`, `workspace_read_file`, `workspace_write_file`, `workspace_list_files`, `workspace_changes`, `workspace_sync`, `workspace_destroy`, `workspace_allow` | | Files | `list_files`, `copy_files` | | Several machines | `run_on_machines`, `snippet_list`, `snippet_run`, `snippet_save`, `snippet_delete` | | Logs, services, Docker | `log_sources`, `logs_read`, `machine_services`, `service_action`, `docker_run`, `docker_pull`, `compose_project`, `compose_action` | | Processes and ports | `machine_processes`, `process_signal`, `machine_ports` | | Desktops | `desktop_screenshot`, `desktop_input`, `desktop_displays`, `desktop_windows`, `desktop_add_display`, `desktop_remove_display`, `desktop_set_display` | | GitHub and code | `github_inbox`, `github_repos`, `github_repo`, `github_item`, `github_favorite`, `github_accounts`, `github_use_account`, `local_checkouts`, `git_status`, `git_setup`, `git_sync` | | Runners and jobs | `github_scopes`, `list_runners`, `list_jobs`, `install_runners`, `runner_action`, `cancel_run` | | VMs | `vm_options`, `vm_create`, `vm_destroy` | | Schedules | `schedule_list`, `schedule_save`, `schedule_delete`, `schedule_run`, `schedule_log` | | Cloud machines | `cloud_options`, `cloud_create`, `cloud_power`, `cloud_usage`, `cloud_destroy` | | Usage | `agent_usage` | | Long operations | `get_operation`, `list_operations`, `cancel_operation` | Every tool describes itself to your agent, so it knows the arguments without this page. ## Ids | Thing | Looks like | |---|---| | Machine | `mac-studio`: a slug of its name. The display name works too. | | Runner | `mac-studio/mac-studio-01`, or `github/` for one GitHub knows but no machine lists. | | Agent session | `beacon/claude-3f9a` | | Workspace | `ws-7f3a2c` | ## Results and errors Every tool returns JSON. The state can be a few minutes old: `status` uses the last machine check, and says when that was. An agent that needs it fresh calls `check_machines`; checks are read-only. Failures come back with a `code` the agent can act on: | Code | Means | |---|---| | `not_found` | No machine, runner, session or workspace by that id. | | `invalid` | A bad argument. | | `busy` | The machine is already doing a changing operation. One at a time per machine; wait and retry. | | `github` | GitHub refused, often for a missing permission. | | `unreachable` | The machine didn’t answer. | | `operation_failed` | The command ran and failed; the log says why. | | `internal` | A bug in Muxin. | Many errors also carry a `hint`, often the exact command that fixes the problem, such as `gh auth refresh -h github.com -s admin:org`. Agents are told to pass it to you as is. A diagnostic also lists `actions`: what Muxin can do about it, the likely fix first. Long operations (installing runners, copying files, creating a VM) wait until they finish and return the end of their log. With `wait: false` the agent gets an operation id instead and checks on it with `get_operation`. ## Without MCP An agent that can run shell commands but doesn’t speak MCP can use the [command line](https://muxin.dev/docs/cli.md) instead. Add `--json` to any command for the same results the MCP tools return. An agent that loads skills can learn the command line from Muxin’s skill, with no server to set up: ``` muxin skill install # for every agent found on this computer muxin skill install --agent hermes # just one: claude, codex, opencode, gemini, pi, hermes, copilot, cursor, qwen, droid, kimi, or agents muxin skill remove muxin skill show # the guide the skill reads ``` What goes in each skills folder is a short stub. It tells the agent to run `muxin skill show`, which prints the guide from the Muxin you have. So the skill is never out of date, even after an update. If an older Muxin put a full copy there, run `muxin skill install` once more to swap it for the stub. Source: https://muxin.dev/docs/agents --- # Command line > The muxin command: everything the app does, for your terminal, your scripts and agents without MCP. The `muxin` command does what the app does, from a terminal. It’s the same program: run with no arguments, it opens the window. Use it for quick looks, in scripts, and for AI agents that run shell commands but don’t speak [MCP](https://muxin.dev/docs/agents.md). ## Install the command - **macOS**: **Settings › General › Command line** installs it in `/usr/local/bin`. With Homebrew, it’s already in your PATH. - **Windows**: the installer offers to add it to your PATH. - **Linux**: the `.deb`, `.rpm` and Arch packages, the AUR and Homebrew put it in your PATH, and so does `install.sh` from the `.tar.gz`. With the AppImage, `muxin shell-command install` puts it in `~/.local/bin`. `muxin shell-command remove` takes it out again. `muxen`, its name before 0.5.1, runs it too. `muxin --help`, and `--help` after any command, lists the options. ## JSON and exit codes - `--json`, on every command: print JSON only on stdout, the same shapes the MCP tools return. Errors print as `{"error": {...}}` with a `code` and often a `hint`. Progress goes to stderr. | Exit code | Means | |---|---| | `0` | Success. | | `1` | The operation failed. | | `2` | Bad input, or the thing wasn’t found. | `muxin ws exec` is the exception: it exits with the command’s own exit code (124 if it timed out), so it composes like running the command locally. Machines are named by their id, a slug of their name such as `mac-studio`; the name works too. The app, the CLI and MCP servers can all run at once and see each other’s changes. ## Machines ``` muxin status [--refresh] # overview and what needs attention muxin machines muxin machine beacon # everything about one machine muxin check # check every machine now and print a report muxin ssh-hosts # your ssh config, your tailnet, this network muxin add-machine --name Beacon --host you@beacon.local # connects directly once it answers muxin add-machine --name Old --host old.local --ssh-only # keeps it on ssh muxin rename-machine beacon "Beacon server" # the id stays the same muxin remove-machine beacon # nothing on the machine changes muxin disconnect beacon # stop connecting; its sessions go on there muxin connect beacon muxin ignore beacon low-disk [--undo] # stop showing a warning it's meant to have muxin connection beacon [--direct on|off] muxin wake beacon # Wake on LAN muxin power win-test off # a VM or a cloud machine ``` See [Machines](https://muxin.dev/docs/machines.md) and [Connections](https://muxin.dev/docs/connections.md). ## Agent sessions ``` muxin session ls # with each one's branch and pull request muxin session start beacon claude --cwd ~/code/api --prompt "Fix the failing test" muxin session read beacon/claude-3f9a muxin session wait beacon/claude-3f9a # until it's done or needs you [--timeout 600] muxin session question beacon/claude-3f9a # what it's asking, and the options muxin session answer beacon/claude-3f9a 1 muxin session send beacon/claude-3f9a "Also update the README" muxin session do beacon/claude-3f9a review # or commit, pull_request, fix_comments, … muxin session attach beacon/claude-3f9a # use it in this terminal muxin session rename beacon/claude-3f9a "API tests" muxin session handoff beacon/claude-3f9a codex [--on orbit] [--keep] # another agent takes over muxin session restart beacon/claude-3f9a muxin session stop beacon/claude-3f9a ``` Agents are `claude`, `codex`, `opencode`, `gemini`, `agy`, `amp`, `pi`, or `shell` for a plain shell. The actions are `commit`, `commit_push`, `pull_request`, `review`, `fix_comments`, `conflicts` and `recap`. From inside a session, `muxin session start codex --prompt "…"` (no machine) starts a helper beside it, and `--keep` lets it go on after that session ends. See [Agent sessions](https://muxin.dev/docs/sessions.md). ## Boxes ``` muxin box new acme/api "Fix the flaky webhook test, and open a pull request" muxin box new ~/code/app "Finish this refactor" --on beacon --agent codex muxin box ls muxin box send box-7k2m9q "Also update the docs" muxin box attach box-7k2m9q muxin box shell box-7k2m9q muxin box pause box-7k2m9q muxin box rm box-7k2m9q ``` See [Boxes](https://muxin.dev/docs/boxes.md). ## Workspaces ``` muxin ws create --platform linux --repo acme/api --ref main muxin ws create --docker --image node:22 --repo acme/web # in a fresh container muxin ws create --machine beacon --worktree-of ~/code/api --branch fix-login # a worktree of a checkout there muxin ws ls # with each one's branch and pull request muxin ws exec ws-7f3a2c -- cargo test muxin ws exec ws-7f3a2c --background -- npm run dev muxin ws cat ws-7f3a2c .muxen/logs/1.log echo 'hello' | muxin ws write ws-7f3a2c notes.txt muxin ws files ws-7f3a2c src --depth 1 muxin ws changes ws-7f3a2c # git status and the diff muxin ws sync ws-7f3a2c ~/code/api --push # or --pull; --delete mirrors deletions muxin ws shell ws-7f3a2c # a shell there, for you muxin ws rm ws-7f3a2c [--keep-files] muxin ws allow nas --off # no workspaces on this machine ``` `ws` is short for `workspace`. Leave out the machine and Muxin picks the least-loaded one that matches `--platform`. ## Files and editors ``` muxin files beacon:~/build # what's in a folder (alias: ls) muxin cp beacon:~/build/app.tar.gz mac-studio:~/Downloads muxin edit beacon:~/code/api [--editor zed] [--print] ``` `edit` opens the folder over ssh in Zed, Cursor or VS Code; `--print` shows the command instead. See [Files](https://muxin.dev/docs/files.md). ## Running things ``` muxin run --on beacon,mac-studio -- df -h / # one command on several machines muxin run --all -- uptime # every machine that's online muxin snippet ls # your saved commands (add, rm, run --on a,b) muxin ps beacon [-n 20] # busiest processes and GPUs muxin kill beacon 4242 [--force] muxin ports beacon # what's listening muxin forward beacon 3000 # its port 3000 at localhost:3000, until Ctrl-C ``` `run` exits 1 when any machine failed. See [Run on machines](https://muxin.dev/docs/run.md) and [Servers](https://muxin.dev/docs/servers.md). ## Logs and services ``` muxin logs beacon --list # what there is to read muxin logs beacon # the system log muxin logs beacon --unit nginx -n 500 --grep error muxin logs beacon --container postgres --follow muxin logs beacon --file /var/log/syslog muxin services beacon # services and containers, failed first muxin services beacon restart nginx muxin services beacon stop postgres --container ``` See [Logs and services](https://muxin.dev/docs/logs-services.md). ## Desktops ``` muxin desktop shot beacon [-o screen.jpg] muxin desktop input beacon '[{"type":"click","x":640,"y":400},{"type":"text","text":"hello"}]' muxin desktop displays beacon # its monitors, with their ids muxin desktop windows beacon # its apps' windows, with their ids muxin desktop add beacon --size 2560x1440 --name Side muxin desktop set beacon --size 3840x2160 --scale 2 muxin desktop remove beacon ``` `shot` and `input` take `--display` for one monitor, or `--display window:` for one app’s window. Input coordinates are in the screenshot’s pixels. See [Desktops](https://muxin.dev/docs/desktops.md). ## VMs and schedules ``` muxin vm options muxin vm create win-test --system windows-11 --on beacon muxin vm create dev --system ubuntu-24.04 --install claude,codex muxin vm destroy win-test muxin schedule ls [--on beacon] muxin schedule add beacon --name Tests --every day --at 09:00 --command "make test" muxin schedule add beacon --name Triage --every weekdays --at 08:30 --agent claude --prompt "Triage new issues" --folder ~/code/api muxin schedule run beacon muxin schedule log beacon muxin schedule rm beacon ``` `--every` takes `15m`, `2h`, `day`, `weekdays` or days like `mon,thu`. See [VMs](https://muxin.dev/docs/vms.md) and [Schedules](https://muxin.dev/docs/schedules.md). ## Cloud machines ``` muxin cloud login --browser # or --token TOKEN, or --doctl muxin cloud options # regions, sizes, prices muxin cloud create build-box --region nyc3 --size s-2vcpu-4gb muxin cloud usage muxin cloud power build-box off # still billed while off muxin cloud destroy build-box muxin cloud logout ``` A cloud machine costs money every hour it exists. See [Cloud machines](https://muxin.dev/docs/cloud.md). ## GitHub, git and runners ``` muxin github inbox muxin github repos muxin github repo acme/api muxin github issue acme/api#632 muxin github accounts muxin github use work-login muxin checkouts --repo acme/api muxin git status beacon muxin git setup beacon --identity --credentials muxin watch acme # or acme/api; unwatch to stop muxin runners [--machine beacon] [--state offline] muxin jobs muxin install beacon --count 2 [--label gpu] [--mode auto|service|background|docker] muxin runner restart beacon/beacon-01 # start, stop, restart, logs, remove, update muxin cancel-run 123456789 ``` `github` is also `gh`. See [GitHub](https://muxin.dev/docs/github.md) and [Runners](https://muxin.dev/docs/runners.md). ## Usage, settings and files ``` muxin usage [--days 30] [--machine beacon] # tokens and cost at API prices muxin settings # show them muxin settings --poll 20 --check-interval 15 # GitHub every 20 s, machines every 15 min muxin paths # where Muxin keeps its files muxin updates # whether a newer Muxin is out, and how to update muxin init # write a starter config.toml muxin mcp # the MCP server, for agents muxin skill install # teach your agents this CLI muxin skill show # the guide your agents read muxin quit # quit the running app ``` Muxin keeps its files in `~/.config/muxin` (`%APPDATA%\muxin` on Windows). Set `MUXIN_HOME`, or pass `--config-dir`, to use another folder; a separate one is handy for trying things without touching your real setup. Source: https://muxin.dev/docs/cli --- # Usage and cost > What Claude Code and Codex used across all your machines, in tokens and in what it would cost on the API. The Usage page (`⌃5`) adds up what your agents used on every machine: tokens, requests, and what the same work would cost through the API. It reads Claude Code’s and Codex’s own logs on each machine, so it covers sessions you started anywhere, not only in Muxin. ![The Usage page: tokens, requests and cost at API prices, a chart of each day, and tables by model, by machine and busiest folders.](https://muxin.dev/images/shots/usage-dark.png?v=f4dd6895) *Each day’s use, then the same broken down by model, machine and folder.* ## Reading the page Pick a period at the top: **Today**, **7 days**, **30 days** or **90 days**. Today counts from midnight on this computer. - **At API prices**, **Tokens**, **Requests** and **Most used**: the totals for the period. - **Each day, at API prices**: a chart, Claude Code and Codex in their own colors. - **By model**: requests, output tokens, cache reads, all tokens and the cost for each model. - **By machine**: which machines did the work. - **Busiest folders**: the projects that used the most, with the machine and agent. Muxin reads the logs when you open the page. Click the refresh button to read them again. ## What the cost means Costs are at Anthropic’s and OpenAI’s list prices for each model. If you use Claude Code with a Claude plan, or Codex with a ChatGPT plan, you don’t pay per token: the number is what the same work would have cost through the API. It’s useful for comparing models, machines and projects, and for seeing what a plan saves you. A model Muxin doesn’t have a price for is counted in tokens only, and the page names it. > **Note:** Cache reads are often most of the tokens. They’re much cheaper than fresh input, which is why a large token count can still cost little. ## Where the numbers come from Muxin’s agent on each machine reads the logs the agents already write. Nothing extra is recorded. | Agent | Logs | |---|---| | Claude Code | `~/.claude/projects` (or under `$CLAUDE_CONFIG_DIR`) | | Codex | `~/.codex/sessions` | Only machines that are connected and reachable are counted. A machine that’s off or disconnected drops out until it’s back; its logs are still there. Other agents (OpenCode, Gemini CLI, Amp) don’t show up here yet. ## From the command line ``` muxin usage # the last 7 days muxin usage --days 30 muxin usage --machine beacon muxin usage --days 1 --json # for scripts ``` Agents get the same through the `agent_usage` tool, so you can ask yours “what did my agents use this week, by machine?”. See [MCP for your agents](https://muxin.dev/docs/agents.md). Source: https://muxin.dev/docs/usage --- # Settings and themes > What each Settings tab changes, where your settings are kept, and every keyboard shortcut. Open Settings with `⌘,`. It has eight tabs: General, Appearance, Terminal, GitHub, Cloud, Mobile, Prompts and Keyboard. ## General - **Command line**: installs the `muxin` command for your terminal and your AI agents, or says where it already is. See [Command line](https://muxin.dev/docs/cli.md). - **Agents**: four switches. Your iPad has the first three, and each machine keeps the newest choice. - **Let agents say when they need you**, on unless you turn it off. For Claude Code, Codex, Copilot CLI, Qwen Code and Kimi Code, Muxin adds a small hook to their settings on your machines. Turning it off takes the hooks out. See [How Muxin knows](https://muxin.dev/docs/sessions.md#state). - **Continue agents’ conversations after a restart**, on unless you turn it off. Sessions come back after a machine restarts. With this on, those agents continue their conversation. Off, they start a new one. See [After a restart](https://muxin.dev/docs/sessions.md#restart). - **Agents may start helper sessions**, on unless you turn it off. An agent in a session can start another one to help with its task, and wait for its answer. Helpers show under it and end when it does. Off, Muxin says no when an agent asks. See [Helpers](https://muxin.dev/docs/sessions.md#helpers). - **Show agents in the sidebar**, on unless you turn it off. The sidebar lists every agent session on your machines in one place, the ones that need you first. See [In the sidebar](https://muxin.dev/docs/sessions.md#sidebar). - **Clipboard**: **Share the clipboard with your machines**, off until you turn it on. Copy on this computer, paste on a machine’s desktop, and back. Passwords from a password manager aren’t shared on a Mac or Windows. The Linux app can’t tell them apart. - **Desktops**: **Send this computer’s shortcuts to the machine**, on unless you turn it off. While a machine’s desktop has the keyboard, shortcuts like `⌘Tab` and Alt+Tab go to the machine. `Ctrl+Alt` by themselves gives them back. See [Your computer’s own shortcuts](https://muxin.dev/docs/desktops.md#shortcuts). - **Editor**: which editor **Open in editor** uses first: Zed, Cursor or VS Code (with Remote - SSH), whichever you have. `muxin edit` uses it too. - **Code folders**: where Muxin’s agent on each machine looks for your git checkouts, like `~/Developer` and `~/code`. Add your own, like `~/app`, or take one off the list. **Usual folders** puts the defaults back. See [Checkouts on your machines](https://muxin.dev/docs/github.md#checkouts). - **Connections**: **Connect to new machines directly**, on unless you turn it off. Once a machine you add answers, Muxin talks to its agent directly instead of through ssh. See [Direct connections](https://muxin.dev/docs/connections.md#direct). - **Updates**: **Tell me when a new version is out**. Muxin asks GitHub for its latest release when it opens and twice a day. Nothing about you is sent. When there's a new one, the sidebar and the menu bar menu say so, and About shows how to update. - **Menu bar** (**Tray** on Windows and Linux): Muxin’s icon. Turn it off on a Mac and only the icon goes. Turn it off on Windows or Linux and closing the window quits Muxin. See [Closing the window](https://muxin.dev/docs/getting-started.md#closing). Under it, **Notify me when a session needs me or is done**, on unless you turn it off. See [Notifications](https://muxin.dev/docs/sessions.md#notifications). - **Tailscale**: whether this computer is on your tailnet and how many of your machines are on it. Muxin never changes Tailscale’s settings; see [Connections](https://muxin.dev/docs/connections.md). - **Machine checks**: **Check machines every** so many minutes. A check is read-only, over ssh. Set it to 0 to check only when you ask (`⌘R`). - **Machines file**: where `config.toml` is, with buttons to open it or show it in Finder. ## Appearance Choose **System**, **Light** or **Dark**. System follows your computer. Light and dark each have their own theme, so switching keeps your pick for both. ![Settings, Appearance: System, Light or Dark, then the dark and light themes, then the icon styles.](https://muxin.dev/images/shots/appearance-dark.png?v=fbe90625) *A theme for dark and one for light, and how icons look.* - **Themes**: Muxin Dusk (dark) and Muxin Dawn (light) are the defaults. Also Muxin Graphite and Muxin Paper, and popular ones: Catppuccin, Tokyo Night, Nord, Rosé Pine, Gruvbox, Solarized, Dracula, Everforest, Kanagawa and GitHub, most in light and dark. The Terminal themes (Terminal, Terminal Midnight and Terminal Paper) make Muxin look like an app in your terminal: one monospace font, square corners and `[ Buttons ]`. - **Icons**: how the icons in the sidebar and on pages look. **Minimal** (the default) is plain gray line icons; **Tiles**, **Soft**, **Duotone**, **Rounded** and **Fluent** add color. ## Terminal How agent sessions and shells look: - **Font**: any monospace font installed on this computer, each shown in itself. - **Text size**: also `⌘+` and `⌘−` while a terminal has focus, `⌘0` to reset. - **Line height**: Compact, Normal or Relaxed. - **Cursor**: whether it blinks while the terminal has focus. A preview shows the result as you change it. **Reset** goes back to the defaults. ## GitHub - **Account**: who Muxin is signed in as, through the GitHub CLI or a `GITHUB_TOKEN`. **Sign in with GitHub** when you aren’t. - **Watching**: the organizations and repositories whose runners and jobs Muxin follows. Your organizations are listed, so watching one is a click. When watching an organization needs the `admin:org` permission, **Grant access** adds it. - **Syncing**: **Sync GitHub every** so many seconds (20 by default; unchanged answers don’t count against GitHub’s rate limit), and how many recently pushed repositories per organization to scan for jobs. See [GitHub](https://muxin.dev/docs/github.md) and [Runners](https://muxin.dev/docs/runners.md). ## Cloud - **Usage and cost**: what your cloud machines cost this month and what they will by month’s end, with your DigitalOcean bill when the sign-in can read it. - **DigitalOcean**: sign in with the **Browser**, an **API token** (read and write), or `doctl` if you use it. - **New machines**: the default **Region**, **Size**, and what each one **Comes with** (Docker, the GitHub CLI, Node with Claude Code and Codex, Tailscale and more). - **Tailscale key**: with one saved, new machines join your tailnet by themselves. Without one, Muxin opens Tailscale’s approval page for each. - **When one sits idle**: after so many hours with no busy session, running job or CPU use, tell you, power it off, or destroy it. A powered-off droplet is still billed. Muxin has to be open to notice. See [Cloud machines](https://muxin.dev/docs/cloud.md). ## Mobile Pair an iPad or iPhone with the machines you pick: it shows a QR code for the app to scan. Below it, the devices you paired, each with its machines and **Unpair**. See [Muxin for iPad](https://muxin.dev/docs/ipad.md). ## Prompts What each of a session’s [actions](https://muxin.dev/docs/sessions.md#actions) types into the agent: Commit, Commit and push, Open a pull request, Review the changes, Fix the review comments, Resolve conflicts and Write a recap. ![Settings, Prompts: each session action with its prompt, an Edit button, and the command that runs it.](https://muxin.dev/images/shots/prompts-dark.png?v=2304862b) *Each action’s prompt, with the command that runs it from a terminal.* - **Edit** changes one. Write it the way you’d ask the agent yourself. - `{branch}`, `{base}` and `{pull}` are filled in with the session’s branch, the branch it started from, and its pull request. - **Reset** goes back to Muxin’s prompt. ## Keyboard Every shortcut can be changed: click its keys, then press the new ones. **Reset all** puts them back. Hold `⌘` or `⌃` anywhere in the app to see them. | Shortcut | Does | |---|---| | `⌘P` | Go to a machine, session or desktop | | `⌘⇧P` | Command palette | | `⌃1` … `⌃7` | Overview, Jobs, Workspaces, GitHub, Usage, Run on machines, Schedules | | `⌘1` … `⌘9` | Your first nine machines | | `⌘J` | Activity | | `⌘,` | Settings | | `⌘R` | Refresh all machines | | `⌘⇧R` | Sync GitHub | | `⌘N` | Add machine | | `⌘T` | New session | | `⌘D` / `⌘⇧D` | Split the terminal right / down | | `⌘⌥→` / `⌘⌥←` | Next / previous pane | | `⌘⇧↵` | Show the pane alone, or the whole split | | `⌘⇧W` | Close the pane (the session goes on) | | `⌘⇧]` / `⌘⇧[` | Next / previous session | | `⌘F` | Search machines and sessions | | `⌘B` | Hide or show the sidebar | | `⌘[` / `⌘]` | Back / forward | On Windows and Linux, `Ctrl` takes the place of `⌘`, and the pages are `Alt`+`1` … `7`. The machines’ modifier can be `⌘`, `⌃`, `⌥⌘` or off. A few have no keys until you give them some: next and previous agent (skipping shells), rename what's on screen, end the session on screen, and go to session 1 … 9 of the machine on screen. ### herdr's keys Coming from herdr? Pick **Keys like › herdr** at the top of the Keyboard tab. Muxin then uses herdr's keys wherever it does the same thing. A herdr space is a machine here, and a tab is a session. On a Mac that means `⌘1` … `⌘9` go to the sessions of the machine on screen, and `⌃1` … `⌃9` go to your machines. `⌘[` and `⌘]` go to the previous and next agent, `⌘W` ends a session, and `F2` renames. The pages move to `⌥⌘1` … `7`, and Back and Forward to `⌃⌘[` and `⌃⌘]`. On Windows and Linux you get herdr's `Ctrl+Shift` keys. **Keys like › Muxin** puts Muxin's back. ## Where settings live Settings, the look of the app and your machines are all in one file, `config.toml`, in `~/.config/muxin` (`%APPDATA%\muxin` on Windows). Muxin writes the `[settings]` (with your prompts in `[settings.prompts]`) and `[ui]` sections and the `[[machine]]` entries, and keeps your comments on machines. You can edit it by hand; the app picks up changes. ``` muxin paths # where everything is muxin settings # show the settings muxin settings --poll 30 --check-interval 0 ``` Source: https://muxin.dev/docs/settings --- # Troubleshooting > What each “can’t connect” message means and how to fix it, plus where Muxin keeps its files and how to get help. When Muxin can’t reach a machine, its card and its page say why in a few words, and usually what to do. Here’s each message, what causes it, and the fix. When a message comes with a command (a **hint**), run it in a terminal on this computer: it’s the quickest way to see or fix what ssh is complaining about. ![An offline machine's page: Harbor is offline, shut down, asleep, or off the network, with Wake and Try again.](https://muxin.dev/images/shots/offline-dark.png?v=8a1cb25a) *Every machine that can’t be reached says why, with what you can do about it.* ## “Can’t connect” messages ### “X is offline” It didn’t answer at all: shut down, asleep, or off the network. Nothing’s wrong on your end, and Muxin reconnects when it’s back. Its page says when it was last seen. If Muxin knows its network card, **Wake** sends a Wake on LAN signal. With Tailscale, “Tailscale doesn’t see it either” confirms it’s really off. ### “X isn’t accepting connections” The machine is there, but nothing answers on the ssh port. Either it’s still starting up, or its ssh server is off: - **Mac**: turn on **Remote Login** in System Settings › General › Sharing. - **Windows**: OpenSSH Server isn’t running. See [Windows](https://muxin.dev/docs/windows.md) to set it up and start it. - **Linux**: start its ssh server, for example `sudo systemctl enable --now ssh` (`sshd` on some systems). ### “X doesn’t know this Mac yet” ssh reached it, but your key wasn’t accepted. Set up access once, with your password there; the hint has the command: ``` ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host ``` Then **Try again**. On a Windows PC with an administrator account, the key goes in a different file; see [Windows](https://muxin.dev/docs/windows.md#setup). ### “Your ssh key for X is locked” The machine already has your key, so copying it again won’t help. The key has a passphrase, and Muxin can’t reach an ssh agent that holds it. Add it to your agent; the hint has the command: ``` ssh-add ~/.ssh/id_ed25519 ``` Then **Try again**. If ssh works in a terminal, you can also start Muxin from there. ### “Can’t find X” Its name doesn’t resolve to an address. Check the host in its settings or your ssh config for a typo, or join the network or VPN it’s on. ### “X’s ssh identity changed” The machine’s host key isn’t the one ssh remembers. That’s expected after reinstalling it. Remove its old key and connect once to accept the new one: ``` ssh-keygen -R host ssh user@host ``` > **Warning:** If you didn’t reinstall it or change its address, find out why before accepting the new key: ssh warns about this because it can also mean something is pretending to be your machine. ### “Tailscale is off on this Mac” The machine is reached through Tailscale, and Tailscale is off or signed out on this computer. Turn it on, or sign in, and Muxin reconnects. Muxin never changes Tailscale’s settings itself. A related one: “X is on, but not answering”. Tailscale sees the machine, so it’s on; its ssh may be off, or a firewall is in the way. ### “X didn’t finish the check” It answered, but the check took too long: the machine is very busy, or the connection is poor. Try `ssh` in a terminal to see how it responds. ### “Beacon is offline” on another machine A machine reached through another one (a VM, or one behind a jump host) can’t be reached when the one in front is off. The message names that machine: wake or start it first. “X isn’t answering” means the machine in front is up, but nothing answers behind it. ### A VM: “stopped” or “installing” - **“X is stopped”**: its container on the host isn’t running. **Start** it from its page or right-click menu. - **“Installing Windows 11…”**: Windows is still installing itself, 15 to 30 minutes the first time. **Watch the install** on its page shows its screen. - **“X is powered off”**: a cloud machine you powered off. It’s still billed. See [Cloud machines](https://muxin.dev/docs/cloud.md). ## Direct connections on a Mac: Local Network macOS asks before an app talks to devices on your local network. If you said no, or the prompt never came, direct connections to machines at home fail and Muxin uses ssh instead. The Connection card says “Not reachable on this network”. 1. Open **System Settings › Privacy & Security › Local Network**. 2. Turn on **Muxin**. 3. Quit Muxin and open it again. When the machine you’re connecting to is a Mac, allow **Muxin Agent** (`muxen-agent` before Muxin 0.10.0) in the same place on that Mac. If neither is the problem, UDP port 47821 is probably blocked between you. See [Direct connections](https://muxin.dev/docs/connections.md#direct). ## A Mac asks again for Screen Recording or Accessibility Since Muxin 0.10.0, Muxin’s agent on a Mac is an app, Muxin Agent. Before, it was a plain program, `muxen-agent`. macOS keeps permissions for each app, so after updating, the Mac may ask again, or the desktop may say to allow it. 1. On that Mac, open **System Settings › Privacy & Security**. 2. Turn on **Muxin Agent** under **Screen Recording** (to see the screen) and **Accessibility** (to control it). 3. Open the desktop in Muxin again. ## ⌘Tab doesn’t go to the machine On a machine’s desktop, the bar above the screen has a switch: **Send ⌘Tab to Beacon**, with your machine’s name. While it says that, your shortcuts are still your computer’s. Click it. - **On a Mac**, Muxin needs your OK first. Allow **Muxin** under **System Settings › Privacy & Security › Accessibility**, then go back to the desktop. That’s Muxin on your own Mac, not Muxin Agent on the machine. - **On Linux with Wayland**, your desktop may ask first. Some don’t offer it at all. - **An app in a window of its own** doesn’t take them. Open the machine’s whole desktop. - **You gave them back.** `Ctrl+Alt` by themselves (`⌃⌥` on a Mac) switches it. Press them again. - **Settings › General › Desktops** has to be on for it to start by itself. The **Keys** menu beside the switch sends a shortcut with a click, whatever the switch says. See [Your computer’s own shortcuts](https://muxin.dev/docs/desktops.md#shortcuts). ## Muxin doesn’t open on Linux Muxin draws its window with Vulkan, so it needs your graphics card’s Vulkan driver. The packages ask for it, but a minimal system, a VM or the AppImage may not have one: - Debian and Ubuntu: `sudo apt install mesa-vulkan-drivers` - Fedora: `sudo dnf install mesa-vulkan-drivers` - Arch: `sudo pacman -S vulkan-radeon` or `vulkan-intel` (NVIDIA’s driver includes it) Run `muxin` in a terminal to see why it stops. If the AppImage says it can’t mount, run it with `--appimage-extract-and-run`, or use a package. ## Password prompts A few things need root on the machine: starting or stopping a system service, ending another user’s process, adding a virtual monitor on Linux. When sudo there wants a password, the app asks you for it, passes it to sudo over its encrypted connection, and keeps it in memory only until you quit. Nothing is saved. The command line and MCP can’t ask, so they fail with a hint to do it in the app instead. For runners on Linux, passwordless sudo lets Muxin install them as services; without it, they run in Docker or in the background. ## Where Muxin keeps its files - `config.toml`: your machines and settings, in `~/.config/muxin/` (`%APPDATA%\muxin\` on Windows), or `$MUXIN_HOME` if that’s set. You can edit it by hand; Muxin keeps your comments. - `state.json`, beside it: the last machine check, and what Tailscale last said about each machine. - `direct.json`, beside it: the machines paired for direct connections. `muxin paths` prints where they are. ## Getting help Still stuck? [Report it on GitHub](https://github.com/LumaryLabsLLC/muxin/issues/new/choose): the form asks for what helps, like your Muxin version and the machines involved. **Copy Versions** in Muxin’s menu bar or tray menu copies the versions for you. On an iPad, it’s in **Settings › About**. Questions go in [Discussions](https://github.com/LumaryLabsLLC/muxin/discussions). Or write to . Say what the machine is (Mac, Linux, Windows, a VM), the message Muxin shows, and what `ssh` says when you connect from a terminal. Source: https://muxin.dev/docs/troubleshooting --- # Common questions > What people ask about Muxin: the FAQ on its home page. ## How much does Muxin cost? Nothing, on a Mac, Linux or Windows. Muxin is free and open source, under the Apache License 2.0. The code is on [GitHub](https://github.com/LumaryLabsLLC/muxin). [Muxin for iPad](https://apps.apple.com/app/muxin-for-ipad/id6829937152) is free to download, with a demo. Reaching your own machines from it takes a subscription: $15 a month in the US. ## Which platforms does it run on? The app runs on macOS 12 or later, Linux and Windows 11, on Intel, AMD and Arm processors. On Linux there’s a .deb, an .rpm, an Arch package, an AppImage and the AUR. It can manage Macs, Linux machines and Windows PCs. [Muxin for iPad](https://apps.apple.com/app/muxin-for-ipad/id6829937152) is on the App Store, for iPadOS 18 or later. ## Where does my data go? - Your settings and your list of machines stay on your computer. - Muxin connects to your machines with your own ssh. - Files you copy go through the app on your computer. - Web apps you open from a machine stay on `localhost`. Nothing opens on the network. - GitHub uses your `gh` login. A DigitalOcean token stays in your Mac’s Keychain, in Windows’ Credential Manager, or in a private file on Linux. - The shared clipboard is off until you turn it on. On a Mac or Windows, passwords you copy from a password manager stay on your computer. The Linux app can’t tell them apart, so they’re shared with the rest. - The app has no analytics or telemetry. - Alerts to an iPad, shares and pairing pass through muxin.dev. [The privacy policy](/privacy) says exactly what it sees. ## What do cloud machines cost? What DigitalOcean charges for the size you pick. They’re in your own account, and you pay DigitalOcean directly. DigitalOcean bills a machine while it exists, even powered off. Only destroying it stops the charges. Muxin shows what each one costs. It can also remind you about, turn off or delete a machine that sits idle. ## Do I need to install anything on my machines? No. If you can `ssh` into it with a key, Muxin can add it. Muxin installs its own small helper and keeps it up to date. On Windows, turn on OpenSSH Server first. ## Do my machines need to be on the same network? No. Muxin reaches any machine you can `ssh` into. With Tailscale, that works from anywhere. ## Which agents does it work with? Claude Code, Codex, OpenCode, Gemini CLI, Amp, Pi, or a plain shell. Muxin finds which ones each machine has. ## Can my AI agents use Muxin? Yes. Muxin has an MCP server with 90+ tools, so Claude Code, Codex or any MCP client can use your machines. Muxin tells them to ask you before changing anything. [Set it up](/docs/agents). ## How do I update it? Muxin tells you when a new version is out, in the sidebar. About shows how to update the copy you have: with Homebrew or the AUR, or the new file to download, which installs over the old one and keeps your settings. Linux packages update with your package manager. ## Wasn’t it called Muxen? Yes. Muxin was called Muxen before 0.5.1. Updating keeps your settings, machines and sessions. The `muxen` command still works too. ## Where can I read how it works? In the [docs](/docs), with pictures of each step. AI agents can read them too, at [llms.txt](/llms.txt). Source: https://muxin.dev#faq