Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Installation

Pretorin CLI requires Python 3.10 or later.

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 run xattr on 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 update resolves 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, the RELEASE-TAG binding, 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. See pretorin update for the failure categories and the not-writable case.
  • Homebrew — brew upgrade pretorin. Brew owns the installed file, so pretorin update deliberately points you at brew instead of replacing it.
  • macOS, or any other architecture — manual re-download. No self-update asset is published for these, and pretorin update says so rather than pretending. Repeat the download-and-verify block above with the new VERSION, then re-run pretorin link if 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

spctl is unreliable here — don’t trust it for this binary. spctl -a -t exec can 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. Use codesign (above) as the source of truth, not spctl.

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 brew error pointing at uv/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.).