CAIN-42 CAIN Studio

Recipes

TypeScript / JavaScript with CAIN

CAIN decides before any async function runs anything. 10 worked recipes.

Last reviewed 2026-10-02

There is no npm package yet: copy the helper from the TypeScript page (Node 18+, Deno, Bun, edge runtimes, no dependencies). guard() throws unless the verdict is ALLOWED and not blocked; a timeout or error is a refusal.

Pick the kind of tool

Payments

An agent that can move money: transfer_funds

Refunds

A support agent that issues refunds: issue_refund

Email

An agent that sends email: send_email

SQL

An agent with database access: run_sql

Shell

An agent that runs shell commands: run_shell

HTTP requests

An agent that fetches urls: http_get

Files

An agent that writes files: write_file

Deployments

An agent that ships code: deploy_service

Customer data

An agent that exports records: export_customers

Code merges

An agent that merges pull requests: merge_pull_request

The whole path, with payments as the example

1 Get a key

No key yet? Create a free account (every new account starts with a 7-day trial), then copy the key from the console. Requests go from your browser straight to this site.

Give each agent its own key in production (console → Agent keys): decisions, trust history and revocation are then per agent.

2 Install

Copy cain.ts from the TypeScript page into your project and set CAIN_API_KEY.

3 Put CAIN in front of any async function

There is no npm package yet: copy the helper from the TypeScript page (Node 18+, Deno, Bun, edge runtimes, no dependencies). guard() throws unless the verdict is ALLOWED and not blocked; a timeout or error is a refusal.

import { guard } from "./cain";   // the ~30-line helper from /docs/sdk-typescript

export const transferFunds = guard('transfer_funds', async (args: { amount_usd: number; to_account: string }) => {
  // your existing code, unchanged
}, 'payments-agent');

// throws CainRefused unless CAIN answers ALLOWED for these exact arguments

On a refusal the agent gets a CainRefused error carrying the decision. The tool body never runs: not on a refusal, not on a hold, not when CAIN cannot be reached.

4 See what CAIN decides for this exact call

This is the request the integration sends when the model calls transfer_funds with these arguments. record: false evaluates it without writing an evidence record. A new agent has no trust history, so expect REQUIRE_APPROVAL at first; destinations outside your egress allowlist are refused by the egress stage.

5 Write the rule, and test it before you save it

Small transfers run; anything over $100 waits for a person. The amount the rule reads is the one the model actually chose, because the adapter sends the call's real arguments.

The panel sends the draft rule to the rule tester: it says which rule would decide the call and saves nothing. Swap in the safe arguments below to see it pass through. matches is a case-insensitive glob (*, ?), not a regular expression; conditions on one rule must all hold; the first matching rule by priority wins.

Safe arguments: {"amount_usd": 25, "to_account": "acct-991"}

When it does what you want, save it from the console or with POST /fabric/tool-rules:

curl -sS -X POST https://cainstudio.online/fabric/tool-rules \
  -H "X-API-Key: $CAIN_API_KEY" -H 'Content-Type: application/json' \
  -d '{"name": "payments-guard", "effect": "require_approval", "priority": 10, "match_path": "/tools/transfer_funds", "conditions": [{"field": "amount_usd", "op": "gt", "value": 100}]}'

6 Handle the calls that wait for a person

A held call is not executed. It appears in the approval queue with its exact arguments; an approval lets that one call run once. Adapters can wait instead of returning: wait_for_approval=120.

GET /fabric/approvals

7 Check it before you ship

cainstudio redteam --agent payments-agent   # dry-runs dangerous calls; exit 2 if any would run
cainstudio decisions                 # what was decided, and why
cainstudio explain <decision_id>

Every recorded decision is signed; Cain().verify(decision) checks its quorum certificate on your machine (Python SDK).

Try CAIN-42 on your own agents

Create a free account and every new account starts with a 7-day trial of the full platform. Or try the sandbox first, with no account at all.

Create a free account →  ·  Try the sandbox  ·  See the whole ecosystem