alpi runs on Linux and macOS. Windows users are expected to install under WSL2 — native Windows is not supported because alpi relies on POSIX primitives (Unix-domain sockets, sandbox helpers, launchd / systemd service backends). The path is the same as Linux once WSL2 is up.
The PyPI package is
alpi-agent. The binary, import, and home directory arealpi:uv tool install alpi-agent # install alpi setup # use
Requirements
alpi runs the same daemon and home layout in three shapes: native (the personal agent next to your shell), Docker (headless fleet daemons), and Kubernetes (the same image as a stateful workload).
| Native | Docker | Kubernetes | |
|---|---|---|---|
| Platform | Linux, macOS (Windows → WSL2) | any Docker host | any cluster |
| Python | 3.11–3.13 (uv manages it) | in the image | in the image |
| Node.js | 24 LTS on the service PATH — needed for npx-launched MCP servers and npm project gates; optional if you use neither | in the image | in the image |
| git | required when the daemon clones projects (workgroup recipes, repo-working agents); plus openssh-client for SSH-URL clones. A chat-only agent needs neither | in the image | in the image |
| Service manager | launchd (macOS) / systemd user + lingering (Linux) — installed by alpi setup | --restart unless-stopped | the pod controller |
| State | ~/.alpi + your workspace | a volume at /data, owned by UID/GID 1000 | a PVC at /data (RWO), runAsUser/fsGroup 1000 |
| Inbound network | none required; ALP 7423 + host plane 49200 only when peers or paired apps dial in — bind a private/overlay address (Tailscale, WireGuard) | publish both ports on a private address; override with ALPI_ALP_TCP_PORT / ALPI_HOST_TCP_PORT | a Service on both TCP ports |
| Outbound network | HTTPS to your model provider (or a local Ollama) | same, plus GitHub + npm registry only when recipes clone projects | same |
Docker. The official image is satoshiltd/alpi (Python + Node 24 + git + ssh client; entrypoint alpi-docker; HOME=/data, so /data/.alpi is the daemon home). One daemon per container; reach the TUI with docker exec -it <name> alpi. Full guide: docker/README.md and the fleet shapes in Deployments.
Kubernetes. No manifests or Helm chart ship yet, but the image runs as a plain stateful, single-writer workload — see the Kubernetes section of docker/README.md for the constraints that matter (replicas: 1, PVC, ALPI_NETWORK_HOST, probes, secrets).
Recommended — uv tool install
uv is alpi's recommended installer. It puts alpi in its own isolated environment, makes upgrades a single command, and never pollutes your system Python.
# Install uv if you don't have it already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install alpi
uv tool install alpi-agent
# Run the setup wizard, then start chatting
alpi setup
alpi
Pin a specific version with uv tool install alpi-agent==<version>.
The first alpi setup auto-installs the alpi daemon — one launchd plist on macOS (com.alpi.daemon), one systemd-user unit on Linux (alpi-daemon.service) — and starts it. The daemon supervises every profile under ~/.alpi/, so a single install gets you 24/7 cron + ALP listener for every profile you create. Manage it later with alpi daemon {status,restart,uninstall} or from alpi setup → Services → Daemon.
Linux note. systemctl --user services die when you log out unless lingering is enabled. The install runs loginctl enable-linger $USER automatically; on minimal containers / WSL without systemd=true, loginctl may be missing — alpi logs a warning and you'll need to keep the daemon foregrounded under tmux / screen, or fix lingering by hand.
The first time the agent runs the browser tool, alpi downloads the Chromium headless shell (~340 MB, one-time, cached under Playwright's own directory — ~/Library/Caches/ms-playwright on macOS, ~/.cache/ms-playwright on Linux). That shell is what browser launches; the full Chromium build is never fetched. No separate install command. If you never use the browser tool, nothing is downloaded.
Alternative — pipx install
If you already use pipx for your Python tools, the same package works:
pipx install alpi-agent
alpi setup
Updating
alpi update
alpi update checks PyPI for a newer version, shows what changed, and runs uv tool upgrade alpi-agent (or pipx upgrade alpi-agent) on confirmation. Nothing is ever installed without your confirmation.
You don't have to remember to run it: on launch alpi checks PyPI in a background thread, at most once every eight hours, and surfaces the result in two places —
alpi doctorprints aVersionrow at the top with the new number when one is available.- The TUI's top bar adds a small
↑ vX.Y.Zbadge next to the current version.
alpi update cannot update an alpi that runs in Docker or from a source checkout: it prints the manual step instead (set the new image tag in docker-compose.yml and run docker compose up -d, or git pull and restart the daemon), and the desktop and mobile apps show the same step instead of an update button.
If a package-manager listing fails, the next check retries detection instead of remembering the installation as a source checkout for the rest of the process.
alpi update --check does just the check and tells you whether an upgrade exists, without installing anything, and it queries PyPI whenever you run it. ALPI_SKIP_UPDATE_CHECK=1 stops only the daemon's background refresh; a result already in the cache keeps showing in the version row and the badge, because both read the cache and never expire it.
To pin an older version intentionally:
uv tool install alpi-agent==<version> --force
Uninstalling
uv tool uninstall alpi-agent # or: pipx uninstall alpi-agent
rm -rf ~/.alpi # only if you want to drop profiles too
~/.alpi holds your profiles, keys, memory, and logs. The uninstaller leaves it in place by default so you can reinstall and pick up where you left off.
Developing alpi
If you're contributing or hacking on alpi, install from source:
git clone https://github.com/satoshi-ltd/alpi
cd alpi
uv sync
uv run alpi
uv sync creates a venv from the lock file. Tests run with uv run pytest tests/. Manual integration tests live under tests/manual/ and are not collected by pytest — read tests/manual/README.md before running them.
Why we don't ship other install paths
- No
curl … | bashinstaller. Pasting a remote bash script into your shell is the opposite of what alpi stands for. Use the PyPI package — it's auditable, version-pinnable, signed by a trusted publisher, and updates flow through a tool you already trust. - No Homebrew formula.
uv tool installalready covers macOS cleanly. Maintaining a Tap is duplicate work without a payoff. - Docker is for fleets, not for the personal agent. The personal
CLI lives next to your shell, your editor, your dotfiles — install it
natively. For headless always-on daemons (home servers, company
fleets) there IS an official image,
satoshiltd/alpi— see Requirements above and docker/README.md. - No platform installers (.pkg, .msi). Same reasoning: install via the language toolchain you already have.
Troubleshooting
alpi: command not foundafter install — the tool's bin directory isn't on yourPATH. uv suggests the right line during install; re-run the suggestedeval "$(uv tool ...)"command, or add~/.local/binto your shell'sPATH.- The browser tool is missing from
alpi doctoron Linux, ordoctorwarnschromium system libraries missing— install the system libraries Playwright needs:uvx --from playwright playwright install-deps chromium-headless-shell. It has to go throughuvx:uv tool installlinks only alpi-agent's own entry points, so a bareplaywrightis not onPATH. Until the libraries are present the tool is withheld from the agent rather than offered and failing at launch. The Docker image installs them at build time from its own playwright. alpi doctorred lights — run it; the output names the missing piece (model, workspace, email credentials, etc.) and tells you which wizard step fixes it.