Anthropic
Wrap your Anthropic client with Rune to scan all tool use blocks in Claude's responses. Same API, same types, with security added transparently.
Installation
pip install runesec[anthropic]Quick Start
from anthropic import Anthropic
from rune import Shield
from rune.integrations.anthropic import shield_client
shield = Shield(api_key="rune_live_xxx")
# Wrap the client — transparent, same API
client = shield_client(
Anthropic(),
shield=shield,
agent_id="analysis-agent",
agent_tags=["analysis", "prod"],
)
# Use exactly as before
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Analyze this dataset"}],
tools=[...],
)What Gets Scanned
Claude uses tool_use content blocks for function calls. Rune intercepts these and scans:
tool_use blocks
Each tool_use block's name and input parameters are scanned for injection, command injection, and policy violations.
tool_result content
When you send tool results back via tool_result messages, Rune scans them for secrets, PII, and indirect injection.
Text responses
Claude's text content blocks are scanned for data leaks before reaching the user.
Agentic Loop Pattern
For agents that run Claude in a loop (calling tools until the task is complete), the wrapper automatically scans every iteration:
messages = [{"role": "user", "content": task}]
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
messages=messages,
tools=tools,
)
# Rune scans tool_use blocks in each response automatically
if response.stop_reason == "end_turn":
break
# Execute tools and add results
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": block.id, "content": result}],
})
# Rune scans tool_result content tooConfiguration
client = shield_client(
Anthropic(),
shield=shield,
agent_id="my-agent", # Required: unique identifier
agent_tags=["prod"], # Optional: for policy targeting
block_on_error=False, # Optional: fail open if Rune unreachable
)Complete Runnable Example
Copy, paste, and run to verify your Anthropic integration:
import os
assert os.environ.get("RUNE_API_KEY"), "Set RUNE_API_KEY"
assert os.environ.get("ANTHROPIC_API_KEY"), "Set ANTHROPIC_API_KEY"
from anthropic import Anthropic
from rune import Shield
from rune.integrations.anthropic import shield_client
shield = Shield()
client = shield_client(Anthropic(), shield=shield, agent_id="anthropic-test", agent_tags=["test"])
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=256,
messages=[{"role": "user", "content": "Say hello in French"}],
)
print("Response:", response.content[0].text)
print("Stats:", shield.stats)Next Steps
- Write Policies — Restrict tool access for your Claude agents
- SDK Reference — Full API documentation
- Prompt Injection — The #1 threat to Claude-based agents