Skip to main content
Glama

AgentGuard

Stop runaway agents with runtime checks in Python.

PyPI version Python versions CI License: MIT

AgentGuard checks budgets, repeated tool calls, retries, and elapsed time in instrumented Python code. Guards raise exceptions so your application can stop the next operation. The base SDK has no runtime dependencies and needs no account.

Names: this repository is agent47, the PyPI package is agentguard47, and the Python import is agentguard. AgentGuard 2.0.0 requires Python 3.11 or newer. On Python 3.9 or 3.10, pin agentguard47==1.4.0. See the Python migration guide before upgrading.

Getting started

Install in a virtual environment, then run the offline checks:

python -m pip install agentguard47
agentguard doctor
agentguard demo

doctor checks the installation and local trace writing. demo exercises budget, loop, and retry stops without provider keys or network access. Follow the trace path printed by the command to inspect its output. agentguard demo --feedback prints a local redacted report; nothing is sent.

For a fresh PowerShell install and a runnable raw starter, follow the published-release walkthrough.

Share a stop receipt (new in 2.0.0)

agentguard receipt agentguard_demo_traces.jsonl prints a receipt of each stop with the trace's SHA-256 drawn as a barcode. Add --format markdown to paste it into a PR or issue. The hash identifies the trace file; it is not a signature. This stop receipt records a covered guard refusal. Anthropic's official /receipts plugin summarizes past Claude Code work (30 days by default). Neither output proves prevented spend or provides a signed attestation. The agentguard receipt command stays the same.

Guard a Claude Code session (new in 2.0.0)

agentguard hook claude-code --install --write

This installs a Claude Code hook that refuses the third identical tool call in a row and a call that already failed twice. "Identical" ignores JSON key order and preserves case and whitespace in values. The optional no_progress_max rule refuses a tool after repeated empty or same-error results even when input changes; it is off by default. Refusals omit raw input and go to .agentguard/claude-code/trace.jsonl. It checks tool calls, not tokens or subscription quota. See the Claude Code hook guide.

Guard a script without editing it (new in 2.0.0)

agentguard run --budget-usd 5 agent.py

This patches the OpenAI and Anthropic clients, then runs agent.py in the same interpreter. Settings come from flags, then environment variables, then .agentguard.json. A guard stop exits 1. Every run ends with the trace path on stderr, ready for agentguard receipt. agentguard run python -m mypkg works too. The bounds are the same as patching the client yourself; see enforcement boundary.

Subprocesses start a separate interpreter and are not patched by the parent. A detached, uninstrumented child can keep running after the guarded script exits. The offline reproduction demonstrates that boundary with two simulated calls and no network access.

agentguard run prices every patched call at paid rates, including a local model behind an OpenAI-compatible URL such as Ollama. A dollar budget can then stop a model that costs nothing. For a local model, patch the client in the script with free_local_clients=[client] and a BudgetGuard token or call cap, then run the script with python; see free local clients.

Stop before a third call

Save this as budget_demo.py and run python budget_demo.py. It makes no network requests.

from agentguard import BudgetExceeded, BudgetGuard

budget = BudgetGuard(max_calls=2)
completed = 0

for _ in range(3):
    try:
        budget.check()  # Check before the operation.
        # Put your provider or tool call here.
        completed += 1
        budget.consume(calls=1)  # Record the completed operation.
    except BudgetExceeded:
        print(f"Stopped before call {completed + 1}")

assert completed == 2

Expected output: Stopped before call 3.

Stop a reworded loop

A stuck agent often rewords each retry, so no call repeats exactly. max_no_progress counts results instead: the same tool coming back empty, or with the same error, N times in a row stops the run whatever the arguments. normalize=True canonicalizes containers while preserving case and whitespace in argument values. Both options are off by default.

from agentguard import LoopDetected, LoopGuard

loop = LoopGuard(normalize=True, max_no_progress=3)

for pattern in ["retry_count", "retryCount", "retries"]:
    loop.check("grep", {"pattern": pattern})
    matches = []  # Put your search here. This one finds nothing.
    try:
        loop.record_result("grep", matches, tool_args={"pattern": pattern})
    except LoopDetected as stop:
        print(stop)

Expected output: No progress: grep came back empty 3 times in a row (limit: 3). Change the approach instead of rewording the call. Functions wrapped with trace_tool feed results to the guard automatically. Any other result in between starts the count over, so pagination and edit-then-test cycles do not trip it.

Connect a provider

Install the provider's client separately. For OpenAI:

python -m pip install openai
from agentguard import BudgetGuard, JsonlFileSink, Tracer, patch_openai

budget = BudgetGuard(max_cost_usd=5.00)
tracer = Tracer(
    service="my-agent",
    sink=JsonlFileSink(".agentguard/traces.jsonl"),
)
patch_openai(tracer, budget_guard=budget)
# Make your OpenAI chat.completions.create or responses.create calls after this setup.

Standard OpenAI clients created earlier are covered too, including resource objects obtained before the patch. Activate the patch before sending requests or saving bound methods and raw/streaming response helpers. Those saved references can retain the original callable; recreate them after activation. patch_openai_async() covers async clients, and agentguard.init() enables both. See the enforcement boundary.

The patch checks recorded usage before dispatch and records response usage afterward, including streamed calls once the final usage arrives. A response can exceed the remaining cost or token allowance. Concurrent requests do not reserve capacity. Chat Completions streams request include_usage unless the caller already set it.

The OpenAI Agents SDK runs on responses.create, so agentguard.init() before the Runner puts every model call under the budget (example). Hosted tools and background=True responses are not covered. See the getting started guide for setup, traces, and framework starters.

Related MCP server: Langfuse MCP Server

How enforcement works

flowchart TD
    accTitle: AgentGuard operation checks
    accDescr: Check a limit before an operation, then record usage.
    A[Instrumented operation] --> B{Guard check}
    B -->|Limit reached| C[Raise exception]
    B -->|Allowed| D[Run operation]
    D --> E[Record usage and trace]
    E --> A

Text equivalent: check before an operation, run it if allowed, then record usage. A guard exception returns control to your application's error handler.

Guard

Checks

Raises

BudgetGuard

Recorded calls, tokens, or estimated cost

BudgetExceeded

LoopGuard

Repeated tool calls; opt in to normalize=True and max_no_progress=N for reworded ones

LoopDetected

FuzzyLoopGuard

Tool frequency and alternating patterns

LoopDetected

RetryGuard

Retries per tool

RetryLimitExceeded

TimeoutGuard

Elapsed time when checked

TimeoutExceeded

RateLimitGuard

Calls within a sliding minute

BudgetExceeded

X402SpendGuard

Payment amounts before the payment callback

BudgetExceeded

For task budgets, use BudgetGuard.goal(...). For signatures and defaults, read the guard source and public exports.

Budgets can also persist across runs: configure JsonFileStateStore, a shared key, and period="day" for a daily counter. Set warn_at_pct=0.8 and an on_warning callback for an 80% warning. Workers must explicitly share the store and key; child-agent budget inheritance is not automatic. Monthly SDK limits are not implemented. See the capability matrix.

Limits and security

  • Guards cover operations you instrument. Installing the package does not intercept every action in Cursor, Claude Code, or another agent.

  • A guard is not a sandbox or permission system. A permitted operation can still be destructive.

  • Timeout checks do not interrupt an already blocked function or cancel an agent running on a provider's server.

  • Cost estimates are not invoices. Supply reported cost or use strict cost resolution when an estimate is insufficient.

  • Recorded-budget preflight refuses the next instrumented call when stored usage is already at a cap. It does not reserve concurrent in-flight requests, predict the next response, or cap a provider subscription. See the enforcement boundary.

  • The base SDK uses the standard library. Optional framework extras install third-party dependencies and need their own security review.

  • The optional [crewai] extra pulls ChromaDB. The 2026-09-12 audit found four unresolved advisories, including PYSEC-2026-311 / CVE-2026-45829. Review that exposure before installing the extra. Base SDK installs do not include ChromaDB.

  • Trace content can contain application data. Review it before sharing or configuring a remote sink.

See security reporting, the dated dependency audit, and release notes. Audit results describe their recorded date, not a permanent clean bill of health.

Local traces and optional hosted ingest

The SDK is the free local proof path. Start local. Add hosted ingest only when you need retained history, alerts, team visibility, spend trends, hosted decision history, or dashboard-managed remote kill signals.

Local guards remain authoritative. HttpSink mirrors trace and decision events; it does not execute remote kill signals by itself. See the dashboard contract before configuring it.

Local use has no hosted event quota, retention period, or API-key allocation. Network egress requires an integration you configure, such as HttpSink or an OpenTelemetry exporter.

Nothing in the local SDK phones home. The AgentGuard website describes the optional hosted service.

Documentation

You want to

Start here

See which paths actually stop a call

Enforcement boundary

Install and trace a first run

Getting started

Find guides and source references

Documentation index

Try a runnable example

Examples

Connect LangChain, LangGraph, or CrewAI

Integration guides

Inspect hosted data through MCP

Read-only TypeScript MCP server

Use local budget tools through MCP

Python budget MCP server

Navigate with an AI assistant

AI documentation index

Contribute a fix

Contributing

Check what changed

Changelog

Help and maintenance

Maintained by Patrick Hughes. Report a bug with the package version, a minimal reproduction, and the expected result. Report vulnerabilities through SECURITY.md.

The source metadata defines the branch version. The PyPI badge links to the published version. Documentation examples and local links are tested in CI. The PyPI README is generated from this README and the changelog.

MIT license.

Available Tools

7 tools
check_budgetA
Read-onlyIdempotent

Read-only hosted event-quota health check. Combines dashboard event quota and recorded cost summaries. This is not SDK BudgetGuard, not a provider invoice cap, and it does not refuse the next model call.

Inputs: no named parameters.

get_alertsA
Read-onlyIdempotent

Read-only recent guard alerts (loop detection, budget exceeded) and errors from the hosted Read API. This reports stored alerts; it does not stop a running agent.

Inputs: limit, since.

get_costsA
Read-onlyIdempotent

Read-only hosted cost breakdown for the current month from the AgentGuard Read API. Estimated savings are recorded guard events, not an invoice credit.

Inputs: no named parameters.

get_traceA
Read-onlyIdempotent

Read-only full event tree for one retained trace. Shows spans, tool calls, LLM calls, guard triggers, and errors. Does not enforce BudgetGuard or intercept provider calls.

Inputs: trace_id (required).

get_trace_decisionsA
Read-onlyIdempotent

Read-only normalized decision.* events from one retained trace. Use this when a workflow includes proposal, override, approval, or binding steps. Does not approve, bind, or enforce those decisions.

Inputs: trace_id (required).

get_usageA
Read-onlyIdempotent

Read-only hosted event quota usage and plan limits from the AgentGuard Read API. This is dashboard event quota, not SDK BudgetGuard and not a provider invoice cap.

Inputs: no named parameters.

query_tracesA
Read-onlyIdempotent

Read-only search for retained AgentGuard trace summaries from the AgentGuard Read API. Requires AGENTGUARD_API_KEY with read access; create keys in the AgentGuard dashboard. Returns JSON with a traces array, newest traces first when the API supports ordering; items include trace_id, service, root_name, event_count, error_count, duration_ms, started_at, API key metadata, and total_cost when available. Defaults to a small page, accepts offset pagination, exact service filtering, and ISO 8601 since/until bounds. Use this to find candidate trace_id values; use get_trace for the full event tree of one trace or get_trace_decisions for decision.* events from a known trace.

Inputs: limit, since, until, offset, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool targets a distinct read-only aspect: trace search, full trace retrieval, decision events, alerts, usage, costs, and budget health check. The descriptions clearly separate them even where they overlap (e.g., usage vs. costs are explicitly differentiated).

    Naming Consistency4/5

    All tools follow a verb_noun pattern with mostly 'get_' prefixes; query_traces and check_budget deviate slightly but are still predictable. The naming is consistent enough that an agent would not be confused.

    Tool Count5/5

    Seven tools is well-scoped for a read-only monitoring API. Each tool has a clear, non-redundant purpose, covering search, detail, decisions, alerts, usage, costs, and budget—neither too few nor too many.

    Completeness5/5

    For a read-only trace and monitoring surface, the tool set is complete: it covers listing/searching traces, retrieving full traces, filtering decisions, and accessing alerts, usage, costs, and budget status. No obvious read operations are missing for the stated purpose.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      A remote Model Context Protocol server acting as middleware to the Sentry API, allowing AI assistants like Claude to access Sentry data and functionality through natural language interfaces.
      7
      46 npm
      961
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Enables querying Langfuse analytics, cost metrics, and usage data across multiple projects. Provides tools for trace analysis, model/service cost breakdowns, and daily usage trends through natural language queries.
      24
      104 npm
      MIT
    • F
      license
      A
      quality
      D
      maintenance
      Enables AI agents to query Prometheus metrics and Loki logs for intelligent alert investigation and troubleshooting. Provides service discovery, metric querying, log searching, and correlation tools to help identify root causes of issues.
      9
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      A local-first security gateway and visual dashboard for AI agents that enforces cost caps, blocks prompt injections, and requires approval for dangerous actions.
      3
      -