groundcheck-mcp
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., "@groundcheck-mcpverify this quote against https://example.com/paper: "grounding verification with no LLM""
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.
Groundcheck, verification with no model in the loop
I built this MCP connector to check whether the grounding behind a claim is
real. Is the quote actually on the page? Does the arXiv id resolve? Does the
code print what someone says it prints, and is the number right? There's no
language model anywhere in the verification path. It works in any MCP host, so
Claude, Gemini or something else. The checkers under verify/ re-derive every
verdict it returns. They run against the same fixtures and don't share the
server's code. If a re-derivation drifts, the build stops.
Abstract
When an assistant "fact-checks" something, it almost always asks a second model whether the first one was right. That just moves the error somewhere else, since the checker hallucinates too. I wanted to check grounding against reality instead. Groundcheck has five tools. They fetch a page, resolve an identifier, run a snippet, grep a codebase or evaluate an expression. Each one returns one of three verdicts with the evidence attached.
I kept the scope narrow on purpose. Groundcheck confirms that the evidence a
claim rests on is real and says what it's quoted to say. It doesn't judge
whether a claim is semantically true. "This quote is on the cited page" can be
checked. "The page's argument is correct" can't. When it can't tell, it
returns unverifiable.
No language model is involved in any verdict.
Contributions. (i) Verification grounded in sources. (ii) A three-verdict
contract with an explicit unverifiable, so refusing to answer is a proper
outcome. (iii) Results you can audit, since every verdict carries the quote,
stdout, matching line or computed value it was based on.
Related MCP server: math-logic-mcp
1. Why this, and why it's hard
Almost every "fact-check" built into an assistant today ends up asking a second model whether the first one was right. That doesn't really verify anything. The checker hallucinates too, so the error just ends up in a different place. Checking against reality instead of another model's opinion is the hard part, and few tools attempt it. That's the only thing this one does.
I want to be careful about scope, since over-claiming would undercut the whole
idea. Groundcheck confirms that the evidence a claim rests on is real and
says what it's quoted to say. It doesn't judge whether a claim is semantically
true. "This quote is on the cited page" is checkable. "The page's argument is
correct" isn't, and pretending won't change that. Every tool returns one of
three verdicts. When it can't tell, it says unverifiable.
verdict | meaning |
| the grounding was confirmed against a real source |
| the source exists and contradicts the claim (wrong number, missing quote, dead id, failing code) |
| no source, or it needs judgement this tool refuses to fake |
flowchart LR
A["Assistant makes<br/>a claim"] --> M{"Groundcheck<br/>MCP server"}
M --> Q["check_quote<br/><i>fetch the page</i>"]
M --> C["check_citation<br/><i>query arXiv / Crossref</i>"]
M --> X["check_code<br/><i>run in a subprocess</i>"]
M --> R["check_repo<br/><i>grep the files</i>"]
M --> T["check_math<br/><i>evaluate an AST</i>"]
Q & C --> NET[("the live web")]
X & R --> LOCAL[("local filesystem<br/>and interpreter")]
T --> PURE[("arithmetic")]
NET & LOCAL & PURE --> V{"verdict"}
V --> OK["checked"]
V --> NO["refuted"]
V --> UNK["unverifiable"]
classDef src fill:#4d4d4d,stroke:#2b2b2b,color:#fff
classDef good fill:#1a9850,stroke:#0f6b33,color:#fff
classDef bad fill:#b2182b,stroke:#7f0f20,color:#fff
classDef warn fill:#f4a582,stroke:#c06a4f,color:#000
class NET,LOCAL,PURE src
class OK good
class NO bad
class UNK warnNone of the boxes in that diagram is a language model. Every verdict ends at something you can look up, run or compute.
2. The tools
tool | verifies | how (no LLM) |
| an exact quote is on a page | fetch the page, match the text |
| an arXiv id or DOI resolves | query arXiv / Crossref, return the real title |
| code prints what's claimed | run it in a subprocess, compare stdout |
| a string/regex is in a codebase | grep the files, return real matching lines |
| arithmetic is correct | evaluate an AST (no |
Every result has the shape {status, method, evidence, detail}. The
evidence field holds whatever was actually found, like the quote, the stdout,
the matching line or the computed value. That's what makes a verdict auditable.
2.1 A live run

Each row above is a real call to the same function the server exposes. That
includes the arXiv lookups that need the network. The refutations are real
too. The first row is the 3.7 x 1400 error from section 3, reproduced.
2.2 The case corpus
verify/export_cases.py writes these tables. I keep them tracked in git so CI
can corrupt one and make sure the harness notices.
table | cases | checked | refuted | unverifiable |
| 27 | 17 | 3 | 7 |
| 10 | 6 | 2 | 2 |
| 11 | 6 | 4 | 1 |
3. It caught a mistake in its own author's work
I wrote check_citation because made-up arXiv ids that looked plausible kept
slipping into research write-ups. They look right and resolve to nothing.
check_math exists because 3.7 × 1400 was written as 8880 in a hardware
deck. It's actually 5180. check_repo grew out of a claim-checker for my
profile README that compares every quoted number with the repo it came from.
So each tool started as a mistake that really happened.
One thing surprised me. While testing, I assumed arXiv 2606.01992 was
fabricated and expected refuted. The tool returned checked. It was right
and I was wrong, because it's a real June-2026 paper. The verifier caught my
own bad assumption, and that's exactly why I wanted verification grounded in a
source.
4. Use it
pip install -e . # or: pip install -r requirements.txt
python -m pytest tests/ # 23 tests, no network needed (mocked transport)For Claude or Claude Code, add this to your MCP config.
{
"mcpServers": {
"groundcheck": { "command": "python", "args": ["-m", "src.groundcheck.server"] }
}
}For Gemini CLI or any other MCP host, it's the same stdio server. Point your
host's MCP config at python -m src.groundcheck.server. MCP is why one
connector can serve both.
5. Security
check_code runs the code you give it in a subprocess. It uses list-form
subprocess, so there's no shell and nothing to inject, and it kills the
process on timeout. It isn't sandboxed from the network or the filesystem,
though. Only pass code you'd run yourself. The other four tools are read-only
(HTTP GET, file read, arithmetic).
6. Limitations
This checks grounding. It doesn't check truth, and that's by design (see Scope above).
Quote matching is exact, apart from normalising whitespace. A paraphrase that
means the same thing returns refuted. Deciding that two sentences "mean the
same" needs a judge, and this tool refuses to be one. Match the literal text.
check_quote reads the served HTML, so it won't find a quote on a JS-rendered
page that client-side JavaScript injects. It fails safe with refuted and
never gives a false checked.
Citations only go through arXiv and Crossref. Other registries aren't wired up yet.
7. Licence
MIT, see LICENSE.
Available Tools
5 toolscheck_citationA
Verify that an arXiv id or DOI actually resolves, and return its real title.
Pass an arXiv id (e.g. '2412.18004' or 'arXiv:2412.18004') or a DOI. A 'checked' verdict includes the genuine title, so a plausible-looking but fabricated identifier is caught as 'refuted'.
| Name | Required | Description | Default |
|---|---|---|---|
| identifier | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does disclose meaningful output semantics: a 'checked' verdict returns the genuine title, while a fabricated identifier yields 'refuted'. That verdict vocabulary is genuinely useful, but failure modes (network errors, malformed input handling, latency) are not mentioned.
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?
Three sentences, front-loaded with the core action; the second covers input format and the third covers the verdict semantics. No filler, and each sentence adds information an agent needs.
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?
No output schema and no annotations means the description must cover both input and response semantics, which it largely does via the checked/refuted verdict explanation. It is nearly complete for a one-parameter tool, though it omits what happens on unresolvable-but-valid-looking edge cases or errors.
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?
The schema has 0% description coverage for its single parameter, so the description must compensate, and it does: it names the parameter concept (arXiv id or DOI) and supplies two concrete arXiv formats plus DOI acceptance. This covers the practically important format ambiguity even though it doesn't specify a DOI example.
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?
States a specific verb (verify) and resource (arXiv id or DOI), plus a secondary outcome (return its real title). The verification framing clearly distinguishes it from siblings like check_quote, check_code, check_repo and check_math, which each target a different artifact type.
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 establishes the trigger condition (you have an identifier that may be fabricated) and the motivation for using it. It gives concrete accepted input formats, but never names an alternative tool or states when NOT to use this one, so it falls short of the top tier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_codeA
Run a self-contained Python snippet and confirm its stdout contains
expected_output.
WARNING: this executes the code. Only pass code you would run yourself; it is not sandboxed from the network or filesystem. Returns refuted if the snippet errors or prints something other than claimed.
| Name | Required | Description | Default |
|---|---|---|---|
| snippet | Yes | ||
| expected_output | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it warns that the code is actually executed, that it is not sandboxed from the network or filesystem, and it defines the failure semantics ('returns refuted if the snippet errors or prints something other than claimed'). These are the exact behavioral traits an agent needs before invoking an execution tool.
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?
Three tight sentences, front-loaded with the primary action, then the safety warning, then the return contract. No filler; each sentence adds information an agent would otherwise have to guess.
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?
No output schema exists, and the description covers the most important return case (refuted on error or mismatched output), which is enough to call the tool correctly. It does not state what a successful result looks like or whether it echoes the actual stdout, a small gap for a verification 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 is 0% (no parameter descriptions at all), so the description must compensate, and it largely does: 'self-contained Python snippet' scopes the snippet, and 'confirm its stdout contains expected_output' establishes that expected_output is a substring-containment match rather than an exact-match string. A few details (encoding, trailing newline handling) remain unspecified.
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?
States a specific operation (run a self-contained Python snippet), the verification contract (confirm stdout contains expected_output), and does so in terms that clearly separate it from check_quote, check_citation, check_repo, and check_math. An agent can select it without opening the schema.
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?
Usage guidance is implicit: 'self-contained Python snippet' and 'Only pass code you would run yourself' define the context of appropriate use, but there is no explicit statement of when to prefer this over a sibling (e.g. check_math for pure arithmetic) or when not to use it. Adequate but leaves selection against alternatives to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_mathA
Confirm an arithmetic expression equals a claimed result.
Evaluates expression (numeric literals and + - * / // % ** only) and
compares to claimed_result. Catches arithmetic a model asserted without
computing.
| Name | Required | Description | Default |
|---|---|---|---|
| expression | Yes | ||
| claimed_result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full disclosure burden. It usefully constrains the accepted input domain to numeric literals and the operators + - * / // % **, which tells the agent what will fail, but it never states the return shape, error behavior for malformed expressions, or numeric precision handling.
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?
Two short sentences, purpose front-loaded, with the operator whitelist as precise supporting detail. Every clause earns its place; nothing is padded or redundant.
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?
For a two-parameter verification tool with no output schema, the description conveys purpose, input constraints, and the intent of the check (catching uncomputed claims), which is enough to call it correctly. The exact response format is only implied rather than stated, which is the one remaining gap.
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%, so the description must compensate, and it does: it names both parameters and defines what `expression` may contain (numeric literals and a specific operator set) and what `claimed_result` is compared against. It could go further on numeric formats or edge cases, but it adds real meaning over the bare schema titles.
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?
States a specific verb ('confirm') and resource ('arithmetic expression equals a claimed result'), and the math domain cleanly separates it from the check_quote/check_citation/check_code/check_repo siblings. An agent can route to it without inspecting the schema.
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?
'Catches arithmetic a model asserted without computing' gives a clear triggering context — verifying a numeric claim rather than trusting it. It stops short of explicit when-not-to-use guidance or naming alternatives (e.g. using a real computation tool for symbolic math), so it is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_quoteA
Verify that an exact quote appears on a web page.
Fetches url and confirms quote is present in its visible text. Use before
attributing a statement to a source. Returns refuted if the page loads but
the quote is absent -- i.e. the attribution is fabricated.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| quote | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that the tool performs a network fetch, that matching is against visible text rather than raw HTML, and that a loaded page without the quote yields a "refuted" verdict meaning the attribution is fabricated. It omits failure-mode behavior (page fails to load), auth, and rate limits.
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?
Three short sentences, front-loaded with the core action, then the mechanism, then the usage trigger, then the failure semantics. No wasted wording.
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?
No output schema exists, so the description appropriately explains the return verdict, including what "refuted" means. It leaves the success verdict and load-failure behavior implicit, which is a small but real gap for an agent interpreting results.
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%, so the description must compensate, and it does: `url` is defined as the fetched target and `quote` as the exact string matched against the page's visible text. It still leaves ambiguity about matching strictness (case, whitespace, normalization) and accepted URL forms.
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?
Specific verb+resource: verifies that an exact quote appears on a fetched web page. This clearly distinguishes it from siblings like check_code, check_repo, and check_math, which all verify different artifact types.
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?
"Use before attributing a statement to a source" gives a clear situation for invocation, and the resource-based framing naturally separates it from the other check_* tools. No explicit alternative is named, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_repoA
Confirm that a string (or regex) actually occurs in files under a local path.
Use to verify a claim about what a codebase or document contains -- 'the README reports 0.9086', 'the function is defined in src/' -- rather than trusting the assertion. Returns the real matching lines.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| regex | No | ||
| pattern | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It usefully discloses that the tool returns the real matching lines and that it is a verification/read operation, but it omits operational traits such as permission needs, path recursion behavior, or what happens on no match.
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?
Two tight paragraphs, front-loaded with the core action and followed by the use case and return behavior. No filler sentences, though the examples could be trimmed slightly.
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?
For a three-parameter tool with no annotations and no output schema, the description covers purpose, use case, and return content. It still leaves path semantics and no-match/error behavior unspecified, which an agent would need to call it confidently.
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%, so the description must compensate. It partially does: 'a string (or regex)' maps to pattern plus the regex flag, and 'under a local path' maps to path. However, it never explains path format (absolute vs relative, file vs directory) or that regex defaults to false.
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 a specific verb and resource: confirm that a string or regex occurs in files under a local path. The scope (local filesystem content) implicitly separates it from siblings like check_citation, check_math, and check_quote, though it never names them explicitly.
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?
It gives clear usage context — verify a claim about what a codebase or document contains rather than trusting an assertion — and supplies concrete examples ('the README reports 0.9086'). No explicit when-not conditions or named alternative tools are provided.
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.
5 tool updates
v0.1.0- First observed
check_citation - First observed
check_code - First observed
check_math - First observed
check_quote - First observed
check_repo
TDQS
Scored across 5 tools
Each tool verifies a distinct artifact type: web-page quote, arXiv/DOI identifier, Python snippet output, local repo content, and arithmetic. The input types and returned verdicts differ clearly, so an agent can pick the right tool without overlap.
All five tools follow an identical check_<noun> pattern (check_quote, check_citation, check_code, check_repo, check_math). This is a fully predictable, uniform convention.
Five tools is well-scoped for a claim-verification server, with each tool earning its place by covering a different source of unverified assertions. No redundancy or filler.
The surface covers the main verification targets (quotes, citations, code, repo contents, math) and returns actionable verdicts. Minor gaps exist, such as no standalone URL-liveness check or batch/multi-source verification, but core workflows are covered.
Maintenance
Related MCP Connectors
Experimental MCP server for current empirical verification of explicit public HTTPS endpoint claims.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for verifying AI agent claims vs reality — single-transcript inline grounding-check that flags when an agent's response states facts not in the input context, when its code silently swallows exceptions and substitutes mock data, or when its multi-turn transcript contains contradictions or unverified completion claims. Sub-second, local, free, no API calls.444 PyPI1MIT
- AlicenseAqualityDmaintenanceMCP server that gives small LLMs verified symbolic-math & logic tools.62Apache 2.0
- AlicenseNot gradedqualityDmaintenanceAn MCP server that verifies whether a claim is actually supported by the source text at a given citation — independent of what the calling LLM asserts.MIT
- AlicenseNot gradedqualityCmaintenanceProvides an MCP server for storing and querying knowledge as verifiable claims, enforcing evidence-backed assertions with exact quotes and refusing paraphrases or unsupported relations.Apache 2.0