Skip to content

Repository files navigation

English · 한국어

AgentBoard

Run a fleet of AI coding agents from anywhere — even your phone.

Python 3.12 FastAPI React 19 TypeScript Vite xterm.js AGPL v3 License CI


AgentBoard is a browser-based command center for running many AI coding agents in parallel — across as many machines as you like. Spawn Claude Code, Codex, Aider, or any shell-based agent in its own tmux session, switch between them with a tap, and pick up exactly where you left off — from your laptop, your tablet, or your phone. Sessions running on several PCs (even behind NAT) aggregate into one dashboard.

Designed for the moment your agents outgrow a single terminal tab — and then a single machine.

Grid view: three agents working in parallel — one asks for confirmation, approved with a single ⏎, and it carries on to Done

Phone: open the waiting agent, tap Yes on the quick-approve bar, watch it finish   Phone view: workspace list with live per-folder state chips

A real, unedited Claude Code session driven through AgentBoard — it adds rate limiting, verifies with a test client, and reports back:

A real Claude Code session in AgentBoard: it edits src/server.py to add slowapi rate limiting, runs a TestClient to verify 429s, and summarizes what it changed

More demos — the file workspace and the review → agent loop

File workspace: upload a file, read rendered markdown, tick a task checkbox (saved to the file), then edit code and save

Review loop: select code in the viewer, attach a note, send it — the note lands directly in the agent's prompt

Why AgentBoard

Modern coding agents are most useful when they run for minutes or hours, not seconds. Soon you're juggling three, five, ten of them — and tmux alone gets old fast on mobile. AgentBoard wraps tmux in a clean dashboard that:

  • Just works on mobile. Real touch scroll with momentum, no broken gestures, no pinch traps. Built and tuned on actual devices, not emulators.
  • Knows what each agent is doing. Each session shows an idle / working / waiting badge derived from its terminal output.
  • Refuses to lose state. Sessions live in tmux — they survive page reloads, server restarts, and flaky networks.
  • Is honestly fast. 80 ms screen refresh on the session you're looking at, 2 s on the rest. Adaptive, never wasteful.

Built for these moments

  • Long-running refactors — kick off an agent at your desk, check its progress from your phone over coffee, tap once to send y when it asks for confirmation.
  • Parallel coding — three agents on three branches, one dashboard, zero context-switching tax.
  • Pair-programming with yourself — the same tmux state, viewed live from any device on the network.
  • Tablet-first development — file browser, code editor, PDF viewer, and a live terminal — all in one tab.

Features

Multi-session terminal Spawn, kill, rename, and switch between unlimited tmux sessions
Multi-machine Aggregate sessions from several PCs in one dashboard; remote agents dial out, so NAT/firewalls are no obstacle
Mobile-first UI Custom touch handlers — momentum scroll, scroll-to-bottom, on-screen keys (PgUp/PgDn, ⌫), keyboard-friendly input
Live state detection Per-session badges: idle, working, waiting-for-input
Push notifications Web Push fires an OS notification when a session goes waiting or completed — even on iOS (installed PWA)
Adaptive polling 80 ms on the active session, 2 s on background sessions
File browser & editor CodeMirror 6 with syntax highlighting for 13+ languages, plus a git-diff view
Markdown + KaTeX Notion-style rendered view, clickable task-list checkboxes, sanitized HTML, math rendered server-free
Jupyter notebooks Read-only .ipynb viewer — rendered cells, syntax-highlighted code, images/tables/errors
PDF & image viewer PDF zoom (50–300%), fit-to-width; images pan/zoom; all lazy-loaded for instant boot
Cookie auth Single password, HMAC-SHA256 signed, per-IP login throttling
Optional Cloudflare tunnel Expose the dashboard publicly with one env var
Survives everything tmux-backed sessions persist across reloads, restarts, and disconnects

Quick start

Docker (fastest)

git clone https://github.com/ralbu85/AgentBoard.git
cd AgentBoard
DASHBOARD_PASSWORD=pick-a-password docker compose up -d --build

Open http://localhost:3002 and log in. Sessions run bash by default — the image ships no AI CLIs, so install what you need (e.g. docker compose exec agentboard npm install -g @anthropic-ai/claude-code) or extend the image. Mount your projects by setting AGENTBOARD_WORKSPACE=/path/to/projects.

Manual (bare metal)

Prerequisites: tmux, Python 3.12, Node 20+.

git clone https://github.com/ralbu85/AgentBoard.git
cd AgentBoard

python3.12 -m venv backend/.venv
backend/.venv/bin/pip install -r backend/requirements.txt
(cd frontend && npm install)

echo "DASHBOARD_PASSWORD=pick-a-password" > .env

./deploy.sh        # builds the frontend, starts the server, waits for /api/health

Open http://localhost:3002, log in, hit + New — and you're spawning agents. The server binds to loopback by default; set AGENTBOARD_HOST=0.0.0.0 in .env for LAN access, or put a reverse proxy (nginx/Caddy) in front for HTTPS.

Add more machines (optional)

Every extra PC runs a lightweight agent that dials outbound to your hub — so machines behind NAT or a firewall just work, no SSH or port-forwarding. On each remote PC:

git clone https://github.com/ralbu85/AgentBoard.git && cd AgentBoard
python3.12 -m venv backend/.venv
backend/.venv/bin/pip install -r backend/requirements.txt   # tmux required too

export AGENT_HUB_URL=wss://your-hub-host/agent-ws   # ws:// needs AGENT_INSECURE=1
export AGENT_TOKEN=<the hub's AGENT_TOKEN>           # defaults to its auth token
export AGENT_HOST_LABEL="Office PC"                  # display name (optional)
agent/start-agent.sh

The machine appears in the dashboard within seconds; its sessions show up as office:1, office:2, … and everything (spawn, kill, input, push notifications) works exactly like local sessions. Use wss:// in production — the token grants shell access, so don't send it in plaintext.

Architecture

   Browser (xterm.js + React)
            │
            │  HTTPS / WSS
            ▼
     nginx :12019
            │
            ▼
     uvicorn :3002 ──── pipe-pane FIFO
            │           capture-pane polling
            ▼
       tmux sessions
Layer Stack
Frontend React 19, xterm.js 5.5, Zustand, Vite, CodeMirror 6
Backend FastAPI, asyncio, tmux via async subprocess
Auth HMAC-SHA256 signed cookie
Proxy nginx (optional, recommended for HTTPS)

API

REST

Method Path Body
POST /api/login {pw}
GET /api/workers
POST /api/spawn {cwd, cmd}
POST /api/kill {id}
POST /api/remove {id}
POST /api/input {id, text}
POST /api/key {id, key}
GET /api/browse?path= directory listing
GET /api/files?path= file metadata
GET /api/file?path= read file
POST /api/file {path, content}
GET /api/health readiness probe

WebSocket /ws

  • Client → server: resize, active, resync, title, key, terminal-input, input
  • Server → client: spawned, snapshot, screen, stream, status, cwd, aiState, info, title, titles

Project layout

backend/
  main.py            FastAPI app, lifespan, static serving
  config.py          .env loading, auth token, project root
  auth.py            HMAC-SHA256 cookie auth
  sessions.py        SessionStore: spawn / kill / recover tmux
  streamer.py        pipe-pane FIFO + capture-pane polling
  state_detector.py  idle / working / waiting heuristics
  tmux.py            async tmux wrappers
  ws.py              WebSocket routing + broadcast
  routes_session.py  REST: login, workers, spawn, kill, input
  routes_file.py     REST: browse, files, read / write
  tunnel.py          optional Cloudflare tunnel

frontend/
  src/
    App.tsx                       root + login flow
    store.ts                      Zustand state
    ws.ts                         WebSocket singleton
    api.ts                        REST wrappers
    components/Terminal/          xterm.js lifecycle, mobile scroll
    components/Sidebar/           session list, mobile overlay
    components/Viewer/            split layout, code editor, file content
    components/SpawnModal/        new-session dialog
    components/FilePanel.tsx      file browser
    components/PdfViewer.tsx      PDF rendering
    components/Header.tsx         status bar, + New
    components/Login.tsx          password login
    components/Toaster.tsx        toast notifications

Notes for contributors

A few non-obvious decisions that have already burned someone:

  • Static assets are served no-cache. Build outputs use fixed names (app.js, index.css); cache busting is via a ?v=<timestamp> query injected by deploy.sh. Never add a client-side setTimeout auto-reload — it loops on slow mobile.
  • xterm.js native touch is disabled (pointer-events: none on .xterm*). A custom handler on .xterm-wrap drives mobile scroll. Playwright's CDP touch direction is the opposite of real devices — trust real-device feedback over emulator output.
  • Raw stream is not applied to the client. Pipe-pane output contains escape sequences that destroy the scrollback. The client receives writeScreen (in-place capture-pane) and a one-time writeSnapshot on session switch.
  • Always launch from the project root. start.sh and deploy.sh handle this — they cd first so backend.main resolves correctly.

License

GNU AGPL-3.0 © 2026 Jihwan (James) Lee.

Free to use, modify, and self-host. The AGPL's network clause means that if you run a modified version as a service over a network, you must offer your users the modified source. For a commercial license without the AGPL obligations, contact the author.

About

Browser-based dashboard for managing multiple Claude Code sessions. Monitor, control, and get notified — no SSH needed.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages