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]

The package is agentguardproxy; the import name is agentguard. agentguard-sdk on PyPI is an unrelated project that also installs an agentguard module — don't install both in the same environment.

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
AGENTGUARD_TENANT_ID (empty) Guard(tenant_id=None) fallback; a value other than local routes calls to /v1/t/<tenant>/…

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")

Fail mode applies to transport failures — urllib.error.URLError (connection refused / DNS / SSL, and HTTP error statuses), OSError (post-connect timeouts and resets), json.JSONDecodeError (garbage response body) — and to responses that aren't a valid decision (a non-JSON Content-Type, or a body without decision).

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 AgentGuard exceptions (AgentGuardDenied, AgentGuardApprovalRequired, AgentGuardApprovalTimeout, AgentGuardAuthError) 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", tenant_id=None)

Method Behavior
check(scope, *, action, command, path, domain, url, session_id, est_cost, meta, approval_id) POST /v1/check (approval_id replays a resolved approval — see the quick start). 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.
  • AgentGuardApprovalTimeoutwait_for_approval deadline elapsed. Carries .approval_id.
  • AgentGuardAuthError — a wait_for_approval status poll got 401/403 (API key missing or wrong). Carries .status.

License

Apache 2.0

Release files for agentguardproxy 1.1.1

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.1
File Size Uploaded
agentguardproxy-1.1.1.tar.gz 97.3 kB Details

Built distribution (wheel)

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

Total release size: 142.3 kB

Release files / agentguardproxy-1.1.1.tar.gz

Download URL agentguardproxy-1.1.1.tar.gz
Size 97.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7c91924e4dc951018845aa103efe6abe2ad41ed38fd54cc892fb07ad9aa31076
BLAKE2b-256 checksum
How to use checksums
9fee9b3668c2a473023afeb072b8d2fa32a9b2fc522bb60e82529da5bfc22ec6
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.1-py3-none-any.whl

Download URL agentguardproxy-1.1.1-py3-none-any.whl
Size 45.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eb28c5b55f35482e25daabdada6af7fd41ae084ab52ae29b0c9fe15106d8dc17
BLAKE2b-256 checksum
How to use checksums
73a7f4c8f04e5664e374d956a0392dcd436ee3b6f994821ae58fb32a5a150ecb
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

This release

1.1.1 This release

2 release files

1.1.0

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