Skip to main content

zotero-provenance

ci release license

A Claude Code plugin that records every source your agent actually used.

Each URL Claude cites in an answer, and each link you paste into a prompt, is filed into a Zotero collection from a hook the model cannot skip. Over time you get a bibliography of your research trail instead of a scrollback to re-read.

Title:  Attention Is All You Need
URL:    https://arxiv.org/abs/1706.03762
Tags:   context:lit-review  project:my-thesis  seen:2026-08-20  domain:arxiv.org
  • Non-discretionary. Capture runs on every turn, whether or not anyone asked.
  • Deduplicated. Cite the same URL again and the item gains a second seen: tag.
  • Verifiable. Pages are hashed, so you can later prove one still says what it said.
  • Write-only. Reading your library is what Zotero MCP servers do; run one alongside.

Install

Inside Claude Code:

/plugin marketplace add musharna/zotero-provenance
/plugin install zotero-provenance
/zotero-setup

The hooks need python3 3.10+, five packages on that interpreter, and jq:

python3 -m pip install httpx beautifulsoup4 idna linkify-it-py markdown-it-py
sudo apt install jq        # macOS: brew install jq coreutils

The CLIs are also on PyPI for use outside the plugin (the hooks themselves install through /plugin, not pip):

pipx install zotero-provenance     # -> zotero-capture, zotero-capture-health

Setup asks for a Zotero API key with write access (https://www.zotero.org/settings/keys), verifies it with a live round-trip, and stores it at ~/.config/zotero-provenance/secrets.env (mode 0600).

platform status
Linux supported; where it is developed and tested
macOS supported; brew install jq coreutils
Windows, WSL supported inside WSL
Windows, native not supported; the hooks are bash scripts

If python3 is not the interpreter with the packages, set ZOTERO_PROVENANCE_PYTHON. A venv at <state-dir>/venv is picked up automatically.

Commands

Command What it does
/zotero-setup First-run configuration.
/source-delta [context] Which sources are new, persisting, recurring, or dropped since last run.
/triage <url> Mark a recurring source as dealt with.

What gets captured

Every URL in prose or a markdown link. Identifier hosts (doi.org, arxiv.org, PubMed, bioRxiv, GitHub) are resolved through their metadata API rather than scraped. When a title cannot be fetched the item is tagged title:unresolved and corrected the next time the URL is cited.

Not captured: URLs shown in code blocks or backticks, localhost and private addresses, tracking parameters, page assets, and reserved names like example.com. Title fetching refuses anything not publicly routable, on every redirect hop.

Details: what is captured, identifier resolution, unresolved titles.

Beyond capture

Prove a page still says what it said. Hashes are stamped onto the item's extra field and never overwritten by a later check.

python3 scripts/snapshot_pages.py             # hash items that lack one
python3 scripts/snapshot_pages.py --verify    # what has changed since

See what a source was cited for. The sentence around each URL is kept in a local index, never sent to Zotero.

python3 scripts/show_claims.py --search retraction

Retry failed writes. A failed Zotero write is queued, not dropped.

python3 scripts/drain_queue.py

Details: page hashing, claims, the retry queue.

Configuration

Credentials come from the secrets file, because hooks do not inherit MCP-scoped environment from ~/.claude.json.

Variable Meaning
ZOTERO_API_KEY Required. Key with write access.
ZOTERO_LIBRARY_ID Required. No default; a default would write elsewhere.
ZOTERO_WEBSOURCES_COLLECTION_KEY Required. Target collection.
ZOTERO_LIBRARY_TYPE user (default) or group.
ZOTERO_CAPTURE_DISABLE=1 Turn capture off entirely.
ZOTERO_CAPTURE_PROJECT Force the project: tag instead of deriving it.
ZOTERO_CAPTURE_PROJECT_ROOTS Extra path roots (:-separated) that projects live under.
ZOTERO_CAPTURE_STATE_DIR Where the dedup database and log live.
ZOTERO_SECRETS_FILE Alternate credentials file.
ZOTERO_PROVENANCE_PYTHON Interpreter to use.
ZOTERO_API_BASE Alternate API root, for tests or a compatible server.
ZOTERO_CAPTURE_HEALTH_DISABLE=1 Turn off the session-start health check only.
ZOTERO_CAPTURE_HEALTH_WINDOW_HOURS How far back operational faults are reported. Default 24.

A health check runs at session start and prints nothing when all is well. When capture is broken it says so in one line. Details: the health check.

How this differs from a Zotero MCP server

zotero-mcp, Zoteus, ZoFiles and llm-for-zotero let the model read or write your library when asked. This plugin records every URL the model cited, asked or not, and keeps checking that those pages still say what they said. One is a tool the agent uses. This is a record of what the agent used.

Known limitations

  • Claude Code on the web captures nothing; sessions bridged with /remote-control do.
  • Title lookup has a one-second budget. On timeout the URL stands in as the title.
  • A GitHub 404 is recorded as not_visible, never gone: private repos 404 on purpose.
  • Citations captured before 2026-08-21 may under-count sources with ) in the URL.

Full list with remedies: known limitations.

Development

pip install -e ".[dev]"
python3 -m pytest -q

About 1,200 tests run by default and need no network. Ten live tests are opted into with -m live. Design rationale, the deployed-root probe, and live-test setup: docs/design.md. Contributions: CONTRIBUTING.md.

License

MIT

Metadata

Release files for zotero-provenance 0.65.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zotero-provenance 0.65.0
File Size Uploaded
zotero_provenance-0.65.0.tar.gz 375.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zotero-provenance 0.65.0
File Interpreter ABI Platform
zotero_provenance-0.65.0-py3-none-any.whl Python 3 none any Details

Total release size: 528.5 kB

Release files / zotero_provenance-0.65.0.tar.gz

Download URL zotero_provenance-0.65.0.tar.gz
Size 375.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e5d4a77f8f4c8055a64ec09f1020b56aeb68222d1a0d6f827a3826420319fddf
BLAKE2b-256 checksum
How to use checksums
214d5c30ab60e4cbc6ead2f2a033e8ffc0d130b5b1160f302905df660d3687ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / zotero_provenance-0.65.0-py3-none-any.whl

Download URL zotero_provenance-0.65.0-py3-none-any.whl
Size 153.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a98fb89b42c247406cf8546d88b49e494e190c164616bd9c48ef32ac62d63c55
BLAKE2b-256 checksum
How to use checksums
6eebfc9e84fc0cf351c549dfaf4c35f3a0bd21c752a25a9f39e685a1d8d4bfd8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.65.0 This release

2 release files

0.64.1

2 release files

0.64.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page