An open API service indexing awesome lists of open source software.

https://github.com/batalabs/muxd

An open-source AI coding agent that lives in your terminal. Multi-provider, multi-channel, persistent sessions with git-like branching.
https://github.com/batalabs/muxd

ai-assistant anthropic cli code-generation coding-agent developer-tools fireworks-ai golang grok llm ollama openai terminal tui

Last synced: 29 days ago
JSON representation

An open-source AI coding agent that lives in your terminal. Multi-provider, multi-channel, persistent sessions with git-like branching.

Awesome Lists containing this project

README

          


muxd


muxd


An open source AI coding agent that lives in your terminal.

37 tools. Any model. Sessions that survive reboots. An agent that builds its own tools.


mux = multiplex your sessions  ·  d = daemon daemon (Unix tradition)


Early Release
Version
Last Commit
Go 1.25+
Windows | Linux | macOS
Apache 2.0

> **Full docs at [muxd.sh](https://muxd.sh/docs)** · [Client setup](https://muxd.sh/docs/client) · [Hub setup](https://muxd.sh/docs/hub) · [Commands](https://muxd.sh/docs/commands) · [Tools](https://muxd.sh/docs/tools) · [Config](https://muxd.sh/docs/configuration)

---

## Architecture

muxd has four components. Run them all on one machine for local dev, or distribute them across servers for a team setup.

| Component | Binary | Role |
|---|---|---|
| **muxd** | `muxd` | Terminal TUI client |
| **muxd-daemon** | `muxd-daemon` | Agent server (sessions, tools, model calls) |
| **muxd-hub** | `muxd-hub` | Hub coordinator (nodes, workers, webhooks) |
| **Web UI** | served by hub | Browser dashboard for workers and nodes |


muxd architecture

### muxd Terminal Client

The TUI you interact with. Connects to a local daemon or a remote hub. Pure client, no agent logic.

```bash
muxd # connect to local daemon
muxd --remote hub.example.com:4097 --token x # connect to remote hub
```

Flags: `--version`, `--remote `, `--token `

### muxd-daemon Agent Server

Headless server that runs sessions, executes tools, talks to model APIs. One per machine.

```bash
muxd-daemon # start on localhost:4096
MUXD_BIND=0.0.0.0 muxd-daemon # listen on all interfaces
```

Configuration is via `config.json` or environment variables:

| Env Var | What |
|---|---|
| `MUXD_MODEL` | Model name or alias (e.g. `claude-sonnet`) |
| `MUXD_PROVIDER` | Provider name (e.g. `anthropic`, `openai`) |
| `MUXD_BIND` | Network interface to bind (default: `localhost`) |
| `MUXD_HUB_URL` | Hub URL to register with |
| `MUXD_NODE_NAME` | Node name (defaults to hostname) |

### muxd-hub Hub Coordinator

Central coordinator for multiple daemons. Manages node registration, worker lifecycle, webhooks, and serves the web UI.

```bash
muxd-hub # start on localhost:4097
MUXD_HUB_BIND=0.0.0.0 muxd-hub # listen on all interfaces
```

| Env Var | What |
|---|---|
| `MUXD_HUB_BIND` | Network interface to bind |
| `MUXD_HUB_TOKEN` | Auth token (auto-generated if not set) |
| `MUXD_WEB_DIR` | Path to web UI static files (enables web dashboard) |

### Web UI Browser Dashboard

React + Vite + Tailwind dashboard for managing workers and monitoring nodes. Served by the hub when `MUXD_WEB_DIR` is set (automatic in Docker).

Pages:
- **Dashboard** — nodes, workers, sessions, cost overview
- **Workers** — create and manage autonomous agents triggered by webhooks or schedules
- **Worker Detail** — activity feed with approve/reject for human-in-the-loop
- **Nodes** — registered daemon nodes with status

```bash
# Local dev
cd web && npm run dev # starts on :5173, proxies /api to hub on :4097

# Production (built into hub)
MUXD_WEB_DIR=/var/lib/muxd/web muxd-hub
```

---

## Configuration

All three binaries share one config file at `~/.config/muxd/config.json`. Each binary only reads the fields it needs.

| File | Location | Purpose |
|---|---|---|
| `config.json` | `~/.config/muxd/` | Shared config for all binaries |
| `muxd.db` | `~/.local/share/muxd/` | Sessions, messages, branches (daemon) |
| `hub.db` | `~/.local/share/muxd/` | Nodes, workers, memory, logs (hub) |
| `server.lock` | `~/.local/share/muxd/` | Daemon PID, port, token (auto-managed) |

### Config fields by binary

**muxd** (TUI client): `model`, `provider`, `hub_url`, `hub_auth_token`

**muxd-daemon** (agent server): `model`, `provider`, API keys, `daemon_bind_address`, `hub_url`, `hub_node_token`, `hub_node_name`

**muxd-hub** (coordinator): `hub_bind_address`, `hub_auth_token`

### Setting values

Three ways to configure, in priority order:

1. **Environment variables** — override everything (e.g. `MUXD_MODEL=claude-sonnet`)
2. **`config.json`** — persisted settings, edited via `/config set ` in the TUI
3. **Defaults** — sensible defaults when nothing is set

API keys follow the same pattern: set in `config.json` via `/config set anthropic.api_key `, or use the standard env var (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc).

### Key config values

| Key | Env var | What |
|---|---|---|
| `model` | `MUXD_MODEL` | Default model (e.g. `claude-sonnet`) |
| `provider` | `MUXD_PROVIDER` | Default provider (e.g. `anthropic`) |
| `daemon_bind_address` | `MUXD_BIND` | Daemon bind interface |
| `hub_url` | `MUXD_HUB_URL` | Hub URL for daemon registration |
| `hub_node_token` | `MUXD_HUB_NODE_TOKEN` | Token for daemon to register with hub |
| `hub_node_name` | `MUXD_NODE_NAME` | Node name (defaults to hostname) |
| `hub_bind_address` | `MUXD_HUB_BIND` | Hub bind interface |
| `hub_auth_token` | `MUXD_HUB_TOKEN` | Hub auth token |

---

## What makes muxd different

Most AI coding tools treat conversations as disposable. muxd saves everything to local SQLite. Close your terminal, reboot, come back next week, and pick up exactly where you left off.

### Agent capabilities

| | |
|---|---|
| **37 built-in tools** | File I/O, bash, grep, glob, web search, HTTP, SMS, git, scheduling, document reading, parallel pipeline, LSP, and more |
| **Any model** | Claude, GPT, Gemini, Mistral, Grok, GLM, Fireworks, DeepInfra, Ollama, or any OpenAI compatible API |
| **Inline diffs** | Every file edit shows a red and green diff in the chat. See exactly what changed |
| **Read any document** | PDFs, Word, Excel, PowerPoint, HTML, CSV, JSON, XML. No plugins required |
| **Self extending tools** | The agent creates its own tools at runtime. Command templates or scripts, ephemeral or persistent |
| **Second opinion** | Ask a different model for a review. Response shown separately with a crystal ball emoji |
| **Chat modes** | Code (read/edit/run), Ask (read-only), Architect (plan only). Switch with `/mode` |
| **Repo map** | Auto-generated codebase overview injected into context for better navigation |
| **Parallel pipeline** | Run sub-agents concurrently with a live DAG showing animated spinners and per-task activity |
| **Code intelligence** | LSP integration with go-to-definition, references, hover, diagnostics, and symbol search across Go, TypeScript, Python, Rust, and C/C++ |

### Session management

| | |
|---|---|
| **Persistent sessions** | Conversations survive restarts. Resume any session by project or ID |
| **Branch and fork** | Explore alternatives without losing your thread. Like git branches for conversations |
| **Project memory** | The agent remembers your conventions and decisions across sessions |
| **Smart compression** | Tiered compaction at 60k/75k/90k tokens. Preserves key decisions while cutting costs |

### Infrastructure

| | |
|---|---|
| **Hub architecture** | Coordinate multiple daemons across machines. Connect from any TUI or mobile client |
| **Copy mode** | Press Ctrl+S to toggle mouse tracking for native text selection. Arrow keys scroll the viewport |
| **Always on daemon** | Background service that survives reboots. Auto titles, schedules tasks, runs headless |
| **Mobile app** | [iOS app](https://apps.apple.com/us/app/muxd/id6759869997) connects via QR code. Chat with your agent from anywhere |
| **Hub dispatch** | Send tasks to remote nodes. The agent can delegate work across your machines |
| **Web dashboard** | Browser-based UI for workers, nodes, and activity monitoring |

---

## Demo


muxd demo


muxd mobile - node picker
    
muxd mobile - chat

---

## Install

**Windows (PowerShell)**
```powershell
irm https://raw.githubusercontent.com/batalabs/muxd/main/install.ps1 | iex
```

**macOS / Linux**
```bash
curl -fsSL https://raw.githubusercontent.com/batalabs/muxd/main/install.sh | bash
```

**From source** (requires [Go 1.25+](https://go.dev/dl/))
```bash
go install github.com/batalabs/muxd@latest
```

**Prerequisites**: git (for undo/redo) and an API key for at least one [supported provider](https://muxd.sh/docs/configuration).

---

## Quick Start Binaries

### 1 machine: daemon + TUI

Everything local. Two terminals, no hub.

```bash
# Terminal 1: start the daemon
muxd-daemon

# Terminal 2: start the TUI (auto-discovers the daemon)
muxd
```

### 1+1: hub + daemon on the same server

One server runs the hub and daemon. You connect from your laptop.


1+1 setup

```bash
# 1. Install (as root)
curl -fsSL https://raw.githubusercontent.com/batalabs/muxd/main/install.sh | sh

# 2. Set up env vars (as your user, on minimal servers without a desktop)
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus

# 3. Install and start the hub service
MUXD_HUB_BIND=0.0.0.0 muxd-hub -service install
muxd-hub -service start

# 4. Keep services running after SSH logout (as root)
su - -c "loginctl enable-linger $USER"

# 5. Get the QR code and token
muxd-hub -service qr

# 6. Install and start the daemon (on the same server)
muxd-daemon -service install
MUXD_HUB_URL=http://localhost:4097 MUXD_HUB_NODE_TOKEN= muxd-daemon -service start
```

```bash
# On your laptop: connect to the hub
muxd --remote :4097 --token
```

Open `http://:4097` in your browser to see the web dashboard.

### 1+2: hub and daemon on separate servers

Dedicate one server to the hub, another to the daemon. More secure: your API keys only live on the daemon server.

```bash
# Server A (hub): coordinate nodes
muxd-hub # prints token + QR code

# Server B (daemon): runs the agent
MUXD_HUB_URL=http://server-a:4097 \
MUXD_HUB_NODE_TOKEN= \
MUXD_NODE_NAME=worker-1 \
muxd-daemon

# Your laptop: connect to hub
muxd --remote server-a:4097 --token
```

### Adding more servers (1+n)


1+n setup

Each additional machine just runs `muxd-daemon` pointing at the hub:

```bash
# Server C, D, E... each run:
MUXD_HUB_URL=http://server-a:4097 \
MUXD_HUB_NODE_TOKEN= \
MUXD_NODE_NAME=worker-3 \
muxd-daemon
```

The hub shows all nodes in the web dashboard. Use `/nodes` in the TUI to pick which node to run sessions on.

---

## Quick Start Docker

First build the images:

```bash
git clone https://github.com/batalabs/muxd.git
cd muxd
docker compose build
```

API keys can be passed as env vars or set inside the TUI with `/config set .api_key `:

| Provider | Env var |
|---|---|
| Anthropic | `ANTHROPIC_API_KEY` |
| OpenAI | `OPENAI_API_KEY` |
| Google | `GOOGLE_API_KEY` |
| Mistral | `MISTRAL_API_KEY` |
| Grok | `XAI_API_KEY` |
| ZAI (GLM) | `ZAI_API_KEY` |
| Fireworks | `FIREWORKS_API_KEY` |
| DeepInfra | `DEEPINFRA_API_KEY` |
| Ollama | `OLLAMA_API_BASE` (default: `http://localhost:11434`) |

### 1+1: hub + daemon on one machine

```bash
# Create .env
echo "MUXD_MODEL=claude-sonnet" > .env
echo "ANTHROPIC_API_KEY=sk-ant-..." >> .env

# Start hub + daemon
docker compose up -d

# Connect from your laptop
muxd --remote localhost:4097 --token
```

Open `http://localhost:4097` in your browser to see the web dashboard.

`docker-compose.yml`:
```yaml
services:
hub:
build:
context: .
target: hub
ports: ["4097:4097"]
environment:
MUXD_HUB_BIND: "0.0.0.0"

daemon:
build:
context: .
target: daemon
environment:
MUXD_MODEL: ${MUXD_MODEL:-claude-sonnet}
MUXD_BIND: "0.0.0.0"
MUXD_HUB_URL: "http://hub:4097"
MUXD_HUB_NODE_TOKEN: ${HUB_TOKEN:-}
env_file: .env
```

### 1+2: hub and daemon on separate servers


docker setup

```bash
# Server A (hub)
docker run -d -p 4097:4097 -e MUXD_HUB_BIND=0.0.0.0 muxd-hub

# Server B (daemon)
docker run -d -p 4096:4096 \
-e MUXD_MODEL=claude-sonnet \
-e MUXD_BIND=0.0.0.0 \
-e MUXD_HUB_URL=http://server-a:4097 \
-e MUXD_HUB_NODE_TOKEN= \
-e MUXD_NODE_NAME=worker-1 \
-e ANTHROPIC_API_KEY=sk-ant-... \
muxd-daemon

# Your laptop
muxd --remote server-a:4097 --token
```

### Adding more servers (1+n)

Each additional daemon server is one `docker run`:

```bash
# Server C, D, E...
docker run -d -p 4096:4096 \
-e MUXD_BIND=0.0.0.0 \
-e MUXD_HUB_URL=http://server-a:4097 \
-e MUXD_HUB_NODE_TOKEN= \
-e MUXD_NODE_NAME=worker-3 \
-e MUXD_MODEL=claude-sonnet \
-e ANTHROPIC_API_KEY=sk-ant-... \
muxd-daemon
```

Or add more `daemon` services to your `docker-compose.yml` on each server.

---

## Running as a Service

Install muxd-hub or muxd-daemon as a system service so it starts on boot and survives SSH disconnects.

### Linux (systemd)

```bash
# Install the hub as a user service
muxd-hub -service install
muxd-hub -service start

# Install the daemon as a user service
muxd-daemon -service install
muxd-daemon -service start
```

**Important**: On minimal servers (no desktop environment), set these env vars first:

```bash
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
```

Then keep services running after logout:

```bash
loginctl enable-linger $USER
```

Without `enable-linger`, systemd kills user services when you close your SSH session.

### Service management

```bash
muxd-hub -service status # check if running
muxd-hub -service stop # stop the service
muxd-hub -service uninstall # remove the service
muxd-hub -service qr # re-show the QR code and token
```

Same commands work for `muxd-daemon -service `.

### macOS (launchd)

```bash
muxd-hub -service install # creates ~/Library/LaunchAgents/com.muxd.hub.plist
muxd-hub -service start
muxd-hub -service status
```

### Windows (registry)

```bash
muxd-daemon -service install # adds startup registry entry
muxd-daemon -service start # launches in background
muxd-daemon -service stop # kills process via lockfile
```

---

## Contributing

```bash
git clone https://github.com/batalabs/muxd.git
cd muxd

# Build all binaries
go build -o muxd .
go build -o muxd-hub ./cmd/muxd-hub
go build -o muxd-daemon ./cmd/muxd-daemon

# Run tests
go test ./...

# Web UI
cd web && npm install && npm run dev
```

See [muxd.sh/docs/contributing](https://muxd.sh/docs/contributing) for code style and development guide.

---

## License

[Apache License 2.0](LICENSE)