DOCS · REFERENCE
CLI reference
Every specd command, the exit codes worth scripting against, the environment overrides, and the interactive shell.
A single static Go binary. It fetches, registers and reports — it never authors, reviews or approves, and the server refuses those for CLI tokens regardless of what the binary asks.
Install
pnpm cli:build # → ./bin/specd
pnpm cli:install # → $(go env GOPATH)/bin/specd — warns if that is not on PATHCommands
| Command | What it does |
|---|---|
specd login | Device flow — a human confirms in the browser. The token lands in your OS keychain. |
specd logout | Drops the stored token. |
specd whoami | Who this machine is signed in as. |
specd projects | Projects this account can see. |
specd use <project> | Set the default project for this machine. |
specd spec pull <id> | Print an approved spec as markdown. Refused server-side for anything unapproved. |
specd spec status <id> | Lifecycle state. Exit 3 when the spec exists but is not approved. |
specd specs list --status approved | List specs, filterable by lifecycle state. |
specd connect . | Register a local repository. Code stays on your machine. |
specd runner pair <code> | Pair this machine as a self-hosted runner. Codes are single-use and expire in 30 minutes. |
specd runner token | Print this machine's runner token — for the daemon's environment. |
specd open <id> | Open the spec (or the project) in the web app. |
specd doctor | Check the whole setup in dependency order. --json for CI. |
specd mcp serve | Serve the knowledge base over MCP. See MCP tools. |
Exit codes
Deliberately distinct, so a pipeline can gate on approval rather than on "something went wrong".
| Code | Means |
|---|---|
0 | Fine. |
1 | Error. |
2 | Usage. |
3 | Exists, but not approved. |
4 | doctor only — something needs fixing. |
- name: Require an approved spec
run: |
specd spec status "$SPEC_ID"
case $? in
0) echo "approved — building" ;;
3) echo "::error::$SPEC_ID is not approved yet"; exit 1 ;;
*) echo "::error::could not reach specd"; exit 1 ;;
esacEnvironment
| Variable | Purpose |
|---|---|
SPECD_API | API base URL. Default http://localhost:4000/api. |
SPECD_PROJECT | Default project slug, overriding specd use. |
SPECD_TOKEN | Token override — for CI. |
SPECD_WEB | Web origin, used by specd open. |
SPECD_RUNNER_TOKEN | Runner token override. |
The interactive shell
Run specd with no arguments at a TTY and you get an interactive shell: type / to see every command, keep typing to narrow by prefix, ↑/↓ to move, Enter to run. A command needing an argument you did not supply prompts for it rather than failing silently.
Every slash command is a thin adapter over the same function the flag-based path calls — same config loading, same errors, same behaviour. /status is deliberately not spec status <id>: it reports CLI version, connected project and auth state, while a spec's lifecycle stays at /spec-status <id>. Full mapping in docs/cli-repl.md.
specd doctor
specd is several services at once — an API, Postgres with an extension, a vault key, a web app on another origin, an optional model provider, an optional embedder, an optional paired runner. When it does not work, the failure usually surfaces as whatever broke first rather than as the cause.
doctor reports config, server, database, embeddings, AI credential, identity and default project in dependency order, and skips what an earlier failure makes unknowable rather than piling on: one broken thing reads as one broken thing. Optional configuration is reported as a note, never a fault — no platform key, no default project and the built-in embedder are all supported ways to run specd, and the embedder note names the retrieval ceiling honestly and says how to lift it.