Python SDK for AgentGuard — the firewall for AI agents
Project description
AgentGuard Python SDK
Lightweight Python client for AgentGuard — the firewall for AI agents.
- Zero runtime dependencies for the core SDK (stdlib
urllib). - Fail-closed by default — if the proxy is unreachable,
check()returnsDENY. - Framework adapters for LangChain, CrewAI, browser-use, and MCP, gated behind optional extras.
Deep reference:
docs/SDK_PYTHON.md— full API, exception hierarchy, fail-mode details, adapter internals.
Install
pip install agentguardproxy
# With framework adapters
pip install agentguardproxy[langchain]
pip install agentguardproxy[crewai]
pip install agentguardproxy[browser-use]
pip install agentguardproxy[all]
Quick start
from agentguard import Guard
guard = Guard(
base_url="http://localhost:8080", # or set AGENTGUARD_URL
agent_id="my-agent",
api_key="…", # or set AGENTGUARD_API_KEY (needed for approve/deny/status)
)
result = guard.check("shell", command="rm -rf ./old_data")
if result.allowed:
execute(command)
elif result.needs_approval:
print(f"Approve at: {result.approval_url}")
# Block until a human resolves it, or 5 min deadline, whichever first
final = guard.wait_for_approval(result.approval_id, timeout=300)
if final.allowed:
execute(command)
else:
print(f"Blocked: {result.reason}")
Environment variables
| Var | Default | Used by |
|---|---|---|
AGENTGUARD_URL |
http://localhost:8080 |
Guard(base_url="") fallback |
AGENTGUARD_API_KEY |
(empty) | Guard(api_key="") fallback; sent as Authorization: Bearer <key> on /v1/approve, /v1/deny, /v1/status |
Fail mode
# Default: fail closed. Proxy unreachable → CheckResult(decision="DENY", reason="AgentGuard unreachable (deny): …")
guard = Guard("http://localhost:8080")
# Opt in to fail open. Proxy unreachable → CheckResult(decision="ALLOW", reason="AgentGuard unreachable (allow): …")
# Use only when your threat model treats AgentGuard as advisory.
guard = Guard("http://localhost:8080", fail_mode="allow")
Three classes of transport failure are caught: urllib.error.URLError (connection refused / DNS / SSL), OSError (post-connect timeouts and resets), and json.JSONDecodeError (garbage response body).
The @guarded decorator
from agentguard import Guard, guarded, AgentGuardDenied, AgentGuardApprovalRequired
guard = Guard("http://localhost:8080", agent_id="my-agent")
@guarded("shell", guard=guard)
def run_command(cmd: str):
os.system(cmd)
try:
run_command("ls")
run_command("rm -rf /") # raises AgentGuardDenied
except AgentGuardDenied as e:
log(f"blocked: {e.result.reason}")
On REQUIRE_APPROVAL the decorator raises AgentGuardApprovalRequired immediately. To block until a human resolves it, opt in:
@guarded("cost", guard=guard, wait_for_approval=True, approval_timeout=300)
def expensive_call(prompt: str): ...
All three exceptions (AgentGuardDenied, AgentGuardApprovalRequired, AgentGuardApprovalTimeout) extend PermissionError, so existing except PermissionError: handlers keep working unchanged.
Framework adapters
LangChain
from agentguard.adapters.langchain import GuardedToolkit
toolkit = GuardedToolkit(
tools=my_tools,
guard_url="http://localhost:8080",
agent_id="langchain-agent",
)
agent = create_react_agent(llm, toolkit.tools, prompt)
Scope is inferred from each tool's name/description (http/api→network, file/path→filesystem, browser→browser, shell→shell) and upgraded at call time if the input dict contains url, domain, or path keys.
CrewAI
from agentguard.adapters.crewai import guard_crew_tools
guarded_tools = guard_crew_tools(
tools=my_crew_tools,
guard_url="http://localhost:8080",
agent_id="crew-agent",
)
Hooks both run and _run (CrewAI calls _run internally).
browser-use
from agentguard.adapters.browseruse import GuardedBrowser
browser = GuardedBrowser(guard_url="http://localhost:8080")
if browser.check_navigation("https://example.com").allowed:
await page.goto("https://example.com")
# Or wrap the page directly so goto() enforces policy for you:
guarded_page = browser.wrap_page(page)
await guarded_page.goto("https://example.com") # raises PermissionError on deny/approval
MCP
from agentguard.adapters.mcp import GuardedMCPServer
server = GuardedMCPServer(guard_url="http://localhost:8080")
server.add_tool("my_tool", "Description", handler=my_handler)
server.run() # stdio JSON-RPC MCP server; pins MCP_PROTOCOL_VERSION
Or as a drop-in stdio server:
python -m agentguard.adapters.mcp --guard-url http://localhost:8080
API reference (summary)
Guard(base_url="", agent_id="", timeout=5, api_key="", fail_mode="deny")
| Method | Behavior |
|---|---|
check(scope, *, action, command, path, domain, url, session_id, est_cost, meta) |
POST /v1/check. Returns CheckResult. Transport failure → fail-closed DENY (or ALLOW if fail_mode="allow"). |
approve(id) / deny(id) |
POST /v1/approve/{id} / /v1/deny/{id}. Returns bool success. Sends Bearer if api_key set. |
wait_for_approval(id, timeout=300, poll_interval=2) |
Polls GET /v1/status/{id} until resolved or deadline. Timeout → CheckResult(DENY, "Approval timed out"). |
CheckResult
Fields: decision, reason, matched_rule, approval_id, approval_url. Properties: .allowed, .denied, .needs_approval.
Exception hierarchy (all extend PermissionError)
AgentGuardError— base; carries.result: CheckResult.AgentGuardDenied— policy said DENY.AgentGuardApprovalRequired— policy said REQUIRE_APPROVAL and the decorator was not configured to wait. Carries.approval_id,.approval_url.AgentGuardApprovalTimeout—wait_for_approvaldeadline elapsed. Carries.approval_id.
License
Apache 2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agentguardproxy-0.5.1.tar.gz.
File metadata
- Download URL: agentguardproxy-0.5.1.tar.gz
- Upload date:
- Size: 90.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d20747694d2b1d5765707dccc5f693da8c7458a8e8edbdea51c3df8652e05393
|
|
| MD5 |
95fee3567eb0515c588689985cd9ca20
|
|
| BLAKE2b-256 |
d58e772f956454c03e1b740f4c48b97908980e8f6d4e36f9d2541cd9a7c9521d
|
File details
Details for the file agentguardproxy-0.5.1-py3-none-any.whl.
File metadata
- Download URL: agentguardproxy-0.5.1-py3-none-any.whl
- Upload date:
- Size: 41.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64bea44551d7bfc0badb3fd40d360e53c1df727bd4c7c2f21740d58da85f13e2
|
|
| MD5 |
f3e5b5847321289bdac2cd6f877d2112
|
|
| BLAKE2b-256 |
82b6d9abbd6c1cb0873d7ab9034c0b071db827f3acf94862439cb0857435a939
|