Skip to main content

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() returns DENY.
  • 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:
        # Replay the approval: consumes the one-shot ALLOW, reserves cost,
        # and audits the execution. The status poll alone spends nothing.
        replay = guard.check("shell", command=command, approval_id=result.approval_id)
        if replay.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_approval deadline elapsed. Carries .approval_id.

License

Apache 2.0

Release files for agentguardproxy 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentguardproxy 1.1.0
File Size Uploaded
agentguardproxy-1.1.0.tar.gz 96.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agentguardproxy 1.1.0
File Interpreter ABI Platform
agentguardproxy-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 141.6 kB

Release files / agentguardproxy-1.1.0.tar.gz

Download URL agentguardproxy-1.1.0.tar.gz
Size 96.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ad17c900f3f9ad1739a9a43a2960fc8a9ffc2389ab7dc49415d44577bb748468
BLAKE2b-256 checksum
How to use checksums
a2b0c09681fe8af78fbef430aec6901161dbad9a555ee92b46f595fdbad4d220
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / agentguardproxy-1.1.0-py3-none-any.whl

Download URL agentguardproxy-1.1.0-py3-none-any.whl
Size 44.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d2dd247e70995a2629fc2f9371bf1f2f790ad3f4bd565b32f5f119f568abce70
BLAKE2b-256 checksum
How to use checksums
f6e313b177a95645db194ffe15170a22e99e27146ec451d01333d671126bad86
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

1.1.1

2 release files

This release

1.1.0 This release

2 release files

1.0.0

2 release files

0.9.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page