Skip to main content

Self-hosted web UI for spawning and managing Claude Code remote-control bridges on a remote host.

Project description

Clauster

Run Claude Code on your own server — and drive it from your phone.
Clauster is a self-hosted web dashboard that starts Claude Code sessions in any project directory on your homelab, NAS, or VPS. You attach from claude.ai/code or the Claude mobile app. No SSH session required.

CI PyPI License: Apache-2.0 Docs

Spawn a Claude session from the Clauster dashboard — open a project's launch menu, trust the directory, and the session starts, then shows Running under Active sessions

Why not just SSH in and run claude?

SSH + terminal Clauster
From a phone Type into a mobile SSH client Tap a project in a browser, then use the Claude app
When you close the laptop Session dies with the shell Session keeps running on the host; reattach later
Starting a session cd to the project, remember the flags One click per project, spawn + permission modes preset

If you already live in a terminal on the same machine as your code, you don't need this. Clauster is for when your code lives on a box you don't want to SSH into every time.

Quick start

curl -fsSL https://raw.githubusercontent.com/schubydoo/clauster/main/install.sh | bash
clauster run

Open http://127.0.0.1:7621 — run with no config and Clauster serves a loopback-only first-run setup wizard that asks for your projects folder and a dashboard password, writes a clauster.yml, and starts on it. Then click Run Claude here on a project. Full recipes (uv / pip, Docker, systemd, reverse proxy) → Installation guide.

Status: 1.0 — stable and actively developed. Requires an Anthropic account with Claude Code access. Loopback-only by default; password and reverse-proxy auth are available for networked deployments (see Auth & networking). No telemetry, ever — see Privacy & data at rest for what Clauster keeps locally. Upgrading from 0.12? 1.0 has five breaking changes — see UPGRADING.md.

Dashboard, light theme
Dark / light — theme toggle persists across reloads
Create or clone a project
Create or clone — SSRF-guarded, cloned code runs only on Start
Password login
Password login — for non-loopback / networked deploys
Every action is reactive — cards insert, badges flip, and clone progress
streams without a full-page reload. Self-hosted assets; no CDN, no trackers.

Features

A self-hosted dashboard for the claude sessions running on your own machine — start them, watch them, and pick them up from your phone.

  • Projects & bridges — a card per directory under projects_root; start, stop and resume bridges, choose the spawn and permission mode, and open any session in Claude by deep link or QR code.
  • Visibility — live bridge-log tail over a WebSocket, a read-only transcript viewer, and per-project cost and token totals.
  • In-app editing — edit a project's Claude Code config surfaces and an allowlist of operational clauster.yml settings, without reaching for SSH.
  • Safety — workspace-trust prompts before a first spawn, session URLs redacted out of the streamed log (the on-disk bridge log stays verbatim unless you set logs.redact_session_url), and an auth model that fails closed on a network bind.
  • Interactive Sessions — an opt-in pty mode with true resume and a read-only live terminal view.
  • Extras — outbound notifications and webhooks, a Prometheus endpoint, a ghost-environment reaper, experimental background agents, and an MCP server (read-only until you opt into its write tools). Each is off, or read-only, by default.

That is the short list, not the whole of it — every feature is documented in full on the documentation site; start at the Quickstart or How it works.

Install

No Python needed — the install script grabs the signed standalone binary for your OS, verifies its checksum, and installs it to ~/.local/bin (Linux & macOS), printing a PATH hint if that directory isn't already on your PATH:

curl -fsSL https://raw.githubusercontent.com/schubydoo/clauster/main/install.sh | bash

On Windows, the PowerShell equivalent installs clauster.exe the same way:

irm https://raw.githubusercontent.com/schubydoo/clauster/main/install.ps1 | iex

Or pick another path — uv tool install clauster (recommended for a Python host), pip/pipx, Scoop on Windows (scoop bucket add clauster https://github.com/schubydoo/clauster && scoop install clauster), or Docker. Full recipes — including supply-chain verification — are in the Installation guide. To hack on Clauster itself, see Contributing below.

Uninstall

  • Install script / standalone binary: remove ~/.local/bin/clauster on Linux or macOS; on Windows, delete %LOCALAPPDATA%\Programs\clauster\clauster.exe unless you set a custom install directory.
  • Python tools: run uv tool uninstall clauster, pipx uninstall clauster, or pip uninstall clauster, matching how you installed it.
  • Scoop: run scoop uninstall clauster.
  • Docker: stop and remove the container with docker rm -f clauster, then remove the image with docker rmi ghcr.io/schubydoo/clauster:latest (substitute the pinned tag you pulled, e.g. :X.Y.Z, if you used a specific release) if you no longer need it. Docker Compose users: run docker compose down from the directory containing compose.yaml (add -v to also delete named volumes).
  • Full purge: stop Clauster first, then remove your state_dir if you want local state/config gone too. See Privacy & data at rest and the Installation guide.

Contributing

Working on Clauster itself? CONTRIBUTING.md has the from-source dev setup (uv sync --extra dev), the local test/lint gates, and the branching + review workflow.

First bridge in 60 seconds

Start Clauster (run clauster; it serves http://127.0.0.1:7621 by default). With an authenticated claude on your PATH, spawning your first bridge is a handful of clicks — no terminal needed once it's started. Clauster spawns claude — it doesn't vendor it — and a spawned bridge inherits the host user's claude authentication, so claude must be logged in (interactive claude login or ANTHROPIC_API_KEY in the environment — either satisfies the check) before any bridge can connect. clauster doctor (step 2) confirms it; see the Quickstart prerequisites for the full list.

  1. Point Clauster at your code. Set projects_root in clauster.yml to a directory whose subfolders are projects (e.g. ~/code); each child directory becomes a card.
  2. Sanity-check the host (optional). clauster doctor confirms claude is found, new enough, and logged in (the bridge inherits this login), and that projects_root / the state dir are usable — fix any ✗ before spawning.
  3. Open the dashboard at http://127.0.0.1:7621. You'll see one card per project to start — a project running several sessions later shows a card for each.
  4. Launch a bridge. On a project's card, click Run Claude here ▾, choose In claude.ai / Desktop, pick a permission mode, then Run. Clauster launches claude remote-control in that directory and the card flips to Running with a live status badge. (The spawn-mode and permission defaults are safe out of the box.)
  5. Attach from anywhere. Use the card's Open in Claude link — or scan its QR code — to pick the bridge up in claude.ai/code or the Claude mobile app. No SSH session.
  6. Stop or resume. Stop signals the bridge; Resume relaunches it (with claude.resume_recap or claude.launch_mode: pty it can carry the prior conversation forward — see the configuration guide). For a deliberate fresh start, Forget the stopped session and launch again with Run Claude here.

Exposing this beyond loopback (e.g. on your LAN)? Read Auth & networking first — a non-loopback bind requires authentication.

Docker

Multi-arch images (linux/amd64, linux/arm64) are published to GHCR on each release, cosign-signed with provenance + SBOM attestations. Two things to know before docker run:

  • The image binds 0.0.0.0, so it refuses to start without enforced auth — set CLAUSTER_AUTH_ENABLED=true, CLAUSTER_AUTH_PASSWORD_REQUIRED=true, and a CLAUSTER_AUTH_PASSWORD_HASH (generate one with docker run --rm -it ghcr.io/schubydoo/clauster:latest clauster hash-password).
  • claude is not baked into the image — mount the CLI onto the container PATH (or set CLAUSTER_CLAUDE_BINARY) along with the runtime user's ~/.claude credentials.

Full run + compose.yaml recipes, volumes, and PUID/PGID mapping: Installation → Docker.

Auth & networking

Loopback (127.0.0.1) needs no auth. Binding to a non-loopback address is refused unless authentication is actually enforced — set auth.enabled: true (the master switch) together with either password login (auth.password_required + a hash from clauster hash-password) or reverse-proxy trust (peer-IP allowlist + HMAC header) — or, to opt out on a trusted LAN, auth.allow_unauthenticated_network. Sessions are signed cookies with server-side revocation ("log out everywhere"); WebSocket connections are authenticated before accept and origin-checked. The origin allowlist is a cross-site defence rather than an authentication method, so it is enforced even with auth.enabled: false; a non-loopback bind auto-trusts no origin and must set auth.allowed_origins.

Configuration

All settings live in clauster.ymlclauster.yml.example is a lean starter, and docs/reference/config.md is the exhaustive per-key reference. Any scalar or list key is overridable by an environment variable of the form CLAUSTER_<UPPER_SNAKE_PATH> (lists take a comma-separated value). The schema is additive-only — old configs always validate against newer versions.

Common flag Default What it does
host / port 127.0.0.1 / 7621 bind address (non-loopback needs auth)
projects_root directory whose children become project cards
auth.enabled false master auth switch — must be on for password / proxy auth to apply
auth.password_required false require login (clauster hash-password for the hash)
claude.resume_recap false recap the prior transcript into a restarted bridge
claude.launch_mode standard pty = native true-resume on Resume (POSIX pty, or Windows ConPTY with the pty extra); default for new bridges only — a bridge keeps the mode it launched with
reaper.ui_enabled false expose the ghost-environment reaper in the dashboard
claustrum.enabled false enable the hosted live-view channel (connect-or-spawn the claustrum daemon)
usage.mode cost per-project badge contents: cost (≈USD + tokens) · tokens (count only) · off (hide + skip the usage fetch). usage.show_cost: false is a deprecated alias for off
logs.redact_session_url false redact the session URL on disk too, not just over WS

CLI

clauster run                  # start the server (default)
clauster hash-password        # generate an argon2id hash for auth.password_hash
clauster hash-token           # mint an API token + hash for auth.api_token_hash
clauster hash-metrics-token   # mint a /metrics scrape token + hash for observability.metrics_token_hash
clauster api-token issue|list|rotate|revoke   # manage named public-API bearer tokens
clauster mcp                  # read-only MCP server over stdio (list + status)
clauster doctor               # diagnose config / environment
clauster backup | restore | migrate
clauster install-service {systemd|launchd|windows}
clauster reap-environments    # reap ghost bridge environments (dry-run by default)
clauster keepers              # list or stop orphaned pty keepers
clauster usage <transcript>   # token + approximate cost for a session transcript
clauster config reconcile     # remove deprecated config keys, writing their replacements
clauster deps list|install|uninstall          # manage optional extras beside the standalone binary
clauster projects | status | sessions         # headless reads (--json), no server needed
clauster logs <instance> | open <instance>    # tail a bridge's redacted log / print its connect URL
clauster start <project> | stop <instance>    # headless spawn/stop through the same engine as the UI
#   <instance> = full id, a unique prefix of one (as printed by `status`), or a project name

Full per-command reference: docs/reference/cli.md.

Roadmap

Planned work, roughly in priority order — the public-facing companion to the in-repo scratch/TODO.md.

  • Friendlier default session names — Server-Mode bridges already accept a custom launch name (#780) and the dashboard lists active/resumable sessions per project; the remaining work is a more predictable default than the random adjective-noun one, and extending custom names to Interactive Sessions.

Not planned: clauster is a single-operator tool — multi-user accounts, OIDC login, and per-user GDPR tooling were considered and declined (one deployment serves one operator; isolate with separate instances instead). The UI is English-only and not localized — there is no i18n string extraction on the roadmap (re-scope only if a real translation contributor appears).

Shipped:

  • Public API — a documented, versioned /api/v1 surface with named Bearer tokens (distinct from the session cookie), managed via clauster api-token issue|list|rotate|revoke; an opt-in OpenAPI schema (api.openapi_enabled) is available for third-party dashboards.
  • The in-repo docs/ pages (setup, networking, config reference, security model) are published as a live docs site at schubydoo.github.io/clauster.

Stack

Python 3.11+ · FastAPI · Alpine.js + Jinja2 + Tabler · uv · pydantic. Developed and CI-gated on Linux; macOS / Windows are in the test matrix. Apache-2.0 licensed.

Project health

Lint codecov Reviewed by Greptile OpenSSF Scorecard OpenSSF Best Practices Python versions GHCR Ruff pre-commit

Support

Questions, bugs, and feature requests all go through GitHub Issues — Discussions are intentionally not enabled. See SUPPORT.md for how to get help, and SECURITY.md to report a vulnerability privately.

License

Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clauster-1.0.0.tar.gz (3.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clauster-1.0.0-py3-none-any.whl (1.0 MB view details)

Uploaded Python 3

File details

Details for the file clauster-1.0.0.tar.gz.

File metadata

  • Download URL: clauster-1.0.0.tar.gz
  • Upload date:
  • Size: 3.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for clauster-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fe5fd9559e955b9487595771f9f59fe9dc4b65da33764e32cd9dc2168adca976
MD5 efdcc67c7a02986d274cf7e87e7e7cfc
BLAKE2b-256 4e1cc00e1c5accfc23764f929429607457873f0ff06b138a8f620e1a823ebe36

See more details on using hashes here.

Provenance

The following attestation bundles were made for clauster-1.0.0.tar.gz:

Publisher: release.yml on schubydoo/clauster

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file clauster-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: clauster-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for clauster-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ba24fc164ba292a6efaf4a176271404d561fa551f120594f706b5abc631cdd2d
MD5 95c70fb21b68f19cda3fc538e838265f
BLAKE2b-256 96b59e587395a567bafc67cb5f313879b9873adc29996402af4df3bc1ab0fc36

See more details on using hashes here.

Provenance

The following attestation bundles were made for clauster-1.0.0-py3-none-any.whl:

Publisher: release.yml on schubydoo/clauster

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page