Recipe · Claude Agent SDK
Claude Agent SDK: guard http requests with CAIN
Step by step, for an agent that fetches URLs: install, wrap the tool, see the live decision, write and test a rule, handle approvals.
Last reviewed 2026-10-02
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
pip install "cainstudio[claude-agent-sdk] @ https://cainstudio.online/cainstudio-0.4.1-py3-none-any.whl#sha256=1bea5cf49aeeb2775acec58933fc39b008a1c84bfd7c9690c54723ed707af689"
export CAIN_API_KEY=...cainstudio 0.4.1, pinned by URL and SHA-256 so pip installs exactly the published wheel (the package is not on PyPI yet). Framework dependencies come from PyPI as usual.
3 Put CAIN in front of PreToolUse hooks
cain_hooks() maps CAIN's decision onto the hook's permission decision: refused is deny, held is ask (the user decides), only an explicit allow proceeds. Tools from an in-process MCP server are named mcp__<server>__<tool>, and that is the name your rules match.
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, create_sdk_mcp_server, tool
from cainstudio.integrations.claude_agent_sdk import cain_hooks
@tool('http_get', "HTTP requests: an agent that fetches URLs", {"url": str})
async def http_get(args):
... # your existing code
return {"content": [{"type": "text", "text": "done"}]}
ops = create_sdk_mcp_server(name="ops", tools=[http_get])
options = ClaudeAgentOptions(mcp_servers={"ops": ops}, allowed_tools=["mcp__ops__http_get"],
hooks=cain_hooks(agent_id='http-agent')) # PreToolUse: CAIN decides
client = ClaudeSDKClient(options=options)On a refusal the agent gets a denied tool call with the reason. 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 mcp__ops__http_get 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
The cloud metadata address, the classic server-side request forgery target, is refused. For everything else, an egress allowlist of the hosts the agent may reach is the stronger control.
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: {"url": "https://api.github.com/repos/acme/app"}
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": "http-guard", "effect": "deny", "priority": 10, "match_path": "/tools/mcp__ops__http_get", "conditions": [{"field": "url", "op": "contains", "value": "169.254.169.254"}]}'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 http-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).
More
Claude Agent SDK, other tool types
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