results.json shape an agent reads, and the check
YAML an agent writes.
Agent and MCP surface
Install the optional MCP dependencies before starting the server:graphcheck.yml. The server deliberately exposes
exactly three tools:
A reliable agent loop is:
- Call
list_checksand select an existing suite ID; do not guess it. - Call
run_suitewith that ID and, when needed, a configured profile name. - Interpret the returned
run.exit_codeand every selected check result as described below. - Use the returned
run.idwithget_resultswhen the persisted artifact is needed later. Uselatestonly when another run cannot race with the lookup.
checks path configured in graphcheck.yml (default: checks/) through its
normal repository/file tools.
run_suite returns the same result model as results.json, even when checks fail. An MCP tool-call
error is different: the request itself could not produce or publish a usable result. Do not treat a
tool-call error as a clean run and do not synthesize a pass.
The equivalent CLI flow is graphcheck run --suite <suite-id> followed by reading
.graphcheck/runs/<run-id>/results.json. The convenience copy at
.graphcheck/runs/latest/results.json has the same race caveat as get_results("latest").
Consuming results.json
results.json is the decision-making contract. The HTML report is a rendering of it, not another
source of truth. Its top-level shape is:
schema_versionversions this contract independently of the GraphCheck release. Reject an unsupported version rather than guessing at its meaning.runcontains identity, timestamps, status, exit code, selection, redaction, target metadata, and a run-level error when setup failed.scoreis a severity-weighted score ornullwhen no check executed. It is useful for reporting, but it does not replace the exit code or verdicts.totalsis the tally ofchecks[];suites[]contains the corresponding per-suite score and totals.checks[]contains exactly the selected check universe. A check excluded by suite or tag selection is absent, not skipped.
Run status is not the verdict
run.status describes execution coverage:
completemeans GraphCheck completed the selected universe. It does not mean all checks passed.partialmeans coverage was lost.partial_reasonexplains why.failedmeans the run could not be prepared or executed as a run. Inspectrun.error.
verdict describes each outcome:
errored is never a pass. Likewise, skipped proves nothing about the graph. Agents must not use
“no fail verdicts” as a success test because warnings, execution errors, partial runs, and an
entirely skipped selection are all non-clean outcomes.
Exit-code contract
Use the storedrun.exit_code as the overall automation decision. It is derived using the first
matching row:
This is a
0/1/2/3 contract, not a boolean convention where every nonzero value means the same
thing. Preserve all four values in wrappers and agent policy.
Evidence and remediation
Everyfail and warn has evidence:
kind is node, rel, or aggregate;
aggregate IDs name a measurement scope rather than a Neo4j element. When truncated is true,
elements is only the capped sample and total_count is the full finding count. Do not infer that
the listed elements are exhaustive.
For errored, use the structured error.code, message, and fix; absence of evidence is
expected because the assertion did not complete. For skipped, branch on skip_reason:
generated: intentionally inert pending human approval; it does not by itself make the run partial.unsupported: a required target capability was unavailable; the run is partial.not_run: execution stopped before this selected check ran, for example under fail-fast; the run is partial.
estimate is an object rather than false, report its sample size, population, confidence, and
confidence interval with the result. Do not present a sampled finding as an exact full-graph count.
Authoring check YAML
Suites are.yml or .yaml files beneath the configured checks directory. They have one optional
suite ID (which defaults to the filename stem), optional defaults, and one or more of the three
check collections:
conformance:id,check, andwithare required.checkselects an installed pack schema, and every type-specific argument belongs underwith.competency:id, nonblankquestion, read-onlyquery, and nonemptyexpectare required;paramsis optional. Shape assertions userows,columns,unique, orempty.containsandequalscreate regression checks.drift:id,metric,target, and nonemptytoleranceare required.baselinedefaults tolatest, but that baseline must exist when the check runs.
severity, tags, provenance, and generated. Severity resolves
from check to defaults to error; tags are the ordered union of suite defaults and check tags.
Check IDs must be unique across all three collections in a suite.
The check YAML contract is strict. Duplicate YAML keys, unknown fields, unknown check names,
invalid with parameters, and most scalar coercions are rejected. The
Check Reference lists every built-in conformance check with
worked examples; validation is the authority on each check’s exact with parameters — an invalid
suite is rejected with an error naming the offending field, so validate-and-correct is a reliable
authoring loop. Beyond structure, authors must also respect the semantic rules above: unique IDs
across all three collections, severity resolution, and the per-kind required fields.
Programmatic authoring and validation
An authoring program should construct data, serialize it with a safe YAML emitter, validate the finished text, and only then publish it. Agent-authored content must setgenerated: true before
that validation and write:
Generated checks require human approval
Every check created or materially rewritten by an agent must remain effectivelygenerated: true. Prefer the file-level marker for an entirely generated suite. The rule is
monotonic: a file-level generated: true makes every child generated, and a child
generated: false cannot override it.
Generated checks are fully parsed and validated, appear as generated: true in list_checks, and
appear in a selected run as verdict: skipped with skip_reason: generated. GraphCheck submits no
query for them. If every selected check is generated, nothing was evaluated and the run exits 2.
Only a human reviewer activates a check after verifying its source assumptions, scope, severity,
parameters, and (for competency checks) read-only query. Approval is represented by removing the
effective marker:
- To approve the whole generated suite, the human removes its file-level
generated: trueand any per-check generated markers. - To approve only some checks, the human removes the file-level marker, leaves
generated: trueon each unapproved check, and leaves approved checks unmarked.
