Skip to main content

Claude Agent SDK

The Claude Agent SDK uses the same hook mechanism as Claude Code. Hooks defined in .claude/settings.json fire on tool calls made by SDK-built agents exactly as they do during interactive Claude Code sessions. No additional adapter or integration code is required.

Setup

pip install vectimus claude-agent-sdk
vectimus init

That’s it. vectimus init writes a PreToolUse hook to .claude/settings.json. The Claude Agent SDK reads this file on startup and fires the hook on every tool call.

How it works

  1. vectimus init writes a PreToolUse hook to .claude/settings.json
  2. The Claude Agent SDK reads .claude/settings.json on startup
  3. Every tool call (Bash, Write, Edit, Agent, MCP, etc.) triggers the hook
  4. Vectimus evaluates the call against Cedar policies and returns allow/deny
  5. Denied calls are blocked before execution — the agent sees a clear message and can try a different approach

The hook configuration is identical for both Claude Code and Claude Agent SDK:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "vectimus hook --source claude-code"
          }
        ]
      }
    ]
  }
}

Basic example

from claude_agent_sdk import Agent

agent = Agent(
    model="claude-sonnet-4-20250514",
    prompt="List the files in the current directory using the Bash tool.",
    allowed_tools=["Bash", "Read", "Glob"],
)

# Tool calls that violate a Vectimus policy are blocked.
# The agent sees: "Blocked by Vectimus policy vectimus-supchain-001: ..."
result = agent.run()
print(result)

MCP tool governance

When your SDK-built agent connects to MCP servers, Vectimus governs those tool calls too. MCP tool names follow the pattern mcp__<server>__<tool> and are evaluated against the MCP allowlist and input inspection policies.

agent = Agent(
    model="claude-sonnet-4-20250514",
    prompt="Query the my-database MCP server to list all users.",
    allowed_tools=["Bash", "Read", "mcp__my-database__query"],
)

By default Vectimus blocks all MCP tool calls unless the server is on the approved list:

vectimus mcp allow my-database

Multi-agent governance

The Claude Agent SDK supports multi-agent patterns where a primary agent spawns sub-agents. Vectimus governs the entire tree — every tool call from every agent passes through the same PreToolUse hook.

This is particularly important because:

  • Sub-agents may be spawned with elevated permissions (bypassPermissions)
  • Background agents run unsupervised and can accumulate risky actions
  • Inter-agent messages can be used to exfiltrate data or hijack goals

Vectimus agent governance policies specifically target these risks:

PolicyWhat it blocks
vectimus-agentgov-006Agent spawns with bypassPermissions or dontAsk mode
vectimus-agentgov-008Agent spawns with max_turns > 50 (runaway cost)
vectimus-agentgov-009Uncontrolled TeamCreate calls (swarm creation)
vectimus-agentgov-005Broadcast SendMessage calls (goal hijacking)
agent = Agent(
    model="claude-sonnet-4-20250514",
    prompt=(
        "You are a code review agent. Use sub-agents to:\n"
        "1. Spawn an Explore agent to find all Python files\n"
        "2. Read the files and summarize any issues\n"
        "Do NOT use bypassPermissions mode on sub-agents."
    ),
    allowed_tools=["Bash", "Read", "Glob", "Agent"],
)

result = agent.run()

Observe mode

To trial policies without blocking:

vectimus observe on

Or set the environment variable (useful for CI/CD):

export VECTIMUS_OBSERVE=true

In observe mode, Vectimus logs all policy decisions to ~/.vectimus/logs/ but never blocks tool calls. Review the audit log, then switch to enforcement with vectimus observe off.