Skip to main content
Glama

declare_run_expectations

Idempotent

Commit a run's pass/fail criteria upfront so it cannot grade itself. Declared assertions override the success ping, marking non-compliant runs as failed.

Instructions

Requires an API key with the write scope or higher. Commit, at the START of a run, to the criteria by which THAT RUN will be judged when it closes — before you can see how it turns out. This is how a run stops grading itself: once declared, a success ping whose body does not satisfy every declared criterion is recorded as a FAILED run with cause 'assertion', regardless of the exit code or what the ping claims. Call this right after your run's /start ping, before doing any work — see the assertions argument for the full, immutable contract, and get_ping_instructions' expectations_how_to for a worked example.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ridYesThe run id exactly as sent on this run's /start ping — the same rid used on every step and the terminal ping.
check_idYesMonitor UUID (from create_monitor or list_monitors).
assertionsYesThe run's complete set of expectations, declared ONCE at the start of the run -- criteria the ping BODY of THIS run's eventual success ping must satisfy when the run closes, checked instead of letting the run grade itself. IMMUTABLE: a second call for the same rid is rejected with a conflict error and the first declaration stands unchanged -- there is no way to edit, add to, or replace it once made, so decide the whole set before you start work. Declaring nothing is allowed and always has been: simply never call this tool for a run, and the monitor's own check-level assertions (if any) stay in force unchanged. INCLUDE AT LEAST ONE POSITIVE CRITERION -- a 'contains', 'matches' or 'json_path' entry -- in every declaration. A declaration made ENTIRELY of 'not_contains' entries is self-satisfying on empty output: a run that produces nothing at all still passes, because there is nothing for the pattern to find. That is precisely the evasion this feature exists to close, so a purely negative declaration defeats its own purpose. A 'matches' entry only counts as positive if its pattern REJECTS an empty body: '.*', '(?s).*' and '^$' all accept one and are validated as perfectly legal patterns, so a declaration resting on one of those is no better than a purely negative declaration. Supply a JSON ARRAY as a string, e.g. '[{"kind":"json_path","path":"result.rows_processed","op":"gt","value":"0"}]'. Fields per entry: kind (required), value, path, op -- no name; a run's declared criteria have none, unlike a monitor's own output assertions. kind is one of 'contains' (body contains value as a substring), 'not_contains' (body does not contain it), 'matches' (body matches value as a Go RE2 regexp, max 1000 bytes), or 'json_path' (parse the body as JSON, read the value at path, compare it against value with op). contains/not_contains/matches require value; json_path requires path and op. path is a DOTTED path only ('a.b.c') -- the query syntax of a real JSONPath library ('[', '*', '$') is rejected. op is one of 'eq', 'ne', 'gt', 'gte', 'lt', 'lte'. At most 20 assertions per run. A malformed entry (uncompilable regexp, a path carrying query syntax, an unknown kind or op) is rejected before anything is written, and nothing is stored if any entry fails.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description extensively discloses behavior beyond annotations. It explains that a second call is rejected (idempotent), that declarations are immutable, that grading outcomes change (success ping failing all declared criteria leads to FAILED run), and that conflicting declarations are rejected. It also clarifies the safety profile (requires write scope). This richness goes well beyond the readOnlyHint/idempotentHint/destructiveHint annotations, adding substantial context without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but every section earns its place given the tool's complexity. The core purpose is front-loaded in the first sentence, and the parameter details are organized. The main description is concise while the assertions parameter documentation is appropriately exhaustive. It is not overly verbose; the length is proportional to the complexity of the contract it defines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema and the tool carries significant side effects, the description covers all essentials: authentication, timing, immutability, allowed values, constraints, errors (including rejection of malformed entries), and references to a worked example. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

While the schema provides 100% coverage, the description enriches each parameter significantly. For rid, it re-emphasizes it must match the /start ping. For check_id, it points to sources. For assertions, it provides a full specification: JSON array format, allowed kinds, required fields per kind, limits (max 20), examples, and pitfalls (purely negative declarations are self-satisfying, regexp caveats). This is far beyond the schema's one-line descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Commit ... to the criteria by which THAT RUN will be judged' for a specific run. It clearly explains the tool's function and contrasts with the alternative of not calling it at all ('Declaring nothing is allowed...'). It distinguishes itself from siblings by being the only tool that declares run expectations, and it references get_ping_instructions for a worked example.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly provides timing instructions: 'Call this right after your run's /start ping, before doing any work'. It also states when not to call: 'simply never call this tool for a run' when you want monitor-level assertions to stay in force. It even references an alternative tool (get_ping_instructions) for a worked example, giving clear contextual guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.