Skip to content

Getting started

Shepherd is interactive mission control for fleets of Claude Code agents — it runs sessions, drains backlogs into pull requests, and keeps a human in the loop where it matters.

Terminal window
curl -fsSL https://raw.githubusercontent.com/erwins-enkel/shepherd/main/deploy/install.sh | bash

The installer provisions prerequisites, clones the repo to ~/.shepherd/app, builds the UI, and on Linux installs and enables the systemd user service. It also installs the prebuilt shepherd CLI into ~/.local/bin (checksum-verified, from the companion cli-vX.Y.Z release); if no binary is published for the version it only warns and carries on. It is idempotent — safe to re-run: it never clobbers an existing ~/.shepherd/ state dir and never force-resets a dirty checkout.

This is third-party curl|bash: the script runs unconfined as your user before any sandbox exists, and it invokes upstream installers it does not control — bun.sh, fnm (Node), and the claude CLI — plus your distro’s package manager for git, unzip, and the C/C++ build toolchain + python3 (needed for the node-pty native build). herdr is not installed via herdr.dev/install.sh (latest-only); Shepherd downloads a version-pinned release binary from GitHub, verifies the version it reports, and installs it to ~/.local/bin — still third-party code fetched and executed on your machine. In keeping with Shepherd’s radical-transparency posture the script echoes each third-party command before running it. Read it first: deploy/install.sh.

OS Mode Notes
Linux (systemd + unprivileged userns) Full The only fully supported target — sandbox membrane, egress allowlist, auto-drain, Tailscale-serve previews, the systemd user unit, and the hourly DB backup timer.
macOS Core-only / degraded Installs prereqs, clones, builds the UI, prints a loud degraded banner. Dev-server detection and loopback previews work; stopping a preview from the UI works but is bounded (the lsof snapshot must be fresh enough and the process is re-checked live, otherwise the stop is refused rather than sent). Exposing a preview over the tailnet is unavailable (it needs the tailscale CLI). No sandbox, egress allowlist, auto-drain, systemd unit, or automated backups — run bun run start manually.
Windows Not supported The installer refuses and routes you to WSL2.

Run on this Mac can install and manage a local server. That server keeps running when you quit or restart the app, including updates and dev rebuilds; sessions continue. On the next launch the app resumes supervision after checking its saved ownership record and the server’s health identity. Use Stop or Restart in the local-server panel to stop the server. Servers started elsewhere remain externally managed. The generated password is offered only when this app run starts the server, never when adopting one already running.

The server answers only on 127.0.0.1 by default. Reachable in your tailnet in the same panel puts tailscale serve in front of that loopback port, so another Shepherd can connect to this Mac over HTTPS with a Full access token minted here. The server keeps listening on loopback only, and turning the switch off removes the mapping again. See Reach the local server from your tailnet for requirements, the trust decision and a two-machine test from a branch checkout.

Variable Default Purpose
SHEPHERD_DIR ~/.shepherd/app Where the repo is cloned / found
SHEPHERD_REF main Git ref to clone or check out
SHEPHERD_SRC (none) Install from a local tarball or directory instead of cloning
SHEPHERD_NO_SERVICE (none) Skip the systemd unit step (set automatically on macOS)
SHEPHERD_NO_CLI (none) Set to 1 to skip installing the prebuilt shepherd CLI binary (also honored by bun run update)
SHEPHERD_CLI_DIR ~/.local/bin Where the prebuilt shepherd CLI binary is installed

The installer never runs commands that need a human secret. After it completes, sign in:

Terminal window
claude # sign in with your Max/Pro subscription
# (or configure API-key auth in Settings → Session)
gh auth login # GitHub integration (PR list, merge, redeploy)
# remote access via Tailscale
tailscale serve --bg 7330
# no allowlist step needed — Shepherd auto-trusts every Tailscale-served
# host fronting its port. Only a non-Tailscale proxy / custom-DNS front
# needs its hostname in SHEPHERD_ALLOWED_HOSTS (in ~/.shepherd/env).

The HUD is gated by a single-operator password: the first time you open it you’ll get a login screen. Set the password with SHEPHERD_PASSWORD (in ~/.shepherd/env), or use the strong one Shepherd generates and prints to the log once on first boot (systemctl --user status shepherd / journalctl --user -u shepherd). Log out from Settings → Session.

On a brand-new install the HUD then opens on a blocking first-run step that asks you to choose a workspace folder before anything else runs. Shepherd only looks for repositories inside this folder, and its background work (polling, drain, task spawning) stays paused until you pick one — you can change it later in Settings. Set SHEPHERD_REPO_ROOT before first boot to skip the picker.

Settings → DIAGNOSE surfaces any remaining gaps with one-click fixes.

To run Shepherd from a checkout instead of the installer:

Terminal window
# 1. install deps (root + ui)
bun install
cd ui && bun install && cd ..
# 2. build the SPA (the core serves it statically from ui/build)
cd ui && bun run build && cd ..
# 3. run the core
bun run start
# → shepherd core on http://localhost:7330

Open http://localhost:7330. To expose it (e.g. via Tailscale), set SHEPHERD_ALLOWED_HOSTS to include the public hostname — see Configuration.

  • Bun — backend runtime + package manager
  • herdr on PATH — Can Celik’s agent multiplexer (herdr.dev); manages the interactive claude panes (owns the PTYs). herdr 0.9.5 is the last supported version. herdr 0.7.5 (protocol 17) reshaped agent start, so Shepherd spawns through a CLI external-registration path (tab create → pane run → report-agent) rather than the legacy agent start; 0.9.5 (protocol 22) keeps that path. Schema, CLI, lifecycle and terminal compatibility are checked against 0.9.5; the sandbox idle-status advisory still applies. Any newer, untested version is refused: Shepherd warns at startup, blocks the in-app updater, and refuses to spawn on it. New releases are admitted through the herdr version bumps procedure (bun run herdr:compat).
  • The claude CLI, logged in with your Max/Pro subscription
  • Node.js — for the PTY helper subprocess

In the web app, open Settings → Access → Connect iPhone → Show QR code. In Shepherd on your iPhone, choose Connect with QR code when adding a server and scan it. The system Camera app can also open the pairing link. The app connects with full access, without typing an address or password. On the Mac, Connect iPhone… in Access settings or the local-server panel opens this web view for you.

Your iPhone must be able to reach the server, for example through Tailscale. A localhost address points at the phone itself; when available, the web view uses its Tailscale address instead. Each QR code works once and expires after five minutes; the open view renews it automatically. Remove a phone’s token under Settings → Access to revoke its access.