Start here
Two ways in, both measured in minutes. Pick the one that sounds like you — you can always come back for the other.
🛡️
I use an AI assistant
Put limits on what it can do — 60 seconds, no code, no account.
🔧
I build agents
Your first agent in 5 minutes, with limits built in from day one.
Protect the assistant you already use
If your AI assistant (Claude Desktop, Cursor, Windsurf…) is connected to tools — GitHub, your files, a database — those tools will do whatever the AI asks. This adds a safety layer: some actions blocked, some ask you first, everything logged.
Open your assistant's tool config file
It's a small settings file listing the tools your assistant can use. Claude Desktop: claude_desktop_config.json · Cursor: ~/.cursor/mcp.json ·all clients →
Wrap a tool with the guard
Take any entry in that file and put the guard in front of it. Before and after:
// before // after
"github": { "github": {
"command": "npx", "command": "npx",
"args": ["-y", "args": ["-y", "@aroha-sdk/mcp-guard",
"@modelcontextprotocol/server-github"] "--block", "delete_*",
} "--gate", "merge_*",
"--",
"npx", "-y", "@modelcontextprotocol/server-github"]
}Plain English: anything starting with delete can never happen. Anything starting with merge asks you first. Everything else works exactly as before.
Restart your assistant and test it
Ask it to delete something. It will tell you the action was blocked by policy — and a log of every decision lands in ~/.aroha/mcp-guard.jsonl. That's it. You're done.
Build your first agent
An agent here is just a function behind an HTTP endpoint — with one superpower available when you want it: callers can hand it a signed permission slip (a mandate) that it physically cannot exceed.
Serve a function
import { serve } from "@aroha-sdk/run"; // npm i @aroha-sdk/run
const agent = serve("hello", async ({ message }) => `You said: ${message}`);
agent.start(8000);Python is the same shape: pip install aroha, decorate a function with @serve.
Call it
curl -X POST http://localhost:8000/v1/run \
-H "Content-Type: application/json" \
-d '{"message": "hello there"}'Streaming, sessions, and a health check are already wired. That's a complete agent.
Give it a limit it can't break
When your agent starts doing things that matter — spending, sending, deleting — you stop trusting instructions and start issuing signed permission slips. This one says “research only, at most 20 searches”:
import { issueTaskMandate } from "@aroha-sdk/credentials";
const { token } = await issueTaskMandate(
myDid, agentDid,
["research", "web-search"], // the only things it may do
{ actionLimits: { "web-search": 20 } }, // and no more than this
myPrivateKey,
);The 21st search doesn't fail politely — it's refused by signature verification, no matter what the model wants.
📋
Evaluating the protocol?
The full depth is here and it isn't simplified: formal spec, five-layer architecture, threat model, conformance suite, and the research behind the design.