Documentation
Learn to install, configure, and operate Tetherlab for multi-agent coordination.
Setup
Tetherlab is a coordination layer for multi-agent coding teams. A shim wraps each agent CLI, coaxes a plan from the agent before it acts, and submits that plan to a central master. The master detects conflicts while plans are still words — before a line of code lands.
Getting Started
The shim wraps your agent CLI, coaxes a plan before any action, and submits it to the master. The master detects conflicts at plan stage — before any code lands. The dashboard gives you a live view of intents, concepts, and conflicts.
Quick start
- •Install the tether CLI:TERMINAL
# Homebrew (macOS / Linux) brew install tetherlab/tap/tether # Or via install script curl -fsSL https://raw.githubusercontent.com/tetherlab/tether/main/install/install.sh | sh - •Sign in and configure:TERMINAL
tether login tether init --global --developer aliceThis discovers your SSH key, writes
~/.tether/config.toml, and launches the onboarding wizard. - •Wrap your agent:TERMINAL
tether wrap claude -p "Add a login endpoint"
Open the dashboard at /app/intents to watch your first intent arrive. The shim submits the plan, the master returns continue, stop, or revert.
Installation
# Homebrew (macOS / Linux)
brew install tetherlab/tap/tether
# Install script (macOS / Linux)
curl -fsSL https://raw.githubusercontent.com/tetherlab/tether/main/install/install.sh | sh
# Install script (Windows)
irm https://raw.githubusercontent.com/tetherlab/tether/main/install/install.ps1 | iexThe install script verifies SHA-256 checksums and installs to ~/.tether/bin. Flags include --version, --no-modify-path, and --no-login.
Verify: tether --version and tether doctor.
Shim Setup
The shim reads two TOML config files. Per-project overrides global.
developer = "alice"
master_url = "http://localhost:8080"
ssh_key_path = "/home/alice/.ssh/id_ed25519"
# workspace_id = "" # set after first workspace binddeveloper = "" # inherited from global
master_url = "http://localhost:8080" # inherited
workspace_id = "550e8400-..." # bound by initSSH key discovery precedence: ~/.ssh/id_ed25519 → id_rsa → id_ecdsa → --ssh-key flag. Your SSH public key must be registered with Tetherlab.
Add .tether/ to .gitignore
.tether/ directory contains local config. Add it to your gitignore.Run tether init inside a git repo for project config. The onboarding wizard (tether onboard) walks through identity, workspace binding, and concept bootstrap. Verify with tether status and tether doctor.
Workspaces
Workspaces
A workspace is the coordination unit. Each workspace holds its own intents, concepts, conflicts, agent registrations, and a bare git clone. All coordination happens within a workspace boundary.
| Command | Description |
|---|---|
tether workspace new --name <name> | Create a workspace and bind local repo |
tether workspace new --name <name> --from-remote <url> | Create with a seed remote |
tether workspace use --name <name> | Bind to an existing workspace |
tether clone <name> <dir> | Clone and bind a workspace |
tether pull | Pull with intent-annotated commit summary |
Workspace membership is invite-based. An owner creates an invite from the dashboard at /app/workspace/settings. Members have roles: Owner (full control), Member (submit intents, resolve conflicts), Viewer (read-only).
Coordinating
Wrapping Agents
The shim intercepts the agent process at launch. Before the agent takes any action, the shim coaxes a plan from it, captures a worktree snapshot, and submits both as an intent. Execution proceeds only on continue.
| Tool | Dispatch path | Coordination |
|---|---|---|
| Claude Code | run_coordinated_session | JSONL transcript + hook injection |
| OpenCode | run_coordinated_server | HTTP server API |
| Anything else | run_passthrough | Plain PTY, no coordination |
tether wrap claude -p "Refactor the auth middleware"
tether wrap opencode "Add rate limiting"
tether wrap --continuous claude # multi-plan session
tether wrap npm test # passthroughSafety invariants
- Pre-decision action gate — no agent action before master says continue
- No fabricated intents — plan extraction failure exits without contacting master
- Fail closed on identity — auth errors abort; concept resolve errors warn
Continuous Sessions
Add --continuous to keep the agent alive across multiple plans. After each completion the shim re-enters the planning phase. The agent conversation, context, and file state persist.
tether wrap --continuous claudeThe lifecycle: Plan → Decide (continue/stop/revert) → Execute → Complete (agent emits ::tether-done::) → Await next plan. End the session with ::tether-end-session::. Capped at 100 plans per session (TETHER_MAX_CONTINUOUS_PLANS).
MCP Server
An alternative integration path for agents that speak the Model Context Protocol. The agent calls MCP tools directly instead of being wrapped by the shim.
{
"mcpServers": {
"tether": {
"command": "tether-mcp-server",
"args": ["--continuous"]
}
}
}| Tool | Purpose |
|---|---|
tether.submit_plan | Submit a plan as an intent |
tether.respond_to_proposals | Confirm/reject concept proposals |
tether.mark_executing | Signal execution started |
tether.mark_done | Mark engagement done |
tether.mark_stopped | Mark engagement stopped |
tether.end_session | End the MCP session |
| Feature | Shim (wrap) | MCP Server |
|---|---|---|
| Transport | PTY wrapper | MCP tools over stdio |
| Worktree revert | Supported | Not supported |
| Semantic diff | File watcher | Not available |
| Rescope | Automatic | Manual (agent must submit) |
How Coordination Works
Every wrap session runs through a 14-state machine in the shim.
Idle → Authenticating → PreparingAgent → ExtractingPlan → SubmittingIntent → AwaitingMasterDecision → Executing → WatchingSemanticDiffs → HandlingRescope → AwaitingNextPlan → Complete/Stopped/Reverted/Failed/Done
Each transition is gated. Auth must succeed before the agent spawns. Plan extraction must succeed before an intent is submitted. The master's decision must return before execution.
| Master action | Meaning | Agent behavior |
|---|---|---|
continue | No conflicts. Execute. | Agent proceeds normally. |
stop | Conflict detected. | Agent receives stop message. Shim pauses or exits. |
revert | Conflict with existing changes. | Shim restores agent-modified files from HEAD. |
Conflicts are detected at plan stage, not merge time. When two agents submit intents touching overlapping concepts, the master flags a hard conflict. Overlapping file paths trigger a coarse conflict (tunable via TETHER_COORDINATE_NOT_BLOCK).
Fail-closed design
Dashboard
Web Dashboard
The dashboard uses Supabase Auth (GitHub and Google OAuth) and maintains one WebSocket connection per mount for real-time updates. Workspace switches trigger socket reconnects. Events broadcast by the master update the SWR cache in place.
| Page | Route | Description |
|---|---|---|
| Overview | /app/overview | Activity feed, summary stats |
| Intents | /app/intents | Intent history with filters |
| Concepts | /app/concepts | Concept list and graph canvas |
| Conflicts | /app/conflicts | Conflict list, collapsible cards |
| Agents | /app/agents | Agent status list |
| Team | /app/team | Per-agent work and roster |
| Inbox | /app/inbox | Invites and pending conflicts |
| Settings | /app/workspace/settings | Identity, invites, danger zone |
| Connection | /app/workspace/connection | Master URL connectivity |
Design: Forest Clay dark theme (evergreen + clay + parchment). Poppins for UI, JetBrains Mono for code. 5-level elevation stack.
Desktop App
Tauri 2 + React 19 native app. Mirrors the web dashboard with React Router 7. The Rust backend imports tether-shim-core for local operations. IPC commands: config discovery, SSH identity, master health checks, agent log tailing, git status.
Distributed as .dmg (macOS) and .deb/.AppImage (Linux).
Concepts & Conflicts
Concepts
A concept is a named, semantically meaningful unit of code — "auth module", "rate limiter", "payment handler". Concepts bridge the gap between what an agent says it will change and what files will be modified. They enable intent resolution, conflict detection, and blast radius analysis.
Concept graph edges
| Edge type | Meaning |
|---|---|
realizes | Implementation of an interface/contract |
depends | Uses or imports from another concept |
modifies | Changes behavior of another concept |
breaks | Known to break when source changes |
When the LLM matcher detects concepts not yet in the registry, the master creates proposals and parks the engagement in blocked — the shim prompts the agent (via the developer) to confirm or reject. Duplicate concepts can be merged from the dashboard.
Conflicts
Tetherlab detects conflicts at plan time, before code is written. Overlapping concepts → hard conflict (losing intent gets stop/revert). Overlapping files → coarse conflict (advisory by default). No overlap → parallel execution.
Resolution flow: Conflict appears in dashboard and inbox → loser is blocked → developer resolves (continue/stop/revert/dismiss) → loser unblocks. The dashboard at /app/conflicts shows collapsible cards with winner/loser intents, overlapping concepts, and blast radius visualization. Bulk resolution is supported.
| Gate variable | Values | Effect |
|---|---|---|
TETHER_COORDINATE_NOT_BLOCK | 0 / 1 | When 1, coarse file-path conflicts are advisory |
TETHER_GRAPH_GATE | advisory / enforcing / off | Graph-based conflict enforcement |
TETHER_VERIFY_GATE | off / advisory / enforcing | Post-merge verification gate |
Reference
CLI Reference
The tether binary. All commands read config from ~/.tether/config.toml (global) and .tether/config.toml (project).
| Command | Description |
|---|---|
tether login | Sign in via browser (device authorization) |
tether init | Create config file (global or per-project) |
tether workspace new | Create and bind a workspace |
tether workspace use | Bind to an existing workspace |
tether wrap <tool> | Run under the shim orchestrator |
tether status | Show config, identity, and connectivity |
tether doctor | 7 diagnostic checks (exit non-zero on failure) |
tether onboard | First-run interactive setup wizard |
tether clone <name> | Clone and bind a workspace |
tether pull | Pull with intent-annotated commit summary |
tether bootstrap | Scan repo for concepts (LLM or --graph) |
tether daemon start | Start background daemon |
tether daemon stop | Stop background daemon |
tether daemon status | Show daemon PID and status |
tether graph dump | Export file dependency graph as JSON |
tether memory bootstrap | Mine session history for memory |
| Env var | Default | Purpose |
|---|---|---|
TETHER_WRAPPED | unset | Prevent recursive wrapping |
TETHER_LOG_FILE | ~/.tether/shim.log | Override log path |
TETHER_MAX_CONTINUOUS_PLANS | 100 | Max plans per session |
TETHER_TRANSCRIPT_TIMEOUT_SECS | 600 | Claude transcript deadline |
TETHER_BLOCKED_WAIT_SECS | 3600 | Max wait for unblock |
Troubleshooting
Start with tether doctor. The shim writes logs to file only (not stderr) — check ~/.tether/shim.log.
| Symptom | Likely cause | Fix |
|---|---|---|
| Auth error before agent spawns | SSH key not registered | Register your key on the Tetherlab dashboard |
| Silent exit after wrap | Plan extraction timeout | Check shim log; increase TETHER_TRANSCRIPT_TIMEOUT_SECS |
| Every intent returns stop | Conflict with executing intent | Check /app/conflicts; resolve |
| TETHER_WRAPPED error | Recursive wrapping | Exit inner session before wrapping again |
| Dashboard shows no data | Wrong workspace selected | Check the workspace picker in the sidebar |
| Semantic diff never rescopes | Files not mapped to concepts | Concepts must be created for your project files |
Config & Ops
Config Reference
| Map | File | Key |
|---|---|---|
| Shim TOML | ~/.tether/config.toml | developer, master_url, ssh_key_path, workspace_id, cli_token |
The MCP server reads the same TOML as the shim. CLI overrides: --continuous, --agent claude|opencode, --master-url, --workspace-id, --log-level.
~/.tether/
config.toml # global config
shim.log # shim logs (file-only)
mcp.log # MCP server logs
daemon.sock # Unix domain socket
daemon.pid # PID file
my-project/.tether/
config.toml # project config
hook-dispatch.txt # Claude hook buffer