Skip to content

Global Flags & Exit Codes

Every saferskills command accepts the same set of global flags — --json, --color/--no-color, -v/--verbose, -q/--quiet, --yes, --force, and --non-interactive (alias --no-input) — reads a handful of SAFERSKILLS_* environment variables, and returns a stable exit code (0 ok, 1 generic/findings-block, 2 usage, 3 not-found, 4 permission, 5 conflict, 6 network/offline, 130 SIGINT). Output discipline is fixed: stdout is machine data, stderr is everything human.

These flags are global — they apply to info, install, uninstall, update, list, search, doctor, capability, agent, and completion alike:

FlagEffect
--jsonEmit machine-readable output on stdout. Suppresses the banner and human chatter.
--color <auto|always|never>Control ANSI color. Defaults to auto.
--no-colorForce color off (equivalent to --color never).
-v, --verboseIncrease log detail on stderr.
-q, --quietSuppress non-essential human output.
--yesAuto-confirm prompts (e.g. a below-threshold install).
--forceBypass the red-tier name gate on install.
--non-interactive, --no-inputNever prompt; assume non-TTY behavior.
Terminal window
npx saferskills --json info mcp-server-github
npx saferskills --non-interactive install mcp-server-github --yes

Why is output split between stdout and stderr?

Section titled “Why is output split between stdout and stderr?”

So you can pipe machine output without it being polluted by human text. stdout carries machine data only (JSON when --json is set); stderr carries everything human — steps, warnings, errors, and the two-line SaferSkills banner. That split lets you do this safely:

Terminal window
npx saferskills --json info mcp-server-github > result.json

result.json contains only the data envelope; the banner and any progress lines went to stderr. The banner is suppressed under --json and --quiet, and for the completion and man outputs.

How does the CLI decide whether to use color?

Section titled “How does the CLI decide whether to use color?”

Color resolves from --color/--no-color first, then the standard environment controls. The CLI honors NO_COLOR (disable), CLICOLOR_FORCE (force on), and TERM=dumb (disable). An explicit --color <auto|always|never> overrides those environment variables.

What environment variables does the CLI read?

Section titled “What environment variables does the CLI read?”

The CLI reads a small, closed set of SAFERSKILLS_* variables plus the standard color and opt-out conventions. Precedence across all configuration is CLI flags → SAFERSKILLS_* env → config.toml → defaults.

VariableEffect
SAFERSKILLS_API_URLAPI origin to call. Precedence: env → config.toml api_urlhttps://saferskills.ai.
SAFERSKILLS_MIN_SCOREMinimum aggregate score (0–100) that installs without a confirm. Precedence: env → config.toml min_score90.
SAFERSKILLS_DIROverride the state directory (default ~/.saferskills/, which holds config.toml and installs.json).
SAFERSKILLS_NO_TELEMETRYDisable all telemetry — usage analytics and install reporting. DO_NOT_TRACK and CI are honored the same way.
SAFERSKILLS_TELEMETRYForce usage analytics on (1/true) or off (0), skipping the first-run prompt. Does not affect install reporting.
NO_COLOR / CLICOLOR_FORCE / TERM=dumbStandard color controls; --color overrides them.

Two opt-out conventions are honored exactly like SAFERSKILLS_NO_TELEMETRY: DO_NOT_TRACK and CI. Source and fork builds send nothing on either telemetry channel regardless of these variables, because telemetry requires a key baked in at release time. See the telemetry section of the install reference and the privacy policy for what is — and is not — collected.

Every command returns one of a fixed set of exit codes, so you can branch on the result in a script or CI step:

CodeMeaning
0Success.
1Generic failure, or a findings-block (e.g. an install refused on score, or agent over a --fail-on threshold).
2Usage error (invalid arguments — emitted by the argument parser).
3Not found (the named capability could not be resolved).
4Permission error (a filesystem write was denied).
5Conflict (e.g. an install/registry state collision).
6Network, rate-limit, or offline error.
130Interrupted (Ctrl-C / SIGINT).
Terminal window
npx saferskills --non-interactive install mcp-server-github
if [ $? -ne 0 ]; then
echo "install did not complete cleanly" >&2
fi