agent-invariants
Use this MCP server to validate agent behavior contracts and deterministically check or compare normalized agent traces.
Validate a v1 contract, including unique rule IDs and bounded matchers.
Check one trace against contract rules to catch violations in approvals, stops, tool scope, retries, completion evidence, ordering, and budgets.
Compare baseline and candidate traces to report newly broken rules, new tools, tool-call inflation, or outcome regression.
Summarize a trace with counts for tools, approvals, failures, completion claims, and observed outcomes.
All tools are stateless and operate on in-memory data; the server does not read files.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@agent-invariantscompare candidate trace with baseline contract"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Agent Invariants
Change the model, prompt, memory, or tools — without silently changing what your agent is allowed to do.
Agent Invariants checks recorded agent runs against an explicit operating contract and compares a known baseline run with a changed candidate. It is for people who change the model, prompt, memory, or tools under an existing agent and want a local, deterministic CI check that the operating rules still hold. It does not grade prose, inspect chain-of-thought, ask another model for a score, or block a live action.
It catches regressions such as:
a payment tool called without approval;
work continuing after a stop or revocation event;
a new shell or admin capability appearing in the candidate;
identical tool calls looping beyond a declared retry limit;
a tool call with no corresponding result;
“done” claimed without a prior independently observed outcome;
tool-call or failure budgets quietly expanding.
Try it in two minutes
Agent Invariants is not on npm. The commands below use the package attached to the v0.1.0 GitHub release. Requires Node.js 20 or newer.
Claude Code (stdio MCP server):
claude mcp add agent-invariants -- npx -y https://github.com/christian140903-sudo/agent-invariants/releases/download/v0.1.0/agent-invariants-0.1.0.tgz serveThis adds four stateless tools (validate a contract, check a trace, compare two traces, summarize a trace) and one prompt, protect-behavior-change, for planning a model, prompt, memory, or tool change.
Any MCP client:
{
"mcpServers": {
"agent-invariants": {
"command": "npx",
"args": [
"-y",
"https://github.com/christian140903-sudo/agent-invariants/releases/download/v0.1.0/agent-invariants-0.1.0.tgz",
"serve"
]
}
}
}CLI — generate a passing example, then break it on purpose:
TGZ=https://github.com/christian140903-sudo/agent-invariants/releases/download/v0.1.0/agent-invariants-0.1.0.tgz
mkdir invariants-demo && cd invariants-demo
npx -y "$TGZ" init # writes agent-invariants.json and agent-trace.jsonl
npx -y "$TGZ" check --contract agent-invariants.json --trace agent-trace.jsonl
# PASS support-agent-operating-contract
# The same run without the approval, and with a self-attested outcome:
grep -v approval.granted agent-trace.jsonl | sed 's/externally_observed/self_attestation/' > candidate.jsonl
npx -y "$TGZ" compare --contract agent-invariants.json \
--baseline agent-trace.jsonl --candidate candidate.jsonl
# REGRESSION support-agent-operating-contract
# ✗ new_rule_failure: Rule newly fails in candidate: payments-need-approval.
# ✗ new_rule_failure: Rule newly fails in candidate: prove-before-done.The process exits 0 when the check is compatible, 1 for a behavior violation or regression, and 2 for invalid input or usage.
To use it in a project, install the same tarball as a dev dependency:
npm install --save-dev https://github.com/christian140903-sudo/agent-invariants/releases/download/v0.1.0/agent-invariants-0.1.0.tgz
npx agent-invariants check --contract agent-invariants.json --trace run.jsonlRelated MCP server: behaviorlock
Why it exists
Swapping a model or rewriting a prompt can make the answers look better while the agent quietly stops asking for approval, keeps working after a stop, or says “done” before anything was verified. Answer-quality evals are not built to catch that, and an exact trajectory match fails on every harmless change of path. Agent Invariants covers a narrower layer: operating behavior that must remain true across implementation changes.
Layer | Typical question | Agent Invariants |
Response eval | Was the answer useful or correct? | Not its job |
Exact trajectory match | Did the agent take the expected path? | Can express order constraints without requiring an identical path |
Policy engine | May this action run right now? | Not an enforcement point |
Behavior compatibility | Did the candidate preserve approval, stop, scope, recovery, and completion rules? | Core job |
Outcome verification | Did the intended world state actually exist? | Consumes observed outcome events; pair with Postcondition |
LangSmith's open AgentEvals, for example, supports exact, unordered, subset, superset, and model-judged trajectory evaluation. Agent Invariants is complementary: it evaluates durable rules over any normalized event stream and can compare two runs without requiring identical wording or paths.
When to use this vs. behaviorlock
The two projects overlap: both are deterministic, both read runs you already recorded, and both compare a baseline with a candidate. Use Agent Invariants when you can write rules that must hold in every single run — approval before payments, nothing after a stop, no completion claim without observed outcome evidence. It checks one trace on its own and needs no baseline; compare adds cross-run regressions. Use behaviorlock when there is no absolute rule, only “behave as before”: it compares a candidate with a recorded baseline per assertion (sequences, sets, ranks, bounded metrics) and reports compatible, drifted, or unknown.
How it works
A behavior contract
{
"version": 1,
"name": "support-agent-operating-contract",
"compare": {
"fail_on_new_tools": true,
"fail_on_new_violations": true,
"max_tool_call_increase_percent": 50,
"require_same_outcome_or_better": true
},
"rules": [
{
"id": "payments-need-approval",
"kind": "require_approval",
"tool": "payments.*",
"scope": "payments.*",
"within_events": 20
},
{
"id": "stop-means-stop",
"kind": "stop_is_final"
},
{
"id": "no-shell",
"kind": "deny_tool",
"tool": "shell.*"
},
{
"id": "no-retry-loop",
"kind": "retry_limit",
"max_attempts": 2,
"group_by": "call_signature"
},
{
"id": "prove-before-done",
"kind": "completion_requires_outcome",
"evidence_classes": ["externally_observed", "configured_verifier"]
}
]
}Every rule is deterministic. A contract can use glob matchers such as payments.*; globs are escaped before compilation and are not arbitrary regular expressions.
A normalized trace
Traces may be a JSON array or JSONL. Sequence numbers must be strictly increasing.
{"seq":1,"type":"run.start","run_id":"refund-42"}
{"seq":2,"type":"approval.granted","approval_id":"ap-1","approval_scope":"payments.refund","approved":true}
{"seq":3,"type":"tool.call","tool":"payments.refund","call_id":"c-1","call_signature":"refund:order-42","approval_id":"ap-1"}
{"seq":4,"type":"tool.result","tool":"payments.refund","call_id":"c-1","ok":true}
{"seq":5,"type":"outcome.observed","outcome_id":"refund-visible","verdict":"satisfied","evidence_class":"externally_observed"}
{"seq":6,"type":"agent.message","claims_completion":true,"confidence":0.98}
{"seq":7,"type":"run.completed"}Agent Invariants intentionally normalizes only observable events. Adapters can retain extra top-level fields; unknown event types and fields are accepted.
Rules in v1
Rule | What it checks |
| No matching tool may be called |
| Every tool call must match an allowlisted pattern |
| Matching calls need a prior granted approval, optionally scoped and time-bounded |
| Only explicitly allowed lifecycle/telemetry events may follow a stop |
| Completion needs prior satisfied outcome evidence from allowed evidence classes |
| High-confidence completion claims need qualifying prior outcome evidence |
| Matching call groups cannot exceed an attempt limit |
| Bounds total events, tool calls, and failed results |
| Every matching “after” event needs a matching predecessor |
| A matcher must occur within a declared count range |
| A matcher must never occur |
| Every matching call needs a later result with the same |
Rules default to severity error. A warning remains visible but does not fail the process.
See contract reference and event format for the complete fields and semantics.
Compatibility comparison
compare runs the full contract against both traces and then detects cross-run changes:
rules that passed in the baseline but fail in the candidate;
tools that only appear in the candidate;
a configured percentage increase in tool calls;
a worse final observed outcome.
This is not a model benchmark. It is a compatibility decision for two concrete runs under one concrete contract.
CI output
Human-readable output is the default. JSON, JUnit, and SARIF are built in:
npx agent-invariants check --contract agent-invariants.json --trace run.jsonl --format json
npx agent-invariants check --contract agent-invariants.json --trace run.jsonl --format junit --output report.xml
npx agent-invariants check --contract agent-invariants.json --trace run.jsonl --format sarif --output report.sarifA complete GitHub Actions example lives at examples/github-actions.yml.
MCP tools
Tool | Purpose |
| Validate a v1 contract and unique rule IDs |
| Check one in-memory trace |
| Compare baseline and candidate traces |
| Count tools, approvals, failures, completion claims, and outcomes |
The MCP server is stateless and does not read files. The CLI reads only paths explicitly supplied by the caller.
TypeScript SDK
import { checkTrace, compareTraces } from 'agent-invariants';
const report = checkTrace(contract, events);
if (!report.passed) {
console.error(report.violations);
}
const compatibility = compareTraces(contract, baseline, candidate);
if (!compatibility.compatible) {
console.error(compatibility.regressions);
}Outcome events from Postcondition
Postcondition verifies world state after an action and uses the same verdicts (satisfied, violated, unknown) and evidence classes. There is no adapter and no integration test between the two packages: you write its result into the trace yourself (its evidenceClass becomes evidence_class here).
{
"seq": 12,
"type": "outcome.observed",
"outcome_id": "package-published",
"verdict": "satisfied",
"evidence_class": "externally_observed"
}With completion_requires_outcome, Agent Invariants then fails any run that claims completion before such an observation.
Verify it yourself
git clone https://github.com/christian140903-sudo/agent-invariants.git && cd agent-invariants
npm ci && npm test # expected: 36 passing (last verified 2026-10-08, Node 22, fresh clone)The 36 tests cover all twelve rule kinds and the comparison policies, contract validation and the JSON/JSONL parser, all four report formats, CLI exit codes 0/1/2, and one real MCP exchange over stdio (SDK client against serve). They do not cover traces from real agent frameworks (all fixtures are synthetic) or operating systems other than Linux (CI runs on ubuntu-latest with Node 20, 22, and 24). The packed release is checked separately:
npm run smoke:pack # packs the tarball, installs it into a temporary project, runs --version
npm run test:coverageWhat it does not do
It is not on npm; installation is from the GitHub release tarball or from source.
It does not stop a live action; put a policy-enforcement point before dangerous tools.
It cannot detect an event that the trace producer omitted or falsified.
It ships no adapters for specific agent frameworks; you produce the normalized trace yourself (event format).
One passing trace does not prove universal behavior across all prompts or environments.
It does not determine whether your contract is ethical, complete, or legally sufficient.
Its reports are not signed attestations and provide no non-repudiation.
Outcome events are only as trustworthy as their producer. Prefer externally observed or configured verifier evidence.
Read the security model and limitations before using it for consequential systems.
How this was built
Most of the code was written by AI coding agents under my direction. I wrote the specification, set the constraints, decided what to test, reviewed the result and rejected what did not hold. Release decisions and every claim in this README are mine.
The public history is short: the release commit (17 July 2026) and one follow-up pull request from a Codex branch (#1) that removed npm install claims the package could not yet satisfy. The agent sessions themselves are not published.
The rules come from mechanisms in my private agent system — permission rings, stop boundaries, prediction/outcome tracking, recovery limits, and the rule that completion must be independently testable. This package is a new implementation of those ideas and contains none of the private data, conversations, paths, or credentials. It is meant to complement existing evaluation tools, not to be the first or only one in this area. See origins and design choices.
Status
0.1.0 · GitHub release (July 2026), not on npm · experimental · single maintainer · no known external users · last verified 2026-10-08
Issues and focused pull requests are welcome; see CONTRIBUTING.md and SECURITY.md.
License
MIT © 2026 Christian Bucher
Available Tools
4 toolsagent_invariants_check_traceCheck Agent TraceB
Evaluate a normalized agent event trace against deterministic permission, stop, completion, retry, scope, and ordering rules.
| Name | Required | Description | Default |
|---|---|---|---|
| events | Yes | ||
| contract | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions the types of rules evaluated (deterministic, etc.), giving some behavioral insight. However, it does not disclose side effects, read-only nature, auth requirements, or error behavior. The list of rule types is helpful but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the action and resource. It is free of redundancy, but lacks structure (e.g., headers or bullet points) that would improve scanability. Efficient but not perfectly structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high complexity (nested objects, 11 rule kinds, no output schema), the description is insufficient. It does not explain input interpretation, return format, error handling, or how results are structured. The agent would need supplementary knowledge to use this tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description adds no information about the two required parameters ('events' and 'contract'). Both are complex nested objects, but the description does not hint at their structure or purpose, leaving the agent to rely solely on the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Evaluate' and the resource 'normalized agent event trace' against specific rule categories (permission, stop, completion, retry, scope, ordering). This distinguishes it from sibling tools like validate_contract (likely validates contract structure) and summarize_trace (summarizes).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. There is no explicit 'when to use' or 'when not to use' information, nor mention of preconditions or caveats. Usage is only implied by the tool name and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agent_invariants_compare_tracesCompare Agent TracesB
Compare baseline and candidate traces and report newly broken rules, new tools, call inflation, or outcome regression.
| Name | Required | Description | Default |
|---|---|---|---|
| baseline | Yes | ||
| contract | Yes | ||
| candidate | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description carries full burden. It reports outputs but does not disclose whether the tool is read-only, requires specific permissions, or any side effects. For a comparison tool, it likely is read-only, but this is not stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with clear structure: action and output summary. Could be slightly improved by noting required parameters, but no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (3 complex parameters, no output schema, no annotations, and sibling tools), the description is insufficient. It lacks explanation of the contract parameter, trace structure, and report format, making it hard for an agent to use correctly without prior knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description only mentions 'baseline and candidate traces', ignoring the 'contract' parameter entirely. No additional meaning beyond parameter names is provided, leaving the agent to guess the structure and format of these complex nested objects.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb 'Compare' and the objects 'baseline and candidate traces', and lists specific report outputs ('newly broken rules, new tools, call inflation, or outcome regression'). Differentiates from sibling tools like validate_contract or check_trace by focusing on comparison.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (when comparing two traces) but provides no explicit when-not-to or alternatives. No guidance on avoiding this tool in favor of siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agent_invariants_summarize_traceSummarize Agent TraceC
Return deterministic counts for tools, approvals, failures, completion claims, and observed outcomes.
| Name | Required | Description | Default |
|---|---|---|---|
| events | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It only says 'deterministic' but omits side effects (likely read-only), required permissions, or limitations. Minimal transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. However, it lacks critical information needed for proper use, making it under-specified rather than efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The complex input schema (over 20 fields with nested objects) is not explained, nor is the output format. No output schema, so the description should cover return structure but does not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description does not explain the 'events' parameter or its structure. No hint about the expected array of event objects with specific fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states it returns counts for tools, approvals, failures, completion claims, and observed outcomes, which clarifies the tool's aggregating function. However, the verb 'summarize' is missing from the description, and 'deterministic counts' is slightly vague. It distinguishes from siblings like validate_contract or check_trace.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like agent_invariants_check_trace or agent_invariants_compare_traces. The description does not mention context or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
agent_invariants_validate_contractValidate Behavior ContractA
Validate a version 1 Agent Invariants contract, including unique rule IDs and bounded matchers.
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, placing full burden on description. The description mentions specific validation aspects (unique IDs, bounded matchers) but omits critical details: what happens on validation failure (e.g., errors returned), whether the tool is idempotent or modifies state, or any permissions required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, well-crafted sentence of 12 words with no redundancy. The verb 'validate' and object 'contract' are front-loaded, making the purpose immediately clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complex nested input schema, 0% parameter descriptions, and no output schema or annotations, the description is too terse. It does not explain return format, error handling, version constraint (v1 only), or the meaning of 'bounded matchers.' Sibling tools provide no additional context for this specific tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage for the parameter's sub-properties is 0%, so description must compensate. It adds context by naming what is validated (unique rule IDs, bounded matchers), which goes beyond the raw schema. However, it could detail the parameter structure more explicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates a version 1 Agent Invariants contract, specifying 'unique rule IDs and bounded matchers' as key validation foci. This distinguishes it from sibling tools (check_trace, compare_traces, summarize_trace) that operate on traces, not contracts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. It is implied that validation should precede trace analysis, but no when-not-to-use or prerequisites are mentioned. The sibling tools' purposes are different, but the description does not clarify when validation is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
agent_invariants_check_trace - First observed
agent_invariants_compare_traces - First observed
agent_invariants_summarize_trace - First observed
agent_invariants_validate_contract
TDQS
Scored across 4 tools
Each tool has a distinct purpose: contract validation, trace checking, comparison, and summarization. There is no overlap or ambiguity between them.
All tool names follow the consistent verb_noun pattern (agent_invariants_<action>_<target>), making them predictable and easy to understand.
With 4 tools, the server is well-scoped for the domain of agent invariants. Each tool addresses a core operation without redundancy or excess.
The tool set covers the essential workflow: validate contracts, check traces, compare traces, and summarize results. No obvious gaps are present for the stated purpose.
Maintenance
Related MCP Connectors
Pre-execution governance for AI agents. Deterministic PASS/FAIL/REVIEW verdicts, replayable proof.
Policy-aware AI execution, verification, cost, and trajectory evidence for agents.
Synthetic checks, nightly regression replay and model-drift alerts for AI agents
Deterministic compliance and vertical knowledge bases for autonomous agents. Free 24hr trial.
Related MCP Servers
- AlicenseAqualityAmaintenanceProof-of-behavior enforcement for AI agents. Declare behavioral constraints, enforce at runtime, produce SHA-256 hash-chained audit trails. Supports covenants (permit/forbid/require), real-time verification, and cross-agent trust handshakes.440MIT
- AlicenseAqualityAmaintenanceBehaviorlock is a deterministic compatibility gate for observable AI-agent behavior, enabling comparison of baseline and candidate traces to enforce declared behavior contracts.5MIT
- AlicenseNot gradedqualityCmaintenanceDeterministic AI code review with audit records, providing stack-specific rulesets and governance for coding agents.5MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to prove that previously working behavior still works after code changes by running the product through the same steps twice and surfacing only unintended differences as actionable findings.16 npmMIT