The MCP server: stalwart mcp
stalwart mcp is the guardrail's MCP server. It runs on your machine, over stdio, and answers your AI assistant's
questions about the guardrail, builds one with you, and measures it on your own calls. It reads and writes files in
the folder it was started in (STALWART_MCP_HOME moves it). It calls the service only where a step already does
(compiling a rule sheet, a hosted hunt, a red team), and it never calls a model: where a step needs one, your own
assistant does it, through a prompt, and the server checks what it made.
Adding it to your client
$ stalwart mcp --config claude # prints: claude mcp add stalwart -- <python> -m stalwart_agents.guardrails.server
$ stalwart mcp --config cursor # the mcpServers entry for Cursor
$ stalwart mcp --config vscode # the servers entry for VS Code
Asking what it can do
| Tool | Answers |
|---|---|
capabilities(language) |
every check, from the guardrail's own list: what it catches and cannot, its inputs and on-fail options; where it can run; versions; what is guaranteed and what is not |
explain_check(name, language) |
one check in full, with an allowed and a stopped example and its manual section |
search_manual(question, language) |
the manual's sections that best match, by their words, in English or Portuguese; no model |
how_to(goal, language) |
fixed recipes: "guard my MCP server", "add it to my Guardrails AI guard", "write a rule for refunds over 100", "evaluate on my traces", ... |
explain_decision(decision_id) |
why a recorded call was stopped: the check, its rule and what it read |
The manual's pages are resources: stalwart://manual/{page} (add /pt for Portuguese), one of building, checks,
tool-kinds, rule-sheet, wording-search, evaluating, connecting, mcp.
Setting it up
| Tool | Does |
|---|---|
catalogue_from_server(server, out) |
reads an MCP server's tools (its address, or a saved tools/list reply) into tools.json |
writes_file(tools, out) |
drafts tool_kinds.yaml: each tool's kind, reason and source, unsure tools first |
set_tool_kinds(changes, reasons) |
sets kinds as your assistant proposes them, recorded as source: assistant |
compile_rules(sheet, out_dir) |
compiles rules.yaml with the service into compiled/ |
lint_rules(sheet, tools) |
a rule for a tool you do not have; a write no rule names |
check_call(call, context) |
one dry-run answer; nothing runs |
search_wordings(tools, language, checks, seconds) |
the wording search of the three checks that read the turn |
snippet(where, upstream) |
the code for python, guardrails-ai or nemo, or gateway's catalogue.json and gateway.yaml |
Measuring it
| Tool | Does |
|---|---|
replay(trace, format) |
every call's answer; counts by rule; the calls stopped; confirmations per 100 calls; p50/p95 time; determinism |
evaluate(labelled, format) |
false alarms and misses against your labels, per rule |
counterfactual(trace, outcome_checker) |
your own outcome check, as run and with the stopped calls removed |
hunt(sheet) |
the bug hunter on your rules (the service, with your key) |
redteam(server) |
an MCP server's tools behind the gateway, proved for any call (the service, with your key) |
compare_with_gai(trace, guard) |
your Guardrails AI guard alone, and with our validator |
benchmark(name) |
fetches the tau2-bench airline or retail data from its pinned upstream commits |
Prompts
build-guardrail: the whole build, in order: tools, kinds, a rule sheet drafted from your policy in plain words, compile and lint, dry runs, search and hunt, the snippet. Your assistant drafts the sheet; you read it before it is used.classify-tools: your assistant proposes kinds for the tools the inference is unsure of.set-up-guardrail: a recipe fromhow_to, followed step by step.evaluate-guardrail:replayandevaluateon your calls, with nothing quoted from them.
A worked session
You: What can this guardrail check?
(the assistant calls
capabilities) Twenty-one checks, in four stages: tool kinds; the admission chain (a withdrawn tool, an address not allowed, a step outside an approved plan); the ten rules of the tool check (allowed tools, the session record, arguments, destinations, order, undo, your rules, outside content, confirmation, any other write); and the checks of what was said (grounding, S1, S2, the confirm read). It judges tools, arguments, labels, history and rules, not what a reply means.You: How do I add it to my Guardrails AI guard?
(the assistant calls
how_to) Installstalwart-agents[guardrails], addgai.ToolCall(...)to your guard, and validate each tool call withguard.validate(gai.as_json(call), metadata={"stalwart": {...}})before running it.
What a report holds
Tool names, rule names, counts, decision ids and digests. Never an argument value, and never a word a person said; every text passes the package's masking of secrets and personal data.