FullVahti

July 30, 2026 · View on GitHub

Find open-access full-text PDFs for your Zotero references, check them for retractions, and catch wrong or incomplete citation metadata — in two clicks, with a tidy report of what still needs a human.

FullVahti workflow: selected or tagged Zotero references are looked up on Unpaywall and PubMed Central; each item is tagged pdf-found, pdf-missing or check-needed; one report note lists what is missing and why — the list you take to your library. No paywall bypass, PMC OA subset only, license recorded per PDF.

FullVahti is a Zotero plugin from the Vahtian tool family. You select references (or tag them), FullVahti looks each one up on Unpaywall and PubMed Central, attaches the free, legal PDF when one exists, and labels every item with what happened:

TagMeaning
fulltext:pdf-foundPDF attached (or one was already there)
fulltext:pdf-missingNo open-access copy exists — request it via your library
fulltext:check-neededSomething went wrong or no DOI/PMID — worth a human look

After each run you also get one report note in your library (tagged fullvahti:report) listing everything not found and why — exactly the list you need for interlibrary loan requests or a PRISMA flow diagram. FullVahti never creates per-item notes: the attached PDF is its own record.

Open access only. FullVahti never bypasses a paywall. Paywalled papers are honestly reported as missing. PubMed Central downloads are restricted to the PMC Open Access Subset via its official OA service — articles that are merely readable in PMC are reported for your library to request, not scraped. The report records the license of every PDF it attaches.

For PhD students & systematic reviewers

The whole point. A typical pass over a screening set, all from inside Zotero:

  1. Collect your references in Zotero (from a database export, a search, or CiteVahti). Tag the set you're working — e.g. cite:closer-look.
  2. Get the full textsTools → FullVahti: Find OA PDFs for tagged items. Free legal PDFs get attached; everything else is labelled and listed in one report note — your ready-made interlibrary-loan / PRISMA "to retrieve" list. Set your library's OpenURL resolver and each missing item gets a one-click Find in my library link.
  3. Catch retractionsTools → FullVahti: Check tagged items for retractions. Cross-checks PubMed and Crossref/Retraction Watch, so a retracted paper can't quietly stay in your review — including the 2024–2025 mass retractions PubMed doesn't index.
  4. Sanity-check the metadataTools → FullVahti: Check citation metadata for tagged items. Compares each record to Crossref and flags missing fields and mismatches (a mismatch often means the wrong DOI is attached). Read-only — it never edits your records.
  5. Record decisions (optional) — if you use CiteVahti for claim-by-claim appraisal, FullVahti is its safe write-back door: confirmed review tags land in Zotero only after a preview, and every write is audited and undoable.

Nothing leaves your machine except the DOI/PMID lookups to the open services named below. No accounts, no analytics.

Install (no technical skills needed)

  1. Download fullvahti-x.y.z.xpi from the latest release — right-click the file and choose Save Link As… if your browser tries to open it.
  2. In Zotero: Tools → Plugins, click the gear ⚙️ in the top-right, choose Install Plugin From File…, and pick the downloaded file.
  3. That's it. Updates install themselves.

Use

  • For a few papers: select them in your library, right-click → FullVahti: Find Open-Access PDFs.
  • For a whole screening batch: tag the references cite:closer-look (or your own tag — change it in Settings → FullVahti), then Tools → FullVahti: Find OA PDFs for tagged items.

The first run asks for your email once — Unpaywall and PubMed Central are free services that ask for a contact address. It is sent only to them, never to us.

FullVahti works politely, one paper at a time, so a big batch takes a few minutes. You can keep using Zotero meanwhile.

Check for retractions

A retracted paper is exactly what a screening workflow must catch — and with well over a hundred thousand retractions issued in 2024–2025 alone (the Hindawi/Wiley, Sage and IEEE sham-paper sweeps), many of them never indexed in PubMed, this matters more than ever. FullVahti flags retracted references using two sources:

  • PubMed (precise — the "Retracted Publication" publication type), and
  • Crossref, which now carries the Retraction Watch database — this catches the mass retractions PubMed doesn't list.

How to run it:

  • For a few papers: select them, right-click → FullVahti: Check for Retractions.
  • For a batch: tag them and use Settings → FullVahti → Check tagged items for retractions, or Tools → FullVahti: Check items tagged … for retractions.

Every item is labelled, and you get a report note that calls out the retracted ones (with where the flag came from):

TagMeaning
retraction:retractedPubMed or Crossref/Retraction Watch records this as retracted
retraction:noneNo retraction recorded in either source
retraction:check-neededNo record found, or the lookup failed — worth a human look

FullVahti only reads the status from PubMed and Crossref — it never decides retraction itself. For each DOI it checks PubMed first, then Crossref; for a DOI-only item it resolves a PMID via PubMed's search before falling back to Crossref.

Check citation metadata

Zotero records imported from databases often have missing or wrong fields — and a wrong field can mean the wrong DOI is attached to the record. FullVahti compares each reference against Crossref and tells you what's off, without changing anything:

  • For a few papers: select them, right-click → FullVahti: Check Citation Metadata.
  • For a batch: tag them and use Settings → FullVahti → Check citation metadata, or the Tools menu.
TagMeaning
citation:okMatches Crossref
citation:incompleteCrossref has fields your record is missing
citation:mismatchA field disagrees with Crossref — check before editing, it may be the wrong DOI
citation:check-neededNo DOI, or Crossref didn't have the record

The report note lists every discrepancy side by side (your value vs Crossref's). FullVahti is read-only here — it never edits a field and never auto-"fixes" a mismatch, because a mismatch needs a human: it can mean the wrong paper is attached, and only you should decide. (Comparisons fold accents and formatting, and only flag fields Crossref actually provides, to avoid noise.)

Check your manuscript's citations

The library side is only half the story: a Word manuscript can hold citations missing from the bibliography, the same paper cited under two different Zotero items (each with its own number), fields flattened to plain text by Track Changes or a Google Docs round trip, and reference-list entries nothing cites anymore. Zotero's duplicate detector cannot see any of this from inside the document.

Tools → FullVahti: Check manuscript citations opens the free Zotero Citation Checker: drop your .docx, get a Citation Integrity Report with every finding, its location (down to paragraph, footnote and table) and the exact repair step. The document is read in your browser and never uploaded; add an exported copy of your library (CSL JSON) and it also flags citations whose item no longer exists in your library.

Getting paywalled papers through your library

FullVahti only ever downloads open-access copies — it never fetches paywalled PDFs, even on your university network, because automated downloading through institutional credentials can trip publishers' "systematic download" terms and get your whole institution's access cut off.

Instead, it can hand the citation to your library. In Settings → FullVahti, paste your library's OpenURL resolver address. After that, every item with no open-access copy gets a "Find in my library" link in the report note — one click takes you to your library's resolver, where you fetch the licensed copy yourself. FullVahti does no paywalled downloading; it just builds the link.

(Your library's resolver URL is usually on its website under "link resolver", "OpenURL", "SFX", or "find it" — ask a librarian if unsure.)

For CiteVahti users (advanced, off by default)

FullVahti is CiteVahti's Zotero companion. It does the Zotero-side work CiteVahti deliberately stays out of — finding open-access PDFs, and writing confirmed review decisions back into your library — while CiteVahti keeps sole ownership of claim verification and the human-first rating workflow. FullVahti never verifies claims, never decides whether a paper supports a claim, never rates anything, and never receives manuscript text: it only ever sees an item key and a short list of allowlisted tags.

Write-back goes through a token-guarded endpoint on Zotero's local server (127.0.0.1:23119 — nothing leaves your machine):

  1. Zotero → Settings → FullVahti → tick Allow CiteVahti to write tags, click Generate new token.
  2. Give that token to CiteVahti.

The safety invariant: no silent Zotero writes

Every write is previewed, confirmed, audited, and undoable. The door is closed unless you open it, only allowlisted tags can be written, and the endpoints enforce this regardless of what a caller sends:

EndpointMethodPurpose
/fullvahti/pingGETAvailability + advertised capabilities and allowedTagPrefixes
/fullvahti/tagPOSTPreview or apply a tag change
/fullvahti/auditGETList recorded writes (token in query string)
/fullvahti/undoPOSTReverse a recorded write by its audit id

Allowlisted tags only. Even with a valid token, only tags beginning cite:, fulltext:, retraction:, citation:, GRADE:, RoB2:, ROBINS-I:, or Quality: are accepted; anything else is refused and nothing is written.

1 — Preview (dry run). CiteVahti shows you exactly what would change before anything is written:

POST /fullvahti/tag
{ "token": "…", "itemKey": "ABCD1234", "add": ["GRADE:high"], "remove": ["fulltext:pdf-missing"], "dryRun": true }
→ { "ok": true, "dryRun": true,
    "preview": { "before": [...], "after": [...], "willAdd": ["GRADE:high"], "willRemove": ["fulltext:pdf-missing"],
                 "alreadyPresent": [], "alreadyAbsent": [] } }

willAdd / willRemove are the effective change — tags already present (or already absent) are dropped, so the preview is exactly what will happen.

2 — Apply (after you confirm). Same call without dryRun. The response returns what was applied and an audit id:

→ { "ok": true, "itemKey": "ABCD1234", "applied": { "added": ["GRADE:high"], "removed": ["fulltext:pdf-missing"] },
    "audit": { "id": "abc-123", "ts": "2026-06-24T…" } }

3 — Audit. Every applied write is recorded locally (the token is never stored). CiteVahti can read it with GET /fullvahti/audit?token=…, and you can read it yourself — no token, no curl — via Tools → FullVahti: Show CiteVahti write-back audit log, which also lets you clear the history (clearing never changes tags already written).

4 — Undo. Any recorded write can be reversed by its audit id (preview the reversal with dryRun: true first):

POST /fullvahti/undo
{ "token": "…", "auditId": "abc-123" }
→ { "ok": true, "undoOf": "abc-123", "applied": { "added": ["fulltext:pdf-missing"], "removed": ["GRADE:high"] }, … }

CiteVahti's job is to obtain your confirmation for each verified decision; FullVahti's job is to make that write previewable, auditable, and reversible. Neither side bypasses the other.

Privacy

  • Lookups go directly from your computer to Unpaywall, NCBI/Europe PMC, and Crossref (for retraction status and citation-metadata checks), carrying the paper's DOI/PMID; your contact email goes only to the APIs that ask for it (Unpaywall, NCBI, Crossref), never to the sites PDFs are downloaded from. Nothing else, to no one else.
  • No analytics, no accounts, no Vahtian servers involved.

Development

Plain JavaScript, no build step — the plugin is the repository. To make an .xpi by hand: zip the files with manifest.json at the zip root. Releases are built automatically by GitHub Actions when a v* tag is pushed.

Compatibility: Zotero 7–9. When a new Zotero major lands, bump strict_max_version in manifest.json and re-release.

Two Claude Code skills live in .claude/skills/: zotero-9-plugin-dev (building/debugging/releasing a bootstrapped Zotero 7/8/9 plugin — including the Zotero 8/9 preference-pane "dead object" pitfall) and fullvahti-for-agents (the write-back API contract for an integrating LLM agent such as CiteVahti).

License

Apache 2.0 © Heidi Andersén / Vahtian