Skip to content

The guardrail

The guardrail checks every tool call an LLM agent makes before it runs, and answers allow, ask the person or refuse, naming the rule that decided. It works with any agent: give it the tools you give your model, and it checks each call the model proposes.

Nothing in it is guessed by a language model: the same call and the same rules always give the same answer.

Guaranteed:

  • Every tool call is checked before it runs, by the same rules, and the same call, context and rules always give the same answer.
  • A tool not on your list never runs; a call whose values break the tool's own description never runs.
  • A write no rule allowed never runs without a person's yes, and that yes covers exactly the call shown.
  • A value in a write that nobody said and no tool returned is asked about.
  • Nothing in a decision is guessed by a language model.

Not guaranteed:

  • It judges tools, arguments, labels, history and rules, not what a reply means.
  • It cannot tell a right value from a wrong one that someone did say.
  • Your rules are only as complete as you wrote them: the bug hunter looks for holes.
  • A tool whose name and description hide what it does may be classed wrongly: mark it.
  • Calls made outside the guardrail are not checked.

The steps below follow one support desk, with four tools: look up an order, refund a card, send an email and save a note. The numbers in each picture match the numbered steps under it, and every line in a picture was printed by the guardrail itself.

What each check does

Every rule of the guardrail, in the order it is applied; the first that applies decides.

Check What it does, simply When it stops a call Can be switched off
Tool kinds Each tool is known to read, change something or send something out: from your file, the tool's own marks, or its name, description and arguments. A tool nobody marked counts as one that changes something. asked (a tool not known to read is a write) yes
Tool withdrawn A tool its owner withdrew from the registry cannot be used. refused no
Address not allowed A call cannot reach an address you do not allow, such as the cloud's metadata service or the company's own network. refused yes
Not the approved plan Where a person approved a plan, a call that is not its next step does not run. refused yes
Plan's tool tier Not active yet: every call passes. never (not active yet) yes
Labels Not active yet: every call passes. Outside content is stopped by the outside content check. never (not active yet) yes
Payment limit Not active yet: every call passes. Spending limits are set in your rules. never (not active yet) yes
Allowed tools Only tools on your list can be used, and only by a named agent where you say so. refused no
Session record The record of the calls already made must be intact; if anyone altered it, nothing more runs. refused no
Arguments Each call's values must fit the tool's own description (types, required fields, allowed values). refused yes
Destinations A tool may send something to an address only if it is known to send things out. refused yes
Order A tool runs only at an allowed point: after another, never after another, or at most N times. refused yes
Undo An undo must match the step it reverses, and a step is undone only once. refused yes
Your rules Your own rule sheet decides, e.g. "refunds over 100 need a manager"; limits per period and spending limits too. refused or asked, as the rule says yes
Outside content A call proposed after reading outside content (a web page, an email) is stopped where you forbid it. refused, or asked where your setting asks yes
Confirmation A call needing a person's yes runs only with that yes, signed; if nobody can give it, it does not run. refused no
Any other write Anything that changes something and no rule allowed waits for a person's yes. asked no
Grounding A value in a write that nobody said and no tool returned is asked about, never allowed and never refused. asked yes
S1: sending verb Where the person's turn asks to send something out and no tool sends anything, the call is stopped. asked by default; refused in strict mode yes
S2: destination Where the turn names a place to send to that no tool takes, and the call does not take it either, the call is stopped. asked by default; refused in strict mode yes
Confirm read The call is read against the turn, its values as typed. Where the turn gives a value the call lacks, or a different one, the person is shown both and asked. The call is never changed. asked by default; refused in strict mode yes

1. Put the guardrail in front of your tools

The guardrail in three lines of Python, and in front of an MCP server

  1. In Python, three lines: the guardrail is made from the tools you give your model, and each call is checked before your code runs it. Install it with pip install stalwart-agents.
  2. In front of an MCP server, stalwart gateway checks every call on its way to the server. The snippet tool of stalwart mcp writes its configuration for you.

2. Write your rules

A rule sheet, compiled and checked against your tools

  1. Your rules are a rule sheet: plain YAML a person can read aloud. Here, a refund over 100 needs a manager's approval, and every email waits for a person's yes.
  2. The sheet is compiled once; the decisions are then made on your own machine.
  3. The sheet is checked against your tools: here, save_note changes something and no rule names it, so you are told, and can decide.

3. A call is allowed, asked about, or refused

One call allowed, one asked about, one refused

  1. Looking up an order only reads, so it is allowed.
  2. A refund of 20 changes something and no rule allows it outright, so it waits for a person's yes.
  3. A refund of 150 breaks the rule of step 2, so it is refused, and the answer names the rule and gives an id to look it up by.

4. An amount nobody said is asked about

A refund whose amount the person never said

  1. The person asked for a refund but never said how much. The model proposed 35 anyway.
  2. No one said 35 and no tool returned it, so the guardrail asks the person before anything runs. It never fills a value in, and never changes the call.

5. Add it to your Guardrails AI guard

The guardrail as a validator in a Guardrails AI guard

  1. Install stalwart-agents[guardrails] and add our validator to your guard. A refused call arrives as Guardrails AI's own failure, with the rule's sentence.
  2. With on_fail=gai.ask, a call that needs a person is held back, and gai.asked(guard) gives you the sentence to show them. On their yes, validate the same call again with the token gai.approve gives.

6. Ask the MCP server what it can do

Your AI assistant asking the guardrail's MCP server

  1. Add stalwart mcp to your AI assistant (Claude Code, Cursor, VS Code) and ask what the guardrail can check: it answers from the guardrail's own list.
  2. Ask how to add it to your Guardrails AI guard, and you get the steps. The build-guardrail prompt walks your assistant through building one with you; it never calls a model of ours.

7. Measure it on your own calls

Your agent's past calls replayed and scored

  1. replay runs your agent's past calls through the guardrail: how many it would have allowed, asked about and refused, by which rule, and whether a second run gave the same answers.
  2. Label each call with what should have happened, and evaluate counts the false alarms (calls that should run, stopped) and the misses (calls that should be stopped, let through).

8. Check your rules for holes

The bug hunter's findings on the rule sheet

  1. hunt runs the bug hunter on your rule sheet. Each finding is something your rules let through, with what to look at; here, it asks you to say what refund_card must never run without, since no table of yours says so.

9. Why was this call refused?

One refusal explained

  1. explain_decision reads back a decision by its id: the rule, what it read, the tool and the names of its arguments. The values themselves, and anything the person said, are never kept.

Going further

The full manual, in English and Portuguese, is in the SDK documentation: building a guardrail, the checks, the rule sheet, evaluating it and connecting it. stalwart mcp serves the same pages to your assistant.