Verify BibTeX references against the Crossref API to catch DOI errors, year mismatches, author mismatches, and title discrepancies. Use this skill whenever the user wants to validate, check, or audit citations in a LaTeX manuscript — including phrases like "check my references", "verify DOIs", "validate citations", "doi-check", "/doi-check", or "run doi-check on my bib". Also trigger when the user suspects a citation might be wrong or wants a systematic audit of their bibliography before submission.
Systematically verifies BibTeX references against the Crossref REST API, then guides the user through interactive repair of any flagged entries.
Two modes:
--tex)--all: verify every entry in the .bib file, no .tex directory neededscripts/
├── bib_utils.py parse_bib, collect_cited_keys, strip_latex_comments
├── crossref_api.py query_doi, search_by_title_author, extract_fields, detect_mismatches
├── bib_updater.py fetch_metadata, format_bibtex_entry, patch_bib_entry
└── doi_check.py main CLI orchestrator (5-step workflow below)
# Default: check only cited entries (requires manuscript directory)
doi-check \
--bib <path/to/refs.bib> \
--tex <manuscript_directory> \
--out <output_directory> # default: output/ref_verification/
# --all: check every entry in the bib (no .tex directory needed)
doi-check \
--bib <path/to/refs.bib> \
--all \
--out <output_directory>
Add --no-interactive to skip the repair loop (report only).
Install the CLI:
uv tool install "git+https://github.com/KaiH1124/doi-check-skill.git"
Detect the .bib path, manuscript directory, and output directory from
context or by asking the user before running.
.bib file (bib_utils.parse_bib)--tex): scan all .tex files recursively, stripping
LaTeX % comments, then extract \cite{} / \citep{} / \citet{} keys
(bib_utils.collect_cited_keys). Only cited entries proceed; entries cited
but missing from bib are flagged immediately.--all mode: skip .tex scanning — every entry in the bib proceeds
to verification regardless of whether it is cited anywhere.https://api.crossref.org/works/{doi}ref_check.csv and summary.txt to the output directorycrossref_api.search_by_title_author()
using the bib title + first-author surname + yeardoi field (bib_updater.patch_bib_entry)bib_updater.fetch_metadata + format_bibtex_entry)| Status | Meaning |
|---|---|
OK | DOI resolved, year/author/title all match |
FLAGGED | DOI resolved but at least one mismatch detected |
ERROR | Crossref could not resolve the DOI (404, network, etc.) |
SKIP_NO_DOI | Entry has no DOI (books, standards, theses) — not queried |
YEAR_MISMATCH(bib=XXXX,cr=YYYY) — year differsAUTHOR_MISMATCH(bib=surname,cr=surname) — first-author surname differsTITLE_LOW_OVERLAP(0.XX) — fewer than 40 % of significant words matchAPI_ERROR: ... — network or HTTP errorDo NOT add % ... at the end of BibTeX field lines, e.g.:
% WRONG — BibTeX parser treats this as a new field name
doi = {10.1016/...}, % NOTE: check this
BibTeX only allows % comments on their own dedicated lines, outside entries.
Inline end-of-line comments cause "missing field name" errors and silently
drop the whole entry. If a note is needed, place it before the entry:
% NOTE: Crossref title differs; verify manually
@article{key,
doi = {10.1016/...},
}
TITLE_LOW_OVERLAP alone may be a false positive for old papers where
Crossref metadata is incomplete (e.g. 1916 Du Bois paper)SKIP_NO_DOI — expected behaviourhttps://api.crossref.org/works?query=… directly —
no MCP tools or third-party packages required, making the skill fully
self-contained and portable to any Claude Code environment