Skip to content

CLI Reference

Run commands from the repository root unless --global is specified.

New to Tuff? Start with the Getting Started guide, then return here for the complete command and flag reference.

The reference is split by task. Each page covers its commands, their flags, and examples.

Page Commands
Start (this page) tuff, tuff init
Create and Add tuff create, tuff add, tuff scan
Packs tuff pack, tuff add pack, pack updates
MCP Servers tuff add mcp, tuff mcp catalog, tuff mcp search, tuff mcp doctor
Inspect and Generate tuff list, tuff status, tuff generate, tuff outdated, tuff policy matrix, tuff policy evaluate
Diff and Update tuff diff, tuff update
Validate in CI tuff check, GitHub Actions
Clean Up tuff delete, tuff untrack, tuff lock migrate, tuff cache clear
Harnesses and Scope tuff harness, scope
Console tuff console serve, tuff console key, tuff console publish

Show the ASCII banner and quick-start menu:

Terminal window
tuff

Initialize Tuff state in the current directory:

Terminal window
tuff init

Initialize global scope (for primitives shared across all projects):

Terminal window
tuff init --global

Creates tuff.lock (and a user-state lockfile for global scope), scaffolds .agents/, and configures open-agents as the default agent.

Project initialization also looks for the harnesses already present in the repository and registers them:

  • A .claude/ directory or a CLAUDE.md file registers claude.
  • A .cursor/ directory registers cursor.

Each registered harness is given the tuff-cli-guide skill in its own layout, so the agent you actually run can read it. Codex is not detected here, because it writes the same .agents/ root that open-agents already covers.

Every command uses the same exit codes, so a script can branch without reading the message:

Code Meaning
0 Success
1 The operation failed: something was not found, was refused, had local changes, or a source was unreachable
2 The command was called wrongly: a bad flag or argument value
70 A bug in Tuff. Worth reporting

tuff check and tuff mcp doctor exit 1 when they find a problem, which is what makes them usable as CI gates.

Failures print the message on one line and, when there is a clear next step, a hint on a second:

error: 'rust-implement' has local modifications for agent 'claude'
hint: use --force to delete them

list, outdated, diff, check, mcp doctor, mcp search, and pack inspect all take --json. When the invocation includes it, a failure is reported as one JSON line on stderr instead, so machine-readable output stays machine-readable:

{"error":{"kind":"drift","message":"'rust-implement' has local modifications for agent 'claude'","hint":"use --force to delete them"}}

The kind is one of usage, not_found, refused, drift, source, corrupt, unsupported, io, or internal.