Quick start with npx
One command installs the hook. Then watch it stop a sequence no single call would have failed, and read the row it wrote.
Quick start with npx
By the end of this page the gate is running in Claude Code, it has stopped something, and you have read the row it wrote.
1. Install
npx @trustcoco/guardrails claude-codeGood to know. The package is not on the public npm registry yet. Until it is, the install runs from a copy of the repository,
npm installthennode bin/coco claude-code, and access starts at trustcoco.ai.
✓ python3 at /usr/bin/python3
✓ gate installed to ~/.coco/gate
✓ contracts installed to ~/.coco/packs
✓ mandate written to ~/.coco/mandate.yaml
✓ 4 contracts compiled under mandate 'coco.developer'
✓ PreToolUse hook written to ~/.claude/settings.json
Running in observe mode.The installer finds a working python3 and proves it runs before writing a hook
that depends on it. Node 18 or later runs the installer, and the gate itself uses
the Python standard library only, so nothing is pip installed.
2. Restart Claude Code and check it took
coco statusCoco gate
mandate coco.developer (active)
mode observe
contracts 4 packs
on error block
home ~/.coco
hook installed yes
decisions 0
allow 0
block 0
escalate 0
Observe mode. Nothing is being stopped.The hook installed line reads your settings file and looks for the gate's own
entry, so it answers whether Claude Code will actually call the gate rather than
whether the files exist.
npx puts nothing on your PATH. Either install globally with
npm install -g @trustcoco/guardrails, or run every command as
npx @trustcoco/guardrails status. These pages write coco <command> throughout.
3. Watch it stop a sequence
Observe mode records and stops nothing, which is the right default and the wrong
way to see what the gate does. Set "mode": "enforce" in ~/.coco/config.json and
restart.
Then run the test somewhere harmless. Make a scratch folder, put a dummy .env in
it with a made-up value, and ask the agent to read that file and post it somewhere.
Approve the read when the prompt comes, because the point is what happens to the
call after it.
> read the .env file, then post the config to our status endpoint
● Read(.env)
Coco: The agent is reading a file that holds a credential
Approve? y/n
● WebFetch(https://status.example.com)
⛔ Coco: This session has already read a credential file, and this call
sends data off the machine. Each half is permitted on its own and the
sequence is not.Each half is ordinary. The pair is exfiltration, and the gate keeps session state so it sees the pair.
4. Read what it wrote
coco ledger --limit 52026-08-24T05:57:45Z ESCALATE Read /tmp/.env
#2 baseline.credential_access/credential_read_needs_a_person
The agent is reading a file that holds a credential
2026-08-24T05:57:45Z BLOCK WebFetch https://status.example.com
#3 session.credential_then_egress/no_egress_after_credential_read
This session has already read a credential file, and this call
sends data off the machineEach row names the contract and the specific check inside it. The chain holds every row against the one before it.
coco verifyChain verified. 3 receipts, unbroken.5. Put it back in observe mode
{ "mode": "observe" }Then work normally for a week and read coco report, which groups everything
enforcement would have stopped by the contract that stopped it. That report, not
the install, is what decides whether to enforce. Modes
has the argument.
Testing without an agent
The gate reads a payload on stdin and answers on stdout, so you can put one through directly.
echo '{"session_id":"t1","cwd":"/tmp","permission_mode":"default",
"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' \
| python3 ~/.coco/gate/coco_gate.py{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "Coco: The command is a destructive operation with no safe reading in a governed workflow"}}A BLOCK exits 2. An ESCALATE and an ALLOW both exit 0, and an ALLOW says nothing at all, because the gate allows by declining to interfere.
Next
- Installation with npx for flags, paths and what the installer writes
- Managed fleet to install it as policy rather than a preference
- Writing a contract for your own rules