Open source · Python CLI · v0.2.0
CiteGuard checks URLs, source titles, redirects and weak claim-to-source word overlap in Markdown research reports. Local, deterministic, no API key or telemetry.
View source on GitHub · Quickstart and documentation
python -m pip install "git+https://github.com/larrylot/citeguard.git"
citeguard check research.md --json
For an isolated CLI, use pipx install git+https://github.com/larrylot/citeguard.git. Requires Python 3.10 or newer.
| Verdict | Meaning |
|---|---|
clean | Available lexical checks passed. Not proof that the claim is true. |
dead | Source returned HTTP 404 or 410. |
title_mismatch | Descriptive link text differs from source title. |
claim_weak | Weak word overlap between claim and HTML text. |
redirect_suspect | Redirect to a different host without strong title match. |
unverifiable | DNS/network failure, oversized response or redirects that could not be followed. |
unchecked | Insufficient readable/checkable HTML; includes PDFs. |
blocked | Untrusted address, embedded credentials or unsupported scheme. |
http_error | Other HTTP error such as 403 or 500. |
unresolved | URL absent from the offline fixture catalog. |
Each citation occurrence receives its own result, while repeated URLs share a single HTTP fetch. Output is JSON or human-readable text. Exit 0 means every citation passed; exit 1 means at least one failed or nothing was found; exit 2 means an input error.
citeguard check fixtures/clean.md --fixtures
citeguard check fixtures/dead_link.md --fixtures --json
The offline fixture commands run from a repository checkout.
Private and non-global IP addresses are blocked by default; redirects and HTML body sizes are limited. Application-level DNS checks are not a full SSRF defense, so hosted services must add network-level egress controls. See Security policy and Changelog.