Skip to main content

Local-first paper pipeline orchestrator between Zotero and Obsidian: detect, note, fetch PDF, queue AI analysis, index.

Project description

ZotVault

Local-first paper pipeline orchestrator between Zotero and Obsidian.

ZotVault watches your Zotero library and, for every new paper, automatically: creates an Obsidian note, secures a PDF (open-access first, politely rate-limited), puts the paper on an AI-analysis queue, and keeps your vault's index current. Around that core loop it adds one-shot DOI/arXiv adding, paper search, a local dashboard, arXiv keyword alerts, an in-library citation graph, embedding-based related-paper suggestions, and synthesis-cluster proposals.

Everything runs on your machine. No cloud accounts required, no API keys required for the core loop, zero runtime dependencies (Python ≥ 3.9 standard library only).

[search]                       [collect]                [archive]           [wiki]
arXiv / S2 / Crossref  ──▶  dashboard / CLI / agent ──▶  Zotero (BBT)  ──▶  Obsidian vault
        ▲                        │ you approve             │ sqlite poll        │
        └── arXiv alert inbox ───┘                         ▼                    ▼
                                            daemon: note → PDF (OA→proxy) → queue → index
                                                     + citation graph · related · synthesis

Features

  • One-shot addzotvault add 10.1103/PhysRevB.1.1 arXiv:2405.01234: metadata via Crossref/DataCite/arXiv → straight into Zotero through the same local channel the browser connector uses — including the OA PDF when one exists (Zotero downloads it itself, like the browser connector). Duplicates are detected before saving; a pipeline cycle runs immediately after the add. Optional translation-server support for arbitrary URL imports.
  • Automatic wiki-fication — new Zotero items become Obsidian notes (template-compatible, atomic writes). Existing notes are never rewritten; your manual sections are structurally safe.
  • Edit-safe highlight sync — Zotero PDF highlights land in ONE marker-delimited block per note (grouped by color, deep links back to the exact annotation), kept in sync incl. deletions. Figure/area annotations are embedded as images (copied from Zotero's cache). Color groups can be renamed to your semantics (label_red = "Core Claims"). Everything outside the block is untouchable; unmarked legacy notes are opt-in ([annotations] adopt_existing). See docs/MIGRATION.md.
  • PDF resolution, politely — Zotero attachment → cache → arXiv → Unpaywall → (opt-in) institutional proxy with browser-session cookies. Sequential, delayed, daily-capped: designed to not get your campus blocked. See docs/PROXY.md.
  • AI-analysis queue — ZotVault doesn't run an LLM; it feeds yours. zotvault queue --json lists unanalyzed papers with readable PDF paths; when your agent (e.g. Claude batch) writes *_analysis.md, completion is auto-detected.
  • Dashboardzotvault webhttp://127.0.0.1:8377 : search → tick → add, queue, alerts inbox, suggestions, audit trail. Localhost only.
  • arXiv alerts — daily keyword digest into a review inbox. Nothing enters Zotero without your click (propose, don't execute).
  • Alert triage (assist) — optionally, a small local Ollama model scores inbox candidates 0–10 for relevance under a strict JSON contract (constrained decoding + validation + one retry); the dashboard sorts by score. Advisory only, off by default.
  • Citation graph — Semantic Scholar citation counts + who-cites-whom within your library, regenerated into Citation_Graph.md.
  • Related papers — local Ollama embeddings over your analysis notes → Related_Suggestions.md link candidates. Free, offline.
  • Synthesis suggestions — clusters analyzed-but-unsynthesized papers into proposed review topics.
  • Auditable — every automatic action lands in a SQLite trace (zotvault trace).

Requirements

  • Python ≥ 3.9 (CLI is cross-platform; the double-click app + install-daemon autostart are macOS today)
  • Zotero desktop with Better BibTeXrequired: it is ZotVault's citekey source. Without it, items can't be named and nothing syncs (ZotVault will mark them blocked and tell you).
  • An Obsidian vault (any folder). ZotVault writes per-paper notes under <papers_subdir>/<citekey>/ — configure the paths; it does not impose a vault structure.
  • Optional: pdftotext (poppler) for full-text AI analysis, Ollama (related papers / local analysis), an institutional web proxy for licensed PDFs.

Quick start

git clone https://github.com/jbaek-dev/ZotVault && cd ZotVault
pip install .                          # or: pipx install .   /   uv tool install .
zotvault init                          # writes ~/.zotvault/config.toml
# edit: [vault] dir, [pdf] unpaywall_email  (+ [alerts] keywords if you want digests)
zotvault doctor                        # verifies Zotero, Better BibTeX, vault paths
zotvault run-once --dry-run
zotvault run-once

Run it continuously. Two options on every platform:

  • System tray (recommended): pip install ".[tray]" then zotvault tray — daemon + tray icon with Open Dashboard / Run now / Pause / Quit. The only third-party packages ZotVault can use, and only if you opt in.
  • OS service: zotvault install-daemon — macOS writes a launchd plist, Linux writes a systemd user unit, Windows prints the Task Scheduler command. Never auto-loads; it tells you the enable command.

macOS extra: double-click ZotVault.app (bash scripts/build_app.sh).

Every command also works without installing, via python3 -m zotvault.cli <cmd>.

Commands

command what it does
init / doctor config file / environment health check
run-once [--dry-run] / daemon one cycle / poll loop (+dashboard thread)
install-daemon autostart: launchd plist (macOS) / systemd unit (Linux) / schtasks cmd (Windows)
tray daemon + system-tray icon (needs pip install ".[tray]")
add <ids…> [--dry-run] resolve DOI/arXiv/URL → save to Zotero
search <query> [--source arxiv|s2|crossref] search with in-library marks
web dashboard server in the foreground
queue [--json] papers awaiting AI analysis
alerts [--fetch|--approve N|--dismiss N] arXiv digest inbox
enrich [--limit N] citation graph + embeddings + suggestion notes
assist [--limit N] score pending alerts with the small local model
related <citekey> / synthesis [--write] similarity / cluster proposals
status / trace [--limit N] state summary / audit trail

Design guarantees

  • Read-only toward Zotero's data. Library reads use a temp snapshot of zotero.sqlite; adds go through Zotero's own connector endpoint (Zotero writes its DB itself). ZotVault never touches storage/; downloaded PDFs live in ~/.zotvault/pdfs/.
  • Vault safety. Existing notes are never rewritten; auto-notes (Citation_Graph.md, Related_Suggestions.md, _Synthesis_Suggestions.md) are clearly marked and ZotVault-owned; index.md is only patched via a strict counter regex; log.md is append-only; --dry-run previews; no delete code path exists.
  • Polite networking. OA-first, sequential fetches, delays, hard daily caps (separate, stricter cap for the proxy), honest User-Agent, backs off on HTTP 429.
  • Nothing personal in code. All user-specific values live in ~/.zotvault/config.toml.

Agent integration

Any agent can drive ZotVault through the localhost API (/api/search, /api/add, /api/queue, /api/status). A ready-made tool module for the Polaris local agent (not yet public) lives in that repo (polaris/tools/zotvault_tools.py): search results show up with in-library marks, and adding requires the user to have explicitly picked papers.

Tests

python3 -m unittest discover -s tests -v   # 101 tests, no network needed

License

MIT — see LICENSE. Changelog in CHANGELOG.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zotvault-0.9.1.tar.gz (90.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zotvault-0.9.1-py3-none-any.whl (84.0 kB view details)

Uploaded Python 3

File details

Details for the file zotvault-0.9.1.tar.gz.

File metadata

  • Download URL: zotvault-0.9.1.tar.gz
  • Upload date:
  • Size: 90.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zotvault-0.9.1.tar.gz
Algorithm Hash digest
SHA256 64e40eb4e646799ebacf8fe99fb91bdb113e9bcb878a16475c7f1de447f81fe9
MD5 766e19d9bac33c7a61901051d75a9f55
BLAKE2b-256 05ea2446331fb219b6c0679d1611de73c230bf2b9ddea9d467a3a1e731ef8c87

See more details on using hashes here.

Provenance

The following attestation bundles were made for zotvault-0.9.1.tar.gz:

Publisher: publish.yml on jbaek-dev/ZotVault

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zotvault-0.9.1-py3-none-any.whl.

File metadata

  • Download URL: zotvault-0.9.1-py3-none-any.whl
  • Upload date:
  • Size: 84.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zotvault-0.9.1-py3-none-any.whl
Algorithm Hash digest
SHA256 15613d7f6d8884f6b6ecf8fc97ca2ba7fd4a6a4793b42850af236984200027b8
MD5 a692840cf32bae70be8219717ac0d90c
BLAKE2b-256 b5e6b7a8b7ef53be8825ee95d8f00b243dde259317e5d91e339103eb232d9a26

See more details on using hashes here.

Provenance

The following attestation bundles were made for zotvault-0.9.1-py3-none-any.whl:

Publisher: publish.yml on jbaek-dev/ZotVault

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page