touchneedle
Citiation tool that verifies the citations in a document are real, accurately described, and consistently used.
Useful for both students and examiners who wish to corroborate citations.
It works standalone, or as a coding agent skill.
Most commercial citation checkers want a .bib file and check it against academic
databases. That covers journal articles but misses standards,
specifications, vendor documentation, and blog posts. In a lot of real
bibliographies, this is half the list.
So this tool parses a prose reference list (Harvard/author-date)
straight out of Markdown or .docx, and routes each entry to whichever
authority can actually confirm it.
What it checks
Existence and metadata — scripted and deterministic:
| Entry carries | Checked against |
|---|---|
| arXiv id | arXiv API |
| DOI | Crossref |
| RFC number | IETF datatracker, falling back to rfc-editor |
draft-* name |
IETF datatracker, including whether the cited revision is still current |
| Quoted title in an academic venue | Crossref, then OpenAlex, by title |
| A URL and nothing else | Fetched live; page title compared with the cited title |
Entries with both an identifier and a URL get both, so a real paper behind a dead
link is still reported. Detects the fabricated-citation signature — a real title
carrying the wrong authors — as MISMATCH.
Internal consistency — every in-text citation resolves to a list entry, every
list entry is cited somewhere, and 2025a/2025b suffixes are used unambiguously.
Claim support — the pass that needs reading rather than fetching. claims
emits a worklist pairing each in-text citation with the sentence making the claim
and a locator for the source; the model then reads each source and rules
SUPPORTED / PARTIAL / UNSUPPORTED / INACCESSIBLE. This catches the failure the
database checks cannot: a genuine source attached to a claim it does not make.
Install
As a command-line tool:
pip install touchneedle
As a Claude Code skill:
git clone https://github.com/nicoleman0/touchneedle ~/.claude/skills/touchneedle
Or as a Claude Code plugin:
/plugin marketplace add nicoleman0/touchneedle
/plugin install touchneedle
There are no dependencies beyond Python 3.11+. pandoc is needed only for .docx input.
Then, in Claude Code: "check the citations in thesis.docx".
Use directly
touchneedle check thesis.docx --out report.md --json data.json
touchneedle claims thesis.docx --out claims.md
From a clone, without installing, that is python3 scripts/touchneedle.py … —
the same file either way.
Options: --offline (parse and cross-check only, no network), --cache DIR
(HTTP cache, 7-day TTL, so re-runs are nearly free), --timeout N, and
--mailto you@example.com for Crossref and OpenAlex's polite rate-limit pool.
--mailto is off by default and never inferred — it sends an address to third
parties.
check exits 2 when something needs attention, 0 when clean, so it drops into CI.
Statuses
MISMATCH and NOT_FOUND are the ones that damage a submission. LINK_DEAD and
STALE need a fix but not a retraction. PARTIAL, LINK_MOVED and
UNVERIFIABLE are for a glance — notably, PDFs and JS-rendered pages land in
PARTIAL routinely, because no <title> can be read from them. A PARTIAL is a
limit of the check, not evidence against the citation.
Limits
Author-date reference lists only — numeric styles (Vancouver, IEEE) are not parsed. Page numbers, edition and publisher details are not checked.
Sources behind paywalls cannot be verified beyond their metadata record.
The list of in-text citations with no matching entry has expected false positives,
because a regex cannot distinguish (Smith, 2024) from (ICLR 2023).
Development
python3 -m unittest discover -s tests -t tests
See CONTRIBUTING.md before opening a pull request.
The short version: standard library only, tests stay offline, and never let a coverage gap report itself as a finding.
Licence
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file touchneedle-0.1.0.tar.gz.
File metadata
- Download URL: touchneedle-0.1.0.tar.gz
- Upload date:
- Size: 24.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e5a05a4c3fc2668213df4e0c7ed97f9c1e99bbf7e37f14a4bf49a52b2fd57f6
|
|
| MD5 |
dc1503ae9ff83df83e1dff2c3c43267f
|
|
| BLAKE2b-256 |
0b5f395d1d9cc40fccae7e6f153b1e444d924af8702aa75307d71bb5be9fac18
|
Provenance
The following attestation bundles were made for touchneedle-0.1.0.tar.gz:
Publisher:
publish.yml on nicoleman0/touchneedle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
touchneedle-0.1.0.tar.gz -
Subject digest:
4e5a05a4c3fc2668213df4e0c7ed97f9c1e99bbf7e37f14a4bf49a52b2fd57f6 - Sigstore transparency entry: 2651560924
- Sigstore integration time:
-
Permalink:
nicoleman0/touchneedle@9c41a793ba76065813d8d1914ed3e107b18ef650 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nicoleman0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9c41a793ba76065813d8d1914ed3e107b18ef650 -
Trigger Event:
release
-
Statement type:
File details
Details for the file touchneedle-0.1.0-py3-none-any.whl.
File metadata
- Download URL: touchneedle-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
699c075c4cea9b3c54ce9b8884442c6678c34a6b85fe5e5ff020b85faa2335da
|
|
| MD5 |
34a44f2662ade776807f8cb9b9a018e5
|
|
| BLAKE2b-256 |
f917a9b150edeb8555afcf50fbb7e32ba5b711d63a8b618428980cb5d5da3f51
|
Provenance
The following attestation bundles were made for touchneedle-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on nicoleman0/touchneedle
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
touchneedle-0.1.0-py3-none-any.whl -
Subject digest:
699c075c4cea9b3c54ce9b8884442c6678c34a6b85fe5e5ff020b85faa2335da - Sigstore transparency entry: 2651560962
- Sigstore integration time:
-
Permalink:
nicoleman0/touchneedle@9c41a793ba76065813d8d1914ed3e107b18ef650 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nicoleman0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9c41a793ba76065813d8d1914ed3e107b18ef650 -
Trigger Event:
release
-
Statement type: