Installation
Pretorin CLI requires Python 3.10 or later.
Recommended: uv
uv installs the CLI as an isolated tool with its own dependencies:
uv tool install pretorin
pip
pip install pretorin
pipx
pipx provides isolated installation similar to uv:
pipx install pretorin
Standalone binary (preview)
Preview — not yet the recommended path. The pip / uv / pipx installs above remain fully supported and are the recommended way to install today. The standalone binary and Homebrew paths below are part of the in-progress binary distribution program (issue #160). On macOS the public recommendation still waits on final validation (a future milestone); until then macOS users should prefer uv/pip/pipx.
macOS releases from v0.23.9 onward are signed and notarized with an Apple Developer ID, so an MCP host can spawn them under Gatekeeper without a silent kill. (First launch performs an online notarization check, so a freshly downloaded copy needs network the first time it runs.) Older, unsigned releases are blocked by Gatekeeper; for those only, clearing the quarantine attribute with
xattr -d com.apple.quarantine <binary>overrides the OS check — a deliberate, at-your-own-risk step. Do not runxattron a notarized release: it strips the very attribute that lets Gatekeeper confirm notarization.
The CLI is also published as a self-contained executable — no Python required.
Customer downloads are served from the public tap repo,
pretorin-ai/homebrew-tap releases,
which mirrors byte-identical copies of the signed, notarized release assets. Each
release carries the per-platform binary plus a signed SHA256SUMS, its cosign
signature, the public key, and the release’s own tag:
pretorin-<version>-macos-arm64.tar.gz # macOS: a onedir tarball (extract, run pretorin/pretorin)
pretorin-<version>-linux-x86_64 # Linux: a single static executable
SHA256SUMS SHA256SUMS.sig cosign.pub
RELEASE-TAG # the release tag this asset set belongs to
RELEASE-TAG is one line naming the tag (v<version>, newline-terminated). Its
digest is a covered line in the signed SHA256SUMS, so it says which release
these signed bytes are — a genuinely signed asset set from a different tag with
the same version segment (a prerelease, say) can no longer answer for this one.
It ships only on releases cut after signed self-update landed. Earlier releases
have no RELEASE-TAG asset and no RELEASE-TAG line in their manifest — for
those, skip both its curl and step 2 below (the asset 404s, and step 2 has
nothing to check), and note that the self-updater refuses them outright
(manifest-cutoff) because their tag cannot be authenticated.
Download, verify, and install (Linux x86_64 shown). The same cosign.pub +
SHA256SUMS.sig verify the bytes regardless of which host served them — and the
tap URLs need no GitHub token:
VERSION=0.28.9
ASSET="pretorin-${VERSION}-linux-x86_64"
BASE="https://github.com/pretorin-ai/homebrew-tap/releases/download/v${VERSION}"
curl -fLO "${BASE}/${ASSET}"
curl -fLO "${BASE}/SHA256SUMS"
curl -fLO "${BASE}/SHA256SUMS.sig"
curl -fLO "${BASE}/cosign.pub"
curl -fLO "${BASE}/RELEASE-TAG"
# 1. Verify the signature over the checksums file. `--insecure-ignore-tlog=true`
# is required because Pretorin signs with a key (no public Rekor transparency
# log entry), NOT keyless — it does not weaken the key-based signature. For
# real trust, also confirm cosign.pub matches the key published out-of-band
# (the docs/release notes), not just the copy in this same release.
cosign verify-blob --key cosign.pub --signature SHA256SUMS.sig \
--insecure-ignore-tlog=true SHA256SUMS
# 2. Confirm WHICH release those signed checksums describe. Two steps, because
# RELEASE-TAG's digest is a covered line in SHA256SUMS: check the digest, then
# check that the content is the tag you asked for.
grep " RELEASE-TAG\$" SHA256SUMS | shasum -a 256 -c - # Linux: sha256sum -c -
[ "$(cat RELEASE-TAG)" = "v${VERSION}" ] && echo "RELEASE-TAG OK" || echo "WRONG RELEASE"
# 3. Verify the specific binary you downloaded against the signed checksums.
# (Checking the whole SHA256SUMS would skip — and silently "pass" — any
# listed asset you didn't download. Pin the one file instead.)
grep " ${ASSET}\$" SHA256SUMS | shasum -a 256 -c - # Linux: sha256sum -c -
install -m 0755 "${ASSET}" /usr/local/bin/pretorin
Upgrading: pretorin update routes by how you installed. A standalone binary
has no managed Python environment, so it never runs pip/uv/pipx. What it does
instead depends on the install:
- Linux x86_64, directly downloaded binary — it self-updates.
pretorin updateresolves the latest tap release, verifies it against a signing key embedded in the binary at build time, and replaces the running executable atomically. The whole chain (signature over the checksums, theRELEASE-TAGbinding, the binary’s checksum, and the downloaded binary’s own reported version) must pass before anything is installed; on any failure your existing binary is left byte-identical. Seepretorin updatefor the failure categories and the not-writable case. - Homebrew —
brew upgrade pretorin. Brew owns the installed file, sopretorin updatedeliberately points you atbrewinstead of replacing it. - macOS, or any other architecture — manual re-download. No self-update asset
is published for these, and
pretorin updatesays so rather than pretending. Repeat the download-and-verify block above with the newVERSION, then re-runpretorin linkif the executable moved.
Verify macOS notarization (macOS, v0.23.9+)
On macOS you can confirm the Apple Developer ID signature yourself. macOS ships as
a onedir tarball, so extract it first and run codesign against the inner
executable. codesign is the reliable check — look for the Developer ID Application authority and the runtime flag (hardened runtime):
tar -xzf pretorin-${VERSION}-macos-arm64.tar.gz
codesign -dvv pretorin/pretorin 2>&1 | grep -E 'Authority|flags'
codesign --verify --strict --verbose=2 pretorin/pretorin
spctlis unreliable here — don’t trust it for this binary.spctl -a -t execcan report “rejected” for a notarized command-line tool because the notarization ticket cannot be stapled to a non-bundle executable; Gatekeeper confirms it online at spawn time instead. Usecodesign(above) as the source of truth, notspctl.
Canonical path for MCP hosts
MCP hosts (Claude, Cursor, Codex) are configured against one stable path,
~/.pretorin/bin/pretorin, so the host config survives reinstalls and upgrades.
After installing the binary (or via Homebrew), pin that path at the executable:
pretorin link
This creates/updates ~/.pretorin/bin/pretorin → the resolved executable. It is
the only thing that writes to your home directory — the Homebrew formula
deliberately does not. The equivalent manual step is:
mkdir -p ~/.pretorin/bin
ln -sf "$(command -v pretorin)" ~/.pretorin/bin/pretorin
Homebrew (macOS Apple silicon + Linux)
Install from the public tap. pretorin-ai/tap expands to the repo
pretorin-ai/homebrew-tap (Homebrew adds the homebrew- prefix automatically),
and the download needs no GitHub login:
# 1. Install (macOS arm64 onedir tarball, or Linux x86_64 binary)
brew install pretorin-ai/tap/pretorin
# 2. Pin the canonical MCP path so Claude/Cursor/Codex configs survive upgrades.
# The formula never writes to $HOME; this explicit step owns the pin.
pretorin link
# 3. Confirm
pretorin version
brew upgrade pretorin drives future updates; pretorin update on a brew
install routes you to that command rather than touching the Homebrew prefix.
macOS recommendation is still finalizing (M10). The macOS arm64 formula installs and runs the signed + notarized onedir today, but the recommended macOS path is gated on final latency/install validation of the Homebrew onedir. Linux Homebrew is usable now. Apple-silicon-only on macOS and x86_64-only on Linux — other arches get a clear
brewerror pointing atuv/pip/pipx.
Verify the brew-downloaded bytes (optional, token-free). The tap release ships
cosign.pub + SHA256SUMS.sig, so a security-conscious user can confirm the
artifact independently:
VERSION=0.28.9
BASE="https://github.com/pretorin-ai/homebrew-tap/releases/download/v${VERSION}"
curl -fLO "${BASE}/SHA256SUMS"; curl -fLO "${BASE}/SHA256SUMS.sig"; curl -fLO "${BASE}/cosign.pub"
cosign verify-blob --key cosign.pub --signature SHA256SUMS.sig \
--insecure-ignore-tlog=true SHA256SUMS
(Confirm cosign.pub matches the key published out-of-band, not just the copy in
the same release.)
brew upgrade pretorin drives updates for Homebrew installs; pretorin update
detects a Homebrew install and points you at brew upgrade rather than pip/uv.
Docker
A multi-stage Dockerfile is included in the repository. The production target builds an image that runs the pretorin CLI as its entrypoint:
git clone https://github.com/pretorin-ai/pretorin-cli.git
cd pretorin-cli
docker build --target production -t pretorin .
docker run --rm pretorin --help
Mount your config directory to persist credentials between runs:
docker run --rm -v "$HOME/.pretorin:/home/pretorin/.pretorin" pretorin frameworks list
The included docker-compose.yml defines test, test-coverage, lint, typecheck, and integration services for contributors. Each is invoked with docker compose run --rm <service>, not docker compose up. See Contributing for development workflows.
Verify Installation
pretorin version
Expected output (the runtime and path lines tell you which install you’re running and where it resolved):
pretorin version 0.28.9
runtime: Python package
path: /path/to/pretorin
A standalone-binary install reports runtime: standalone binary (or standalone binary (Homebrew)) instead.
Updating
Check for and install the latest version:
pretorin update
Or pin a specific version:
pretorin update 0.28.9
The no-argument path checks PyPI first and reports the version it found, then
runs the installer that owns the current CLI environment (uv, pipx, or
pip). It still invokes the installer when PyPI reports no newer version — a
stale PyPI or CDN response should not block an upgrade — so the final “already
up to date” answer comes from the installer, not the version check. The one
early exit is when your installed version is newer than the latest published
one (a pre-release or local build), which it reports and leaves alone.
This section describes the Python-package path only. Frozen installs take a
different route entirely: a directly downloaded Linux x86_64 binary verifies and
replaces itself from a signed release, Homebrew installs are sent to brew upgrade, and other frozen platforms get manual guidance — see
Standalone binary and
Homebrew above.
Older uv-installed Pretorin versions may fail with No module named pip because uv tool environments do not include pip. If that happens, run this one-time recovery command:
uv tool install --force --refresh pretorin@latest
The CLI also checks for updates automatically on startup and notifies you when a new version is available. To disable passive update notifications:
export PRETORIN_DISABLE_UPDATE_CHECK=1
# or
pretorin config set disable_update_check true
Development Installation
For contributing to Pretorin CLI:
git clone https://github.com/pretorin-ai/pretorin-cli.git
cd pretorin-cli
uv pip install -e ".[dev]"
This installs the package in editable mode with development dependencies (pytest, ruff, mypy, etc.).