Installing the CLI
From PyPI
The distribution is published as the-loopy-one — the base name the-loop was already taken. The import package and the console script keep the natural names (decision-019):
| Name | |
|---|---|
| PyPI distribution | the-loopy-one |
| Import package | the_loop |
| Console script | the-loop |
pip install the-loopy-one
the-loop --helpPyYAML comes with it. There is nothing else to add.
Verify
the-loop --versionThe version is derived from the installed package metadata, not a hardcoded string, so it always reports what you actually have.
Upgrading (and installing the plugin)
Once the CLI is on the machine it installs the rest of the-loop — and itself:
the-loop install # the CLI + setup for detected Claude Code and Codex binaries
the-loop install codex --scope project --project-dir .
the-loop upgrade # move both to the current release
the-loop upgrade --dry-run # see the exact commands firstCodex setup preserves existing instructions and adds the operating skill and Stop hook. Review and trust the hook through Codex /hooks before unattended use. Install the official Codex CLI separately. Cursor plugin installation is issue #157.
upgrade works out how the running copy was installed — uv tool, pipx or pip — and uses that installer's upgrade command, so you do not have to remember which one you used. A development checkout is reported and left alone. See install and upgrade for scopes and outcomes.
Extras
There are none, by design. Everything the CLI can do resolves from a single pip install the-loopy-one: hosting the control-plane service and its MCP endpoint (fastapi, uvicorn, the official mcp SDK), reading YAML config (pyyaml), and the Slack sdk transport (slack-sdk). Extras were removed on owner review — "it creates a nightmare when installing" — so there is nothing to remember and nothing that silently degrades when it is missing.
The previously documented names still resolve as empty, deprecated no-ops:
pip install "the-loopy-one[service]" # still works, adds nothing
pip install "the-loopy-one[slack]" # still works, adds nothing
pip install "the-loopy-one[config]" # still works, adds nothingThey are kept only so pinned install lines in existing scripts and Dockerfiles keep resolving without pip's "does not provide the extra" warning. Do not use them in new scripts.
Python 3.10 or newer
The official MCP SDK requires Python 3.10+, so the-loop does too. Python 3.9 reached end of life in October 2025.
For local development
the-loop uses uv, its declared Python package manager. From the repository root:
uv sync # install the workspace (CLI + dev tooling) from uv.lock
uv run the-loop --help # run itOr install the package on its own with any PEP 517 installer:
uv pip install -e . # or: pip install -e .
uv pip install -e ".[dev]" # + pytest and commitizenRun the tests from the repository root:
make test # or: uv run --project cli python -m pytest -q cliReleases
Releases are automatic. On merge to main, .github/workflows/release.yml runs cz bump to derive the next version from the Conventional Commits / PR titles since the last tag (feat → minor, fix → patch, BREAKING CHANGE → major), tags it, and publishes to PyPI via Trusted Publishing (OIDC — no stored token). Merges carrying no feat, fix or breaking change publish nothing. See decision-019 and release & publishing.
What else you may need
The CLI shells out to a few tools rather than reimplementing them. None is required for every command. GitHub is not one of them since issue-442: the daemon reaches it through PyGithub with a token you name under integrations.github.api.tokenEnv (default GH_TOKEN, then GITHUB_TOKEN) — no gh binary, no interactive login.
| Tool | Needed for |
|---|---|
git | Per-work-item workspaces. |
tmux | Hosting every spawned session — required by both ingress daemons (the-loop start). See interactive sessions. |
ttyd | The optional browser terminal. |
claude / codex / cursor-agent | Whichever harness you spawn sessions with. |
Next
- Getting started — a working setup in five steps.