Full-featured CLI for Zotero reference management. Search, import by DOI/PMID, export BibTeX, attach PDFs, semantic search, manage tags/collections, and more. Use this tool whenever you need to interact with a Zotero library programmatically.
Full-featured CLI for Zotero reference management. Search, import by DOI/PMID, export BibTeX, attach PDFs, semantic search, manage tags/collections, and more. Use this tool whenever you need to interact with a Zotero library programmatically.
cli-anything-zotero
Agent-native CLI for Zotero 7/8/9 desktop. 40+ commands across four backends.
Before You Start
Run zotero-cli --json app doctor first. If write_ready is false, follow next_steps (start Zotero / install plugin / enable Local API).
# Export one item in BibTeX
zotero-cli item export ITEM_KEY --format bibtex
# Export a standalone BibTeX file for downstream tools
zotero-cli export bib --items KEY1,KEY2 --output refs.bib
zotero-cli export bib --collection COLLECTION_KEY --output refs.bib
# Other formats: ris, biblatex, csljson, csv, mods, refer
zotero-cli item export ITEM_KEY --format ris
# Render citation preview (static HTML, not a refreshable DOCX field)
zotero-cli item citation ITEM_KEY --style apa
# Render bibliography preview (static HTML, not a refreshable DOCX field)
zotero-cli item bibliography ITEM_KEY --style apa
# Inspect citation fields inside a DOCX before mixing Zotero/EndNote/static references
zotero-cli --json docx inspect-citations manuscript.docx
# AI-authored DOCX citations must use real Zotero placeholders, then validate them
zotero-cli --json docx inspect-placeholders manuscript.docx
zotero-cli --json docx validate-placeholders manuscript.docx
# Static final DOCX: replace placeholders with ordinary text citations and bibliography
zotero-cli --json docx render-citations manuscript.docx --output manuscript-static.docx --force
# Preferred one-shot pipeline (auto: dynamic if LibreOffice ready, else static)
zotero-cli --json docx cite manuscript.docx --output manuscript-cited.docx --mode auto --force
# Dynamic final DOCX: use Zotero/LibreOffice fields when the user needs Refresh
zotero-cli --json docx doctor
zotero-cli --json docx insert-citations manuscript.docx --output manuscript-zotero.docx --force
### AI DOCX Citation Decision Flow
When the user provides a DOCX draft that contains citations, follow this explicit branch:
- Ask for intent if mode is unclear:
- "Do you want static references (final text now), or dynamic references (refreshable in Zotero/LibreOffice)?"
- Preferred default for agents:
- `zotero-cli --json docx cite <docx> --output <final.docx> --mode auto --force`
- If static is explicitly requested:
- `zotero-cli --json docx cite <docx> --output <final.docx> --mode static --force`
- If dynamic is explicitly requested or user mentions later editing/refresh:
- `zotero-cli --json docx cite <docx> --output <final.docx> --mode dynamic --force`
- or lower-level: validate → doctor → insert-citations
- If dynamic conversion returns environment errors:
- do not retry blindly
- report exact error context from `docx doctor`/`docx zoterify-probe`
- offer fallback to static mode (`render-citations`)
Keep only user-facing outputs:
- input placeholder DOCX
- final converted DOCX
- debug artifacts only if user explicitly asked for `--debug-dir`
Behavior note:
- `item citation` and `item bibliography` are static previews and must **not** be used as a replacement for DOCX writing conversion.
- `docx prepare-zotero-import` remains experimental and should not be called in normal user workflows.
When drafting DOCX content with AI, never invent final static citations such as
(Author, 2024) unless the user explicitly asks for static prose. Insert
{{zotero:ITEMKEY}} or {{zotero:KEY1,KEY2}} placeholders from real Zotero
items and validate the document before handoff. When the user asks to insert
citations without specifying a mode, ask whether they want static citations
(docx render-citations, simplest) or dynamic Zotero fields
(docx insert-citations, refreshable but requires LibreOffice).
PDF Management
# Attach a local PDF to an existing item
zotero-cli item attach ITEM_KEY /path/to/paper.pdf
# Zotero-only find PDF
zotero-cli --json item find-pdf ITEM_KEY
# Cascade: Zotero → Unpaywall → EuropePMC → bioRxiv → arXiv
zotero-cli --json item fetch-pdf ITEM_KEY --sources zotero,unpaywall,epmc,biorxiv,arxiv
# Batch cascade for a collection (JSONL progress optional)
zotero-cli --json collection fetch-pdfs COLLECTION_KEY --limit 20 --jsonl-progress --resume
Use --json flag on the root command for machine-readable JSON output:
zotero-cli --json item find "query"
Without --json, output is human-readable text.
Important Constraints
All platforms: Works on macOS, Windows, and Linux with the JS Bridge plugin installed.
Zotero desktop must be running: This is a hard prerequisite (not optional). Use zotero-cli --json app doctor / app launch if it is closed. Do not invent cloud-only or read-only degraded workflows.
JS Bridge plugin required: Install via zotero-cli app install-plugin. Once installed, all JS bridge commands work silently.
Semantic search: Requires ZOTERO_EMBED_API, ZOTERO_EMBED_MODEL, and ZOTERO_EMBED_KEY environment variables, plus a pre-built vector index at ZOTERO_VECTOR_DB.
Item references: Most commands accept a Zotero item key (8-char alphanumeric like 9LPV3KTS), title fragment, or numeric ID.
Collection references: Accept collection key or numeric ID.
zotero-cli import doi "10.xxxx/yyyy"# Note the item key from output, then:
zotero-cli item attach ITEM_KEY /path/to/paper.pdf
"What papers in collection X are missing PDFs?"
zotero-cli --json collection stats COLLECTION_KEY
# Shows total vs withPDF vs noPDF count# Then batch-find:
zotero-cli collection find-pdfs COLLECTION_KEY
"Find papers similar to one I'm reading"
zotero-cli --json item similar ITEM_KEY --top-k 10
Version
1.2.1+ (see package __version__ / PyPI). Roadmap: repo docs/ROADMAP.md.