CLI: install & configuration
How to install the jentrix command-line client, point it at a server, and give
it a token. For the command model and scripting patterns see
CLI: command reference and
CLI: recipes & scripting; the CLI overview is the
hub.
The CLI packages as @jentrix/cli and requires Node ≥ 20. It installs
two bins for the same program: jentrix (use this one) and stacks, the
pre-rename name, kept working for one deprecation window. Invoking stacks
prints a one-line notice on stderr and behaves identically otherwise.
Install
Everything at once — recommended
One line installs the full local toolchain — the jentrix CLI, the
jentrix-runner session host (connected sessions need it), and the default
Claude Code plugin. Run it inside your project folder (macOS/Linux):
bash -c "$(curl -fsSL https://tm.jentrix.ai/install.sh)"
Each deployment serves its own copy, and the copy you run decides which server
the toolchain is pointed at — use the origin you actually work against
(https://stacks-mvp.vercel.app/install.sh for the MVP deployment). Setup
in the workspace menu renders the line already filled in.
Run it as one command. curl … | bash works too, but a bare
curl -fsSL …/install.sh on its own only prints the script, and piping leaves
stdin on the pipe — the prompts and the browser sign-in then depend on a
/dev/tty reconnect that some shells don't provide. The bash -c "$(…)" form
keeps stdin on the terminal, so the interactive half always runs.
The script preflights Node ≥ 20, installs both packages, registers the
plugin, and — when no credentials are configured yet — asks which Jentrix
server to connect to (a numbered picker, with a custom-URL option) and runs
the browser sign-in. Where Codex is installed it also registers the Jentrix MCP
server with codex mcp add and signs it in through the same browser flow — no
personal access token to mint, nothing to export (see
Provider plugins). Because jentrix align runs inside a git repository, the
script then offers to git init the current folder and — optionally — add an
origin remote (the owner/name identity sessions align by; it doesn't have
to exist on GitHub yet). The remote is optional: a repository without one
aligns under local/<directory-name>. Re-running the script is safe: every
step skips or refreshes what is already configured.
The npm-only equivalent (any platform), which does everything except the git bootstrap:
npm install -g @jentrix/cli @jentrix/runner && jentrix plugin install
See Provider plugins below for Claude Code and Codex.
npm (CLI only)
npm install -g @jentrix/cli
jentrix --version
Without installing (npx / pnpm dlx)
Handy for one-offs and CI steps that shouldn't mutate a global environment:
npx @jentrix/cli --help
pnpm dlx @jentrix/cli task list --board board_1 --json
From a packed tarball (offline / air-gapped)
pnpm pack bundles the CLI into a single self-contained tarball —
dist/main.js with all dependencies inlined, plus the surface.json manifest —
that installs cold on any machine with no registry access:
cd cli
pnpm pack # writes jentrix-cli-<version>.tgz
npm install -g ./jentrix-cli-*.tgz
jentrix --version
From a checkout (contributors, developing on the CLI itself)
cd cli
pnpm install
pnpm build # produces dist/main.js (the `jentrix` bin)
node dist/main.js --version
When running from a checkout, substitute node dist/main.js wherever the docs
write jentrix.
Provider plugins
The npm package bundles both provider plugins. Claude Code remains the default for compatibility; choose Codex explicitly:
jentrix plugin install # Claude Code default
jentrix plugin install claude
jentrix plugin install codex
Both plugins provide the connect, align, plan, checkpoint, status, and end
workflows plus trusted lifecycle hooks. A missing matching
@jentrix/runner is installed automatically at the CLI's version.
Claude Code
The npm package bundles the Jentrix plugin for Claude Code, and
jentrix plugin install registers it from the install itself — no repo checkout
or separate marketplace needed:
jentrix plugin install
- It runs
claude plugin marketplace addon the bundled directory andclaude plugin install jentrix@jentrix; re-running it is safe and is how an already-registered install is refreshed (it switches tomarketplace update/plugin updateautomatically). - Prerequisite: the
claudeCLI.@jentrix/runneris required too — the plugin's lifecycle hooks executestacks-runner session-hook(the runner package installs that name alongsidejentrix-runner) to record the trusted session context thatjentrix session attachandjentrix alignread — but a missing runner is installed automatically (npm install -g @jentrix/runner@<the CLI's own version>, keeping the version lockstep), so even a CLI-only install converges:npm install -g @jentrix/cli && jentrix plugin installis a complete setup. Only when that auto-install cannot run (nonpmon PATH, a permission failure on the global prefix) does the command refuse (RUNNER_NOT_INSTALLED) rather than install hooks that would fail on every session start. - The skills appear in new Claude Code sessions; a session that was already running picks them up on restart.
- Without the plugin, everything still works from the terminal —
jentrix session attach/jentrix alignare the universal fallback; the plugin adds the in-session slash commands and the trusted hook context. - Remove it with
claude plugin uninstall jentrix@jentrix(the CLI itself is untouched). - Upgrading from before the rename: if you installed the old
stacks@stacksplugin, remove it. Both register the same commands, so leaving it in place shows every slash command twice. This is the only place that name still applies — everything else isjentrix@jentrix.
Codex
jentrix plugin install codex verifies the codex executable, registers the
bundled local jentrix marketplace, installs jentrix@jentrix, and verifies the
result with codex plugin list --json. It never replaces another marketplace
named jentrix: remove or rename that source deliberately, then retry.
The $jentrix-connect, $jentrix-align, $jentrix-plan, $jentrix-checkpoint,
$jentrix-status, and $jentrix-end skills appear in new Codex tasks. Start a
new task after installation and open /hooks to trust the Jentrix hooks. The
plugin does not bundle an endpoint-specific MCP configuration; alignment still
configures the deployment selected by the operator. Remove it with
codex plugin remove jentrix@jentrix.
The plugin and the MCP server are two halves and neither substitutes for the other: the plugin carries the skills and the trusted lifecycle hooks (session identity), the MCP server is what gives Codex the Jentrix tools. Register and authenticate the second half with:
codex mcp add jentrix --url https://tm.jentrix.ai/api/mcp
codex mcp login jentrix
login runs the browser consent flow — Codex registers itself dynamically
(RFC 7591) and holds its own rotating token, so there is no PAT to mint and no
environment variable to export. The installer performs both steps. An entry
that already exists is never rewritten: codex mcp remove jentrix first if you
want to move it off an exported STACKS_CODEX_TOKEN and onto sign-in.
Updating and uninstalling
npm update -g @jentrix/cli
npm uninstall -g @jentrix/cli
After upgrading, re-run the provider install command so its plugin refreshes from the new CLI package.
What --version tells you
$ jentrix --version
0.5.3 (surface: 242 tools, file dated 2026-07-16)
It prints three things: the CLI semver, the number of MCP tools this build
carries (the bundled manifest's generatedForToolCount), and the date of the
bundled surface.json file (its mtime) — a rough freshness signal for how
current this build's tool surface is relative to the server it talks to. The
manifest is deliberately timestamp-free so it stays byte-stable, so the file's
write date is the only date available; it is not a cryptographic "generated at"
proof, and the wording ("file dated") says so.
Configuration: token and endpoint
The CLI needs a token and an endpoint. Both resolve in a fixed precedence order — the first source that provides a value wins:
| Value | Precedence (first wins) | Default |
|---|---|---|
| Token | --token <t> → STACKS_TOKEN env → config file token | (none — required) |
| Endpoint | --url <u> → STACKS_MCP_URL env → config file url | https://tm.jentrix.ai/api/mcp |
Which config file? A project-local .stacks/config.json, discovered by
walking up from the current directory, wins over the user file
~/.config/stacks/config.json; whichever is found first is the config
file (the two are never merged). This is how different folders bind to
different Jentrix servers — see the next section.
Per-project servers (jentrix login --local)
Run inside a project folder:
cd ~/work/my-app
jentrix login --local
- Credentials land in
./.stacks/config.jsoninstead of the home file, and everyjentrixcommand run in that folder (or any subfolder) uses them — including connected-session hosts, so token rotation follows the same file. - With no
--url/STACKS_MCP_URLset, login first shows the server picker so you choose which deployment this folder binds to. - The
.stacks/directory is created with a self-ignoring.gitignore(*), so the token file cannot be committed. - Plain
jentrix loginkeeps writing the home file — the machine-wide default for folders with no local binding.jentrix logoutclears whichever file is active in the current folder.
STACKS_TOKEN / STACKS_MCP_URL are the same environment variable names the
reference agents use, so a single .env serves both the
CLI and an agent.
Personal access token (the primary path for agents)
Mint a PAT at /account/tokens on your Jentrix server — it looks like tm_….
Then:
export STACKS_TOKEN=tm_your_token_here
jentrix whoami
The CLI's built-in default endpoint is https://tm.jentrix.ai/api/mcp, so
any other deployment needs STACKS_MCP_URL set — that is the single most
common reason whoami reports the wrong server:
export STACKS_MCP_URL=https://stacks-mvp.vercel.app/api/mcp # your origin + /api/mcp
Scope the token to exactly what the caller needs (read, write, admin) and,
where possible, pin it to a single workspace — the CLI inherits both by
construction because it is a thin client over the same
MCP endpoint. For agents, a read-scoped token is the
real safety boundary; see recipes.
Config file
For a persistent default, write ~/.config/stacks/config.json:
{ "token": "tm_your_token_here", "url": "https://tm.jentrix.ai/api/mcp" }
The file is written mode 0600 (owner read/write only). jentrix login (below)
manages it for you; you can also hand-edit it. The token field holds either a
PAT (tm_…) or an OAuth access token (tmo_…); the oauth field, when present,
holds the refresh material (refreshToken, expiresAt, clientId,
tokenEndpoint, scope) that transparent refresh uses. The token is never
printed — not to stdout, stderr, or logs, in any mode.
Browser login (jentrix login)
For humans, jentrix login signs in with your Jentrix account over OAuth 2.1 in
the browser and stores a rotating token in the config file:
jentrix login # opens the browser, listens on a fixed loopback port
jentrix logout # clears the stored token + refresh material
- It uses the authorization-code + PKCE flow against the server's own OAuth authorization server — the same one any OAuth-capable MCP client discovers via RFC 9728 + 8414 — through a static client metadata document, with no client secret.
- The callback listens on the loopback interface only (
127.0.0.1), trying a fixed set of ports so the redirect URI is stable and pre-registered. - Access tokens (
tmo_…) are short-lived and refreshed transparently on the next call when they expire; refresh tokens (tmr_…) rotate on every use and are never sent as a bearer. jentrix login --pastesupports environments with no loopback browser round trip: you complete the flow manually and paste the resulting code.
jentrix login is interactive by design, so agents should always prefer a
scoped PAT via STACKS_TOKEN or the config file over interactive login.
Verify with jentrix whoami
The first command to run after configuring — it prints only what the token can actually prove:
$ jentrix whoami
Config:
server: https://tm.jentrix.ai/api/mcp (default)
token: tm_…a1b2 (environment)
Workspaces:
Acme acme ADMIN
Beta Co beta MEMBER
Note: scope/workspace restrictions are enforced server-side and not
introspectable; a FORBIDDEN (exit 3) on a write means the token lacks
write/admin scope.
- The token is never shown in full — only its type prefix (
tm_…PAT,tmo_…OAuth) and last four characters, including under--json. - The config source (flag / environment / config file / default) is shown for both the endpoint and the token, so you can tell which token you are actually using.
- Workspaces come from
list_workspaces— the only server-verified identity the current tool surface exposes (id, name, slug, and your role in each).
Scopes and workspace pinning are not introspectable from any tool output, so
whoami does not claim them. The honest test is behavioral: if a write returns
FORBIDDEN (exit 3), the token lacks write/admin scope; if a read fails the
same way, it lacks read. jentrix whoami --json emits the same facts as a
stable object for scripts.
Next
- CLI: command reference — the escape hatch, generated commands, flags, output, and exit codes.
- CLI: recipes & scripting — idempotency, conflict merges, rate limits, and agent patterns.