Mission control for AI coding agents — on your own infrastructure. Describe a task from your phone. An agent picks it up on a box you own, works in an isolated git worktree inside tmux, streams every step live, pings you for approvals, and hands you a reviewable diff.
AgentDeck is a self-hosted kanban board that dispatches AI coding agents onto your machines — anything you can SSH into, from a spare laptop or a VPS to a Raspberry Pi or a Proxmox cluster. Every task runs in its own git worktree, streams a live timeline to a mobile-first PWA, and gates risky tool calls behind approvals that hit your phone. Bring your own agent and your own model. The control plane is self-hosted; your chosen agent and model provider determine where prompts and code are processed. A git worktree isolates changes, not operating-system access; use target and permission policies accordingly.
One binary, no runtime. The control plane is a single static Go binary with the PWA and the agent-side hook scripts embedded. Copy it to a box and run it.
Tasks and sessions. A task is work you hand off — dispatch, walk away, review a diff. A session is an agent you work with, for days: it lives in tmux, agentdeck watches its status and screen. Tap Chat for a large-text live reader and multiline composer on your phone. When its context fills up, ask it to write a handoff and hand the thread to a fresh one. It will also discover and adopt the Claude and Codex sessions you started yourself, without disturbing them.
Runs on your hardware. A target is any box with SSH — or the machine
AgentDeck itself runs on. Proxmox users get native extras (pct targets and
ephemeral sandbox containers cloned per task, destroyed after), but nothing
requires Proxmox. You choose where agents execute and which providers they use.
Built for your phone. The whole control loop — dispatch, live timeline, mobile diff review, approve/deny — is designed thumb-first. Approvals arrive as web-push, Discord, or ntfy notifications (ntfy carries approve/deny buttons inline).
Attach files from your phone or desktop. Open a session or task → Chat → 📎 Attach, or drop files onto the composer / paste an image. PDFs, images, text, and other documents are accepted (25 MiB per file, up to 10 per message). Files are copied to the agent's actual machine, including SSH and adopted tmux sessions. Add your instructions and press Send; an attachment by itself can also be sent. Uploading alone does not send a message. Reading a document uses that agent's available file tools; AgentDeck preserves the original bytes.
Uploads live in .agentdeck/context/ under the session directory (the project
repository for tasks), with private permissions and a local Git exclusion.
They stay there for later turns. Removing an attachment from the composer removes
its message reference; it does not delete the uploaded file. Draft references
survive reopening Chat on the same browser. Disposable sandboxes do not yet
support attachments. If AgentDeck sits behind nginx, set
client_max_body_size 26M; to allow a 25 MiB file plus multipart overhead.
Keep talking while tasks run. Open a task and tap Chat to read its conversation, send corrections, and answer approvals. Messages wait for the current run, or choose Interrupt and send to change direction immediately. Follow-ups reuse the worktree and resume Claude/Codex conversation context. Messages survive server restarts; drafts stay on your device. Backlog messages add instructions without dispatching. Ephemeral sandbox tasks queue a fresh container with the previous result; interruption is unavailable there.
Any agent, any model — including fully local. Claude Code, Codex, and
Gemini ship with adapters, and the adapter seam is small enough to add your
own. Point a project's env at any Anthropic-compatible endpoint (Ollama,
LiteLLM, vLLM) to drive whatever model you run.
docker compose -f deploy/docker-compose.yml up -d # → http://localhost:9110For a terminal-only workspace on the same computer as your agent, install the standalone local command. It needs no hosted server, SSH alias, or Grimoire:
git clone https://github.com/JeremiahM37/agentdeck.git
cd agentdeck
bash tools/install-local.sh
agentdeck localUse agentdeck-local in that last command if the installer reported that the
existing remote agentdeck launcher was kept.
See Standalone local AgentDeck for Linux, macOS, and WSL installation and the difference between local and remote operation.
Project-specific optional Spec Kit and Maestro workflows are documented in Project workflows.
…or build the binary
npm ci --prefix frontend # Node 24 at build time
npm run build --prefix frontend
python3 frontend/scripts/stage.py
go build -o agentdeck ./cmd/agentdeck
./agentdeck serve # → http://<host>:9110
# In an interactive terminal, a bare `agentdeck` opens the terminal dashboard.One static binary with the PWA, the agent-side hook scripts and a pure-Go SQLite
driver embedded in it. Nothing to install alongside, nothing to pip at deploy
time — copy the file and run it.
Kick the tires with zero setup — mock mode ships a full demo board with fake agents (no git/tmux/claude needed):
AGENTDECK_MOCK=1 ./agentdeck serveThen register a target + project in the Targets tab (or POST /api/targets /
POST /api/projects) and dispatch from the board. A real target needs only SSH
reachability, git, tmux, python3, and your agent's CLI.
These captures use the current React UI with disposable sample projects. The memory walkthrough connects real AgentDeck and Grimoire servers; the terminal workspace uses real tmux and ttyd. No production notes or credentials appear.
Switch between tasks and long-lived sessions, read conversations, send files, review patches, and respond to approvals. Tasks have their own worktrees; sessions can share an existing repository or use managed workspaces.
Attach to the running process with keyboard input, terminal search, retained scrollback, file browsing, upload/download, diff review, and a split shell. Open multiple terminal tabs without stopping the agents when you switch away.
Use agentdeck console with an explicit AGENTDECK_API for the hosted
dashboard, or agentdeck local for a private runtime on your own computer.
The terminal dashboard manages sessions, tasks, projects, targets, agents,
skills, and routines through the same API. Native tmux attachment preserves the
agent's real terminal rather than reconstructing it from logs.
Inspect the project brief before launch. New projects get their own Grimoire memory location automatically when the integration is enabled; renaming a project does not lose its memory.
Reproduce these screenshots and the real provisioning/scope checks:
go build -o /tmp/agentdeck-showcase ./cmd/agentdeck
.venv/bin/python tools/capture_memory_showcase.py \
--grimoire-root /path/to/grimoire \
--agentdeck-bin /tmp/agentdeck-showcaseBuild Grimoire's server and frontend first. The capture tool needs Python Playwright/Chromium, git, tmux, and ttyd. Everything runs on loopback with temporary databases, a separate vault, and a private tmux socket.
-
Context continuity — Grimoire briefs retain source, trust, and human/agent authority. Session setup distinguishes unavailable memory, partial retrieval, and a successful search with no relevant notes; starting work stays available.
-
Completed handoffs — a fresh agent starts only after its predecessor publishes a complete handoff with a marker unique to that request. Partial or stale files cannot retire the old session.
-
Running build — Targets shows the serving binary's version, commit, and whether it includes local changes. Missing build metadata is shown as unknown.
-
Board — kanban (mobile PWA + desktop), quick-dispatch bar, drag-to-dispatch, live SSE timeline, mobile diff review, and a desktop Deck multi-pane cockpit.
-
Sessions — long-lived interactive agents, grouped by project. Live status (working / wants you / idle) derived from the pane itself, uptime and idle time taken from tmux's own clock, a preview of what is on screen, one-tap terminal attach, send-a-message and interrupt from your phone, discovery + adoption of agents you started by hand, and handoff: the agent writes a wrap for its successor, which starts primed with it. The project outlives the context window.
-
Blank rooms — start any agent CLI in a throwaway git repository with no project attached, for work that does not have a name yet. When it turns into something, promote it: the directory it has been working in becomes the project's repository, so nothing moves, the tmux session keeps running, and the project is immediately dispatchable.
-
Import — point it at where your code lives; it registers everything that looks like a project (git repo, build manifest, or a HANDOFF.md).
-
Targets —
localandsshcover any machine; Proxmox users also getpct(no SSH needed) andsandbox(ephemeral container: clone → run → capture → destroy). Deep credentials probe included. A per-targetcommand_prefixhandles hosts whose SSH lands somewhere other than the work —wsl -e bash -lc "echo {b64} | base64 -d | bash"makes a Windows box with its toolchain in WSL an ordinary target. -
Agents — Claude Code, Codex and Gemini ship built in. Sessions take any CLI, and tasks/routines can use any configured CLI with a declared batch
taskdefinition: define it inPUT /api/agentswith its commands, output mode, permission mappings and provider env, and it appears in the picker — the board holds no opinion about which binary runs. Local models use the CLI's compatible endpoint variables through a project'senv. See docs/agents.md. -
Control loop — hook-gated approvals with web-push + Discord/ntfy sinks, an always-allow policy engine, follow-ups, auto-verify, reviewer gates, A/B parallel attempts, agents that file their own task cards, and shared project memory.
-
Context parity — staged context files, per-project MCP servers, and permission rules, so an agent on a remote target knows and can do what one on your own machine does (docs/context-parity.md).
-
Ops — worktree janitor, cost stats, task templates, one-click ttyd terminal attach, and an MCP server so any MCP client can file and steer tasks.
Attach opens the actual agent terminal with file drop, screenshot paste, searchable tmux history, saved appearance settings, and an optional persistent shell alongside it. A file drawer previews text, images and PDFs and downloads artifacts. Uploads insert the path on the agent's machine without pressing Enter.
Open in terminal opens your device's default terminal on the same session,
keeping the browser attached; either view can remain open and both use the same
tmux process. Connection setup is available under Tools. The installed client
opens the terminal dashboard when run without a subcommand; use agentdeck serve
for the control-plane process.
The shared tmux screen fits the smaller connected terminal, so a larger native
window cannot crop the browser into a blank view. Attachments open as tabs inside
AgentDeck; Pop out remains available.
Middle-click inside the terminal, then move the pointer up or down to autoscroll; move farther from the starting point to scroll faster. Escape, another click, or typing stops it. Slim scrollbars remain available for terminal scrollback and retained history. Returning to the bottom resumes live output automatically. See Terminal workspace.
Run agentdeck console on your server to manage sessions, tasks, routines,
projects, targets, approvals and settings. Install the client on your computer
to run agentdeck directly from your terminal. In the live dashboard, use
arrow keys to select a session and Enter to attach; m opens actions and ?
shows shortcuts. Use agentdeck console --plain for the line-oriented menu.
Press Ctrl+B, then D to detach and return to the menu without stopping
the session. Skip the menus with agentdeck attach session ID.
For a fast command prompt, run agentdeck shell [MACHINE]. It chooses a
configured machine (with a searchable picker when omitted), creates a tracked
blank persistent shell, and attaches immediately. There is no project, agent,
or model setup; run any commands or model CLI in the shell. Ctrl+B then D
detaches without stopping it. The dashboard provides the same action with S
or Actions → Open blank shell.
Remote CLI attachments automatically use a portable xterm-256color terminal
type for SSH, so a server without your terminal emulator's terminfo can still
attach. This applies to both the menu and direct command; no manual TERM
override or local terminal configuration change is needed. After updating the
client, quit and reopen any running CLI menu to use the new version.
The CLI also includes PDF/file uploads, downloads, and a scriptable API:
agentdeck api GET /sessions
agentdeck api POST /tasks/12/takeover '{}'
agentdeck upload session 4 ./requirements.pdf
agentdeck attach session 4Client installation and commands · Workspace navigation · Routine takeover
Run agentdeck in a terminal for a live session dashboard with project/target
groups, fuzzy search, status filters, previews, one-key attachment, and keyboard
forms. Tasks, routines, targets, approvals, context uploads and worktree diff
review are available without opening the browser. Ctrl-b then d returns from an
attached session. Use agentdeck serve to run the server explicitly, or
agentdeck console --plain for the line-oriented client.
See terminal client for installation and shortcuts,
and the bounded terminal experience comparison
for the current evidence ledger.
AgentDeck owns execution: projects, targets, tasks, approvals, worktrees, terminal sessions, and recovery. Grimoire owns durable knowledge: Markdown notes, accepted facts, source provenance, correction history, retrieval, and optional credential brokering. Neither requires the other.
AGENTDECK_GRIMOIRE_URL=http://127.0.0.1:9111
AGENTDECK_GRIMOIRE_CONTEXT_MODE=projectSupply these in your service environment; configure the provider credential there if your Grimoire instance requires one. Use HTTPS for a remote instance.
- Create, import, or promote a project. AgentDeck records a unique memory topic and creates its note in Grimoire. The association survives renaming.
- Launch or dispatch. Only that project's memory is consulted by default; unassigned scratch sessions do not get automatic project memory.
- Keep working. Messages sent through Deck get relevant, deduplicated context. Retrieval uses no language or embedding model and is bounded to 2,400 bytes by default. A short destination hint tells the agent where to store durable facts; raw conversations are not automatically saved.
- Correct and continue. Grimoire retains provenance and protects recognized human corrections. Requested handoffs write to the same project topic, so knowledge can outlive the agent session.
Choose manual/off for no automatic lookup, project for assigned-project
scope, or explicitly opt into all. Per-project path and budget overrides are
available. Setup failures appear in memory_status and the brief preview; retry
POST /api/projects/{id}/memory without overwriting existing notes.
Direct typing into an attached terminal bypasses Deck's send API. Grimoire's optional native prompt hook covers that path when installed with the same scope. It is not silently installed, and Deck never passes its administrative credential into the agent. See automatic memory for configuration, legacy-project mappings, and limitations.
Set a project's env to route its agent at any Anthropic-compatible API:
curl -X POST .../api/projects -d '{
"name":"myrepo","target_id":1,"repo_path":"/srv/myrepo",
"env":{"ANTHROPIC_BASE_URL":"http://ollama-host:11434",
"ANTHROPIC_AUTH_TOKEN":"ollama"}}'
# then dispatch with "model":"qwen3.5:35b-a3b" (or any served model)Driving agentic coding (tool calls, edits) needs a capable model — small local models often reply conversationally instead of acting. The transport works with any model; results depend on the model.
ADK_ISOLATION_REVIEWED=1 ADK_TEST_MODE=go tools/run-isolated-tests.sh .
ADK_ISOLATION_REVIEWED=1 ADK_TEST_MODE=e2e tools/run-isolated-tests.sh .Read the isolation runner before setting its acknowledgement variable. It uses
bubblewrap with private process/network namespaces and tmux state so tests
cannot attach to or alter your real agents. Most tests use a mock executor —
no git, tmux or agent binary — so
they are fast and hermetic. A handful deliberately do not: e2e_real_test.go
dispatches into a real git worktree, starts a real tmux session, runs a real
process and reads back its real diff and exit code, and restart_test.go runs
two App lifetimes over one database file. Those are the tests that catch what
mocks accept: argv that a real shell truncates, a launch race that only exists
once a process starts, a base branch that git init did not create. They skip
themselves if git or tmux is missing.
cmd/agentdeck/ the binary
internal/api/ REST + hook endpoints, SSE streams, embedded PWA
internal/scheduler/ promotes queued attempts, tails running ones, finalises
internal/executor/ local | ssh | pct | sandbox | mock target executors
internal/agents/ per-agent launch commands and stream parsers
internal/hooks/ PreToolUse approval hook + agent kit (stdlib Python, embedded)
internal/store/ SQLite schema and typed row accessors
frontend/ React + TypeScript browser and terminal workspaces
web/ generated assets embedded in the Go binary
e2e/ Playwright browser tests
DESIGN.md full design doc — architecture, feature catalog, roadmap
Config via env: AGENTDECK_PORT (9110), AGENTDECK_DB, AGENTDECK_BASE_URL
(URL targets use to reach this server for approval callbacks), AGENTDECK_AUTH_TOKEN
(optional bearer), AGENTDECK_VAPID_PUBLIC/_PRIVATE (web push), AGENTDECK_MOCK.




