Reliability and governance for agent tool calls

Your agent's tool calls are failing right now.
You just can't see it.

A tool returns a JSON string instead of an object. An MCP server answers isError: true and your code treats it as success. A sub-agent calls a refund tool with its parent's permissions. Three turns later the run goes wrong, and there is nothing to look at.

agentguard sits between an agent and its tools as a single wrap() call. It validates, repairs, retries, records, replays, and enforces which agent may call what.

Python
import agentguard

search = agentguard.wrap(search_orders, result_schema=ORDERS)
orders = search(query="late delivery")
TypeScript
import { wrap } from "@agentguard/sdk";

const search = wrap(searchOrders, { resultSchema: ORDERS });
const orders = await search({ query: "late delivery" });

That is the entire integration. Python 3.10+ or any ESM runtime. First-class adapters for the Vercel AI SDK, MCP and AutoGen. No dependencies, no build step, no agent framework to adopt.

Four failures that look identical from the outside

Malformed output

The tool promised an object and returned '{"orders": [...]}' as a string, or "1041" where an integer belongs. The model gets it anyway and improvises.

Failure that looks like success

MCP reports errors as a normal result with isError: true. Unless you check every call, a failed tool is indistinguishable from a working one.

Nothing to reproduce

The bad run is over. The output that broke it was never written down, so the fix is a guess and the test is production.

Delegated permissions

A sub-agent spawned for a subtask inherits the parent's full reach. Nothing stops it from calling the tool that moves money.

What it does

Validates

Arguments and results are checked against a JSON-Schema subset, with errors addressed by path: hits[0].id: expected integer, got string.

Repairs

Models produce a small set of malformed shapes: JSON as a string, {"data": {…}} envelopes, numeric strings, a bare object where a list belongs. Those get fixed in flight, with no extra tool call.

Retries with instructions

What repair cannot fix is re-called with the schema errors handed back as structured feedback, so the second attempt knows what was wrong with the first.

Records everything

Every attempt, including the raw output that failed, on a background thread that never blocks a call and never fails one. An observability layer that can take you down is worse than none.

Replays deterministically

Re-run a failed call against the output it really returned: no network, no side effects, same answer every time. Paste a candidate schema and see whether your fix would have caught it.

Records who looked

Opening a trace, running a replay, signing in or failing to sign in: all written to an append-only audit log with actor, target and address. Kept for a year. The traces themselves are kept a fortnight.

Enforces capability

Per-tool rules in YAML. A delegated sub-agent's grants are intersected with its parent's, so handing off work can never widen what that work may touch.

The incident, in four clicks

Nobody buys observability. They buy the afternoon back after an agent told a customer their refund went through and it didn't. Here is that afternoon, in the live demo.

  1. Which tool is failing. Top offenders, ranked worst-first, with the actual error text, not a chart you have to interpret.
  2. What the tool really returned. Open any failed call and read the raw output of every attempt.
  3. Whether your fix works. Paste a candidate schema into replay and watch the failure stop reproducing, against real traffic, before you ship.
  4. What the policy stopped. The sub-agent that tried to delete an order, blocked before the tool ran.
Open the demo

No signup. It is the product's own dashboard running on a captured day of agent traffic.

It runs in your infrastructure

Traces contain your tool arguments and results: order numbers, amounts, customer identifiers. That data never leaves your network, because there is nowhere for it to go. The collector makes no outbound calls.

Two credential types that never overlap

Agents get write-only ingest tokens. People get session logins. An ingest token will leak eventually, because it lives in every deploy config, and when it does it still cannot read a single trace back.

Credentials useless if the database leaks

scrypt password hashing with per-user salts, tokens stored only as SHA-256 digests and shown once, constant-time comparison everywhere.

Secrets stripped before recording

Values under keys like password, api_key and authorization are redacted inside your process, before a trace is even queued.

Hardened by default

Binds to localhost, strict CSP, CSRF on every write, login throttling, an audit log of every read, non-root container on a read-only filesystem, retention you control.

Full detail in SECURITY.md, shipped with the product, including what it deliberately does not do.

Pricing

Self-hosted at every tier, priced per production environment. You can leave whenever you like.

Starter

€49/mo

one environment

  • The whole product, nothing withheld
  • Both SDKs, collector, dashboard
  • Policy engine, replay, audit log
  • Email support from the people who wrote it
Request access

Enterprise

Custom

on-prem, licensed

  • Air-gapped deployment
  • Capability governance review
  • Audit support and SLAs
  • Source escrow on request
Talk to us

Every plan starts with a 30-day evaluation at no charge, on your own infrastructure and your own traffic. Starter is priced the way it is on purpose: small enough to put on a card without a procurement process, large enough that both sides treat it as a real relationship. Design partners, which means the first teams to run this in production, keep it free while we build together and get a permanent discount afterwards. Say so in the form.

Request access

Access is granted by hand, one team at a time. We would rather have ten deployments we understand than a thousand downloads we don't. Tell us what your agents do and we will get back to you.

We use this to answer you and for nothing else. No newsletter, no tracking, no third parties. You can also write straight to par@prodx.se.