tool_guards — Tool Guards
Pre-flight validation and transformation rules that sit in front of every tool call — built-in, custom code, wrapped, MCP, Composio connector, OpenAPI, and skill tools all pass through the same guard layer before their code runs. Validation rules reject a bad call with a structured fix-it message the model can act on; transform rules silently fix the arguments and let the call proceed.
Section key tool_guards · Shape object · Tier All plansEdit in the dashboard: Tools page — the Parameter guards section of the wrap editor, or the Tool Guards dialog for any tool by its runtime name
Per-tool guards, keyed by exact tool name.Guards are keyed by the tool’s runtime name: a built-in by its plain name (
web_search), one of your custom tools as tool_<name>, and an MCP/connector tool by its namespaced name. A tool with no guard entry passes through untouched.
Fields
Per-tool guard fields
Per-parameter rule fields
Each rule combines any of three kinds of field. Validation rules reject the call when violated; transform rules never reject — they change the value and let the call continue. Validation (reject) rules:
Transform (silently fix) rules:
Messaging and advertising:
Evaluation order
For each guarded call:block— if set, the call is refused immediately withblockMessage; no parameter rules run.- Per parameter, rules apply in a fixed order:
forbidden→default(fill if missing) →hardSet(always override) → string transforms (trim,lowercase,uppercase) →required→ and then, only when a value is present:type, numericmin/max(orclamp),minLength/maxLength,pattern,enum,custom. - Violations are collected across all parameters and reported together in one message, so the model can fix everything in a single retry.
- If nothing violated, the tool runs with the transformed arguments. The model’s original message is never mutated — transforms apply to a copy.
What the model sees on a violation
A rejected call never reaches the tool — the guard’s message is surfaced to the model as an error tool result, so it can self-correct in the next step. The message is structured plain English:message override if set). Blocked tools produce a “Tool call to … was refused before running.” message naming the tool, plus the block message. Guard refusals also fire your post_tool_call hooks with the error summary, and are recorded as refused tool calls in the conversation’s interaction trace.
Layering and precedence
Three guard layers merge per turn, weakest first: subscriber → owner → platform. A stronger layer’s field wins on the same parameter;block is OR-ed across layers, so a weaker layer can block a tool but never un-block one. Guards a subscriber adds on their own Tools page are forced reject-only — the value-mutating fields (default, hardSet, clamp, trim, lowercase, uppercase) are stripped, so a subscriber can tighten your rules but can never transform an argument past them.
Examples
Validate an email recipient — reject anysend_email call without a well-formed address, and tell the model up front:
limit sane without ever failing the call: