Developer documentation
CLI
Last reviewed 31 August 2026
All docs
CLI reference#
Start here: cainstudio (installs with the SDK)#
The command you get today comes with the Python SDK wheel:
pip install https://cainstudio.online/cainstudio-0.3.0-py3-none-any.whl
export CAIN_API_KEY=... # from /signup
cainstudio try # a real decision, no key needed
cainstudio decide send_email --agent my-agent --args '{"to": "a@example.com"}'
cainstudio approvals # what is waiting for you
cainstudio approve <approval_id> # use your key, not the agent's: a key cannot approve its own request
cainstudio decisions # recent decisions
cainstudio explain <decision_id> # why it came out that way
cainstudio deny <approval_id>
Every subcommand takes --json and --base-url. Checked against the published wheel on 1 October 2026 (cainstudio --help).
The full cain CLI (not yet installable on its own)#
The reference below documents cain, the operator CLI that ships with self-hosted MCPGate and the source distribution. It is not published as a standalone package yet, so on a laptop with only the SDK installed, use cainstudio above.
Twenty commands. Every one accepts --json, and every one returns a meaningful exit code, because the second thing anyone does with a tool like this is put it in CI.
Exit codes#
| code | meaning |
| 0 | success / authorized / all checks passed |
| 1 | a check failed, or the action was denied |
| 2 | usage error (bad flag, missing config) |
| 3 | could not reach the fabric |
| 4 | not authenticated |
1 and 3 are deliberately distinct: a pipeline needs to tell a policy refusal apart from an outage.
cain --help#
usage: cain [-h] [--version] [--json] [--env NAME] [--endpoint URL]
[--timeout SECONDS] [--no-strict]
<command> ...
CAIN Trust Fabric -- authorize, enforce and audit what your agents do.
positional arguments:
<command>
init create cain.yaml in this project
login authenticate this machine against a fabric
connect check a fabric answers and report what it enforces
protect guard an agent, or put MCPGate in front of an MCP server
run run a command with CAIN configured in its environment
verify ask the fabric to decide about one action
explain show why one decision came out the way it did
inspect list recent decisions, or one agent run
audit evidence: signatures, and who has read what
doctor diagnose this setup and report what is unprotected
test conformance and red-team suite -- can this deployment be
trusted?
policy show or dry-run policy
status is the fabric up, and what is it enforcing?
validate check cain.yaml is valid and fail-closed
options:
-h, --help show this help message and exit
--version show program's version number and exit
--json machine-readable output
--env NAME cain.yaml environment overlay to apply
--endpoint URL override fabric endpoint
--timeout SECONDS override request timeout
--no-strict treat an undetermined verdict as ALLOW (not recommended)
one-minute quickstart:
cain login authenticate this machine
cain init create cain.yaml (fail-closed defaults)
cain protect show the smallest change to guard your agent
cain run agent.py run it with CAIN configured
then:
cain doctor is anything misconfigured or unprotected?
cain test does enforcement actually work end to end?
cain inspect what decisions have been made
cain explain <id> why one decision came out the way it did
Every command accepts --json.
Exit codes: 0 ok, 1 failed/denied, 2 usage, 3 unreachable, 4 unauthenticated.
Commands#
cain init#
Create cain.yaml. Detects your runtime from requirements.txt / package.json.
cain init --name billing-agent --runtime langgraph cain init --self-hosted # target MCPGate rather than CAIN Studio
cain login#
Authenticate this machine. The key is verified before being stored; a rejected key is not written anywhere.
cain login --api-key <key> echo "$KEY" | cain login cain login --logout
cain connect#
Prove a fabric answers and report what it actually enforces -- including which stages are advisory rather than blocking. Run this first against a freshly self-hosted MCPGate.
cain protect#
Print the smallest real integration for your runtime. Does not edit your source: the change is three lines you should read, and a tool that silently rewrites application code stops being trusted the first time it guesses wrong.
cain protect # your agent cain protect mcp ./my-server # an MCP server
cain run#
Run a command with CAIN configured in its environment.
cain run python agent.py cain run -- node agent.js --flag
Refuses to start when the fabric is unreachable unless you pass --skip-preflight.
cain verify#
Ask for one decision, from the shell.
cain verify --action /send --resource email-service
cain verify --action delete --resource customer --payload '{"id":"c_1"}'
cain verify --plan '[{"tool":"refund","args":{"amount":500}}]'
Exit code follows the verdict, so cain verify ... && do_the_thing is safe.
cain explain <decision-id>#
The full stage-by-stage trace: identity, policy and the policy *version* that produced it, risk, verification, approval, enforcement, execution, evidence.
cain inspect#
Recent decisions, or one correlated agent run:
cain inspect --limit 50 cain inspect --chain cor_9f2a...
cain audit#
Evidence. Signature for one decision, or the access log of who has read evidence.
cain doctor#
Diagnose everything and report what is unprotected. See troubleshooting.
cain test#
Conformance + red-team suite. See conformance.
cain test cain test --suite redteam cain test --suite isolation --verbose cain test --json | jq .conformance
cain policy#
cain policy show cain policy test --action /refund --resource billing
cain status#
Is the fabric up, and what is it enforcing right now?
cain validate#
Validate cain.yaml. An unknown key is an error, not a warning -- a key that gets silently ignored is how a config ends up looking stricter than it is.
cain validate cain validate --list-keys
Global flags#
--json machine-readable output (every command) --env NAME apply a cain.yaml environments: overlay --endpoint URL override the fabric endpoint --timeout SECS override request timeout --no-strict treat an undetermined verdict as ALLOW (not recommended)