Configuration
The spec CLI is configured from three places: environment variables, a
stored login written by spec auth login, and an optional .specstrand marker file at a workspace root. Every setting is optional
except a way to authenticate. This page covers all of them and the order in which they
apply. Server-side settings for a self-hosted instance are documented elsewhere.
Environment variables
The CLI reads these variables. Nothing else in the environment changes its behaviour.
| Variable | Purpose |
|---|---|
SPEC_API | Override the API base URL. Unset, the CLI talks to https://api.specstrand.com, so a fresh install needs nothing here.
A trailing slash is trimmed. Also settable per command with --api. |
SPEC_TOKEN | Personal access token (PAT). Always wins over the token stored by spec auth login, which makes it the right choice for CI and
ephemeral shells. |
SPEC_RUN | Pin the implicit run for commands that take --run or [RUN]. Beats the remembered run in the state file; loses to an
explicit --run. |
SPEC_PROJECT | Default project scope, which in turn defaults --plan and --queue. Beats the .specstrand marker; loses to --project. A slug that names no project you can see is an error. |
SPEC_SCAN_BIN | Path to the spec-scan executable used by spec codegraph scan and spec codegraph validate. Set it
to pin a build or an unpacked release; see the scanner for the lookup order. |
A CI job needs exactly one of them:
export SPEC_TOKEN=<your-PAT>
spec task next --plan <plan-slug>Set SPEC_API only to send commands somewhere other than the default
origin, a local API for example:
export SPEC_API=http://localhost:8080Precedence
When a setting can come from more than one place, the more explicit source wins. Flags beat the environment, the environment beats files on disk.
| Setting | Resolution, first match wins |
|---|---|
| API base | --api, then SPEC_API, then the stored login, then https://api.specstrand.com (the default). |
| Token | SPEC_TOKEN, then the stored login. |
| Run | --run or a positional RUN, then SPEC_RUN,
then the run the last spec task next or spec task resume claimed in this workspace. |
| Project scope | --project, then SPEC_PROJECT, then a .specstrand marker, then a project whose slug matches the git origin repository name, then none. An explicit --plan or --queue always wins over a scoped default. |
Having no project scope at all is fine: commands simply run without defaults. A bad slug
in --project or SPEC_PROJECT is an error, because you named it;
a bad slug in a marker file, or a git remote that matches nothing, quietly resolves to no
scope.
Stored login
spec auth login verifies the token against the instance and stores both the
token and the API base in config.json under the user configuration
directory: ~/.config/specstrand on Linux, ~/Library/Application Support/specstrand on macOS, and %AppData%\specstrand on Windows. The file is written with mode 0600; on Linux and macOS a copy that is group- or world-readable is
ignored with a warning rather than trusted.
spec auth login --token <your-PAT> # stores the base it verified against
spec task next # no SPEC_API or SPEC_TOKEN needed from here onNext to it, state.json remembers the run your last claim opened, keyed by
API base plus workspace root (the git top level, or the working directory outside a
repository). That is why two checkouts driving the same instance never share a current
run, and why spec task report and spec task complete need no --run in the normal loop. The state file is a convenience: losing it costs
one explicit --run, nothing more.
The .specstrand workspace marker
A .specstrand file at a repository root (or any folder, no VCS required)
pins a default project scope for every command run beneath it. The CLI walks up from
the working directory to find it, the way git finds .git. The format is
one key: value per line; blank lines and # comments are
ignored, unknown keys are skipped, and keys are case-insensitive.
# .specstrand
project: my-project
plan: docs-platform # optional default for --plan
queue: Tasks # optional default for --queue| Key | Meaning |
|---|---|
project | Required. The project slug. A file without it, or one that cannot be read, yields no scope. |
plan | Optional. Supplies --plan to spec task next and spec plan import when the flag is not given. |
queue | Optional. Supplies --queue the same way; a queue name or UUID. |
With that file in place, an agent working the repository can claim without flags:
spec task next # scoped to my-project, plan docs-platformCommit the marker if the whole team drives the same project from that repository; keep it out of version control if the scope is personal.
The codebase scanner
spec codegraph scan and spec codegraph validate execute the
separate spec-scan binary, published per platform alongside the spec installers (it needs cgo for tree-sitter, so the CLI does not embed
it). The CLI looks for it in this order: SPEC_SCAN_BIN, then spec-scan on your PATH, then the directory that holds the
running spec executable, which is where the release layout puts both. A SPEC_SCAN_BIN that points at a directory, or at a path that does not exist,
is a clear error naming the variable.
export SPEC_SCAN_BIN=/opt/specstrand/spec-scan
spec codegraph scanCodebase graphs are off during the beta; the CLI reference lists the verbs and the instance flag that enables them.
Self-hosting
Running your own SpecStrand server? The server's environment variables, required
settings, and deployment topology are documented in the source repository under deploy/README.md, alongside the operations runbook. They are not published
here.
See also: CLI reference, MCP setup.