Skip to main content

cli-anything-zotero

PyPI Python 3.10+ License GitHub release GitHub stars

Let AI manage your Zotero library.

中文文档 | English | Roadmap | TODO | Commands

MCP legacy notice: v0.9.5 is the final release with the zotero-mcp command and cli-anything-zotero[mcp] extra. New releases are CLI/SDK-first. Existing MCP users should pin pip install "cli-anything-zotero[mcp]==0.9.5" or use the legacy/mcp branch.


For Non-Programmers

This tool is designed to be used by AI, not memorized by you. After a simple install (~3 minutes), just talk to your AI assistant in plain language:

"Find papers about diabetes and kidney disease in my Zotero library"

"Import this DOI into my CKM collection: 10.1038/s41586-024-07871-6"

"Export all papers in my thesis collection as BibTeX"

"Find PDFs for items in my review collection that are missing them"

All you need to do:

  1. Follow the Installation steps below
  2. Tell your AI assistant (Claude Code, Cursor, etc.) what you need
  3. That's it

What It Does

Built on CLI-Anything by HKUDS, this tool gives AI agents full access to your local Zotero library through a JS Bridge — a lightweight Zotero plugin that exposes a privileged JavaScript endpoint.

Prerequisite: the Zotero desktop app must be running. This is intentional — we automate the local client (Connector, Local API, CLI Bridge), not a cloud-only API substitute.

Key capabilities:

  • Search & browse — keyword search, full-text PDF search, collection tree, tags
  • Import — from DOI, PMID, RIS/BibTeX files, or JSON
  • Export — BibTeX, CSL-JSON, RIS, CSV, formatted citations
  • PDF management — attach files, auto-find PDFs online, search annotations
  • Write operations — update metadata, manage tags, add notes, trigger sync
  • DOCX citations — turn {{zotero:ITEMKEY}} placeholders into static text or refreshable Zotero fields (see below)
  • Advanced — execute arbitrary Zotero JS, semantic search with local embeddings, AI analysis

All write operations run locally through the JS Bridge — no API key or internet connection required.

DOCX citations: static vs dynamic

AI-authored drafts should use placeholders such as {{zotero:ITEMKEY}} or {{zotero:KEY1,KEY2}}, then convert them with the docx commands.

Mode Command Output Extra software
Static (default for simple finals) docx render-citations or docx cite --mode static Plain-text citations + static bibliography No. Only pip install + JS Bridge + running Zotero (Local API).
Dynamic (refreshable fields) docx insert-citations or docx cite --mode dynamic Real Zotero fields in Word/LibreOffice + refreshable bibliography Yes — extra stack required (see table below).
Auto docx cite --mode auto Picks dynamic if the stack is ready, else static Same as dynamic when available

Dynamic mode is optional and is not installed by pip alone. You also need:

Requirement Why
Zotero Desktop (running) Source library + word-processor integration
CLI Bridge plugin (zotero-cli app install-plugin) Local privileged bridge used by conversion
LibreOffice Opens/saves the DOCX during field insertion
Zotero LibreOffice plugin Creates refreshable citation/bibliography fields

Check the machine before relying on dynamic mode:

zotero-cli --json docx doctor

If doctor reports missing LibreOffice / the LO add-in / Bridge, use static mode (or install the missing pieces). On macOS the full dynamic path is tested end-to-end; on Windows/Linux, doctor works but auto open/save may still need manual LibreOffice interaction until verified.

One-shot when you are unsure:

zotero-cli --json docx cite draft.docx --output draft-cited.docx --mode auto --force

CLI-First Usage

cli-anything-zotero is now maintained as a CLI/SDK-first tool. The primary interface is the zotero-cli shell command, which works well for Codex, Claude Code, Cursor, shell scripts, and other agents that can run terminal commands.

For legacy MCP users, install the frozen MCP release explicitly:

pip install "cli-anything-zotero[mcp]==0.9.5"

The legacy/mcp branch and the v0.9.5 release remain available, but MCP receives no new feature maintenance after that line.


Installation

Prerequisites: Python 3.10+, Zotero 7+ (running).

Step 1: Install the package

pip install cli-anything-zotero

This installs the zotero-cli command. The old cli-anything-zotero command remains as a compatibility alias.

Step 2: Install the JS Bridge Plugin (one-time, both modes)

zotero-cli app install-plugin

First install requires manual steps in Zotero:

  1. The command generates a .xpi file and prints its path
  2. In Zotero: Tools → Plugins → gear icon → Install Plugin From File...
  3. Select the .xpi file, then restart Zotero

After the first install, future upgrades via app install-plugin are automatic.

Upgrading to Zotero 10: bridge versions up to 1.2.1 only declare support for Zotero 7–9, so Zotero 10 disables them. Upgrade to 1.2.2 or later and repeat the manual install above once; automatic upgrades work again afterwards.

For existing users upgrading to the dynamic DOCX citation workflow, update both the Python package and the Zotero bridge plugin:

python -m pip install -U cli-anything-zotero
zotero-cli app install-plugin
# restart Zotero
zotero-cli app plugin-status
zotero-cli docx doctor

Step 3: Set up your AI client

No client-specific setup is required. Tell your AI assistant that zotero-cli is available; it can run zotero-cli --help to discover commands.

Verify it works:

zotero-cli app ping
zotero-cli js "return Zotero.version"

Troubleshooting

Problem Solution
Cannot resolve Zotero profile directory Launch Zotero at least once first
Plugin not appearing Restart Zotero after installing the .xpi
endpoint_active: false Plugin failed to load — reinstall via Zotero UI
No endpoint found after a Zotero major upgrade Zotero disabled the bridge as incompatible; zotero-cli app doctor reports app_disabled. Upgrade cli-anything-zotero, run zotero-cli app install-plugin, then install the printed .xpi once by hand (Tools → Plugins → gear → Install Plugin From File...) and restart Zotero. Automatic upgrade cannot work here because it needs the live bridge
Windows: pip not recognized Close and reopen PowerShell after installing Python

Usage (CLI Mode)

Search & Browse

zotero-cli item find "machine learning"
zotero-cli item search-fulltext "CRISPR"
zotero-cli collection tree

Import

# Preferred agent ingest
zotero-cli --json add doi "10.1038/s41586-024-07871-6" --tag "review" --fetch-pdf
zotero-cli --json add arxiv 2602.02093 --collection COLLECTION_KEY
zotero-cli --json add file ./paper.pdf
zotero-cli --json add bibtex ./refs.bib --collection COLLECTION_KEY

# Lower-level import still available
zotero-cli import doi "10.1038/s41586-024-07871-6" --no-translator
zotero-cli --json item fetch-pdf ITEM_KEY --sources zotero,unpaywall,arxiv
zotero-cli --json collection fetch-pdfs COLLECTION_KEY --limit 20 --jsonl-progress

# DOCX one-shot citations
zotero-cli --json docx cite draft.docx --output draft-cited.docx --mode auto --force

# Audit recent write ops
zotero-cli --json audit tail --limit 20

Library hygiene

# Find duplicate clusters. Matches on DOI, and on normalized title confirmed by
# a shared creator surname and an agreeing year. Each copy reports its
# attachment counts and its Better BibTeX citation key.
zotero-cli --json item duplicates --limit 20
zotero-cli --json item duplicates --year-tolerance 0   # exact year agreement only
zotero-cli --json item merge KEEP OTHER1               # dry-run; --confirm applies

Clusters whose copies carry more than one pinned citation key are flagged with citation_key_conflict: true. Merging those silently orphans whichever key your manuscript already cites, so resolve the key before merging.

Deleting things

zotero-cli item delete ITEM_KEY --confirm     # -> trash. Reversible.
zotero-cli item restore ITEM_KEY              # <- back out of the trash
zotero-cli collection delete COLLECTION_KEY --confirm   # with its subcollections
zotero-cli collection restore COLLECTION_KEY            # brings the subcollections back too

delete moves things to the Zotero trash, exactly as the Delete key does in the Zotero UI. Trashed items keep their keys and stay recoverable until you empty the trash, which the CLI never does for you. collection delete --delete-items also trashes the items of the collection and of every subcollection; collection restore leaves those items in the trash, as the Zotero UI does, so restore them with item restore.

Permanent erasure is a separate path and bypasses the trash entirely:

zotero-cli item delete ITEM_KEY --permanent --yes-erase

--permanent prompts before erasing even when --confirm is given; only the explicit --yes-erase suppresses that prompt. --confirm is the flag people paste into scripts out of habit, so it is deliberately not the flag that can destroy anything.

Read & Export

zotero-cli item get ITEM_KEY
zotero-cli item find "keyword" --scope fields
zotero-cli item export ITEM_KEY --format bibtex
zotero-cli export bib --items KEY1,KEY2 --output refs.bib
zotero-cli item citation ITEM_KEY
zotero-cli item context ITEM_KEY              # LLM-ready context
zotero-cli docx inspect-citations draft.docx  # detect Zotero/EndNote/static citation fields
zotero-cli docx validate-placeholders draft.docx
zotero-cli docx render-citations draft.docx --output draft-static.docx --force
zotero-cli docx doctor
zotero-cli docx insert-citations draft.docx --output draft-zotero.docx --force

For AI-authored DOCX workflows, use Zotero-bound placeholders such as {{zotero:ITEMKEY}} or {{zotero:KEY1,KEY2}}, then choose the final output mode (details and extra software requirements are under DOCX citations: static vs dynamic):

  • Static citations: docx render-citations replaces placeholders with ordinary citation text and appends a static bibliography. Easiest path; no LibreOffice. Cannot be refreshed by the Zotero word processor plugin.
  • Dynamic citations: docx insert-citations converts placeholders into real Zotero/LibreOffice fields and creates or updates a refreshable bibliography field. Needs LibreOffice + Zotero LO add-in + Bridge on top of Zotero Desktop.

AI agents should ask the user which mode they want when the request is ambiguous. If the user only wants a simple final DOCX and has not installed LibreOffice, prefer static citations. Always run docx doctor before promising dynamic conversion.

Recommended AI protocol:

  1. zotero-cli --json docx validate-placeholders <input.docx>
  2. If the user wants editable references / refresh support:
    • zotero-cli --json docx doctor
    • zotero-cli --json docx insert-citations <input.docx> --output <final.docx> --force
    • If conversion fails, report the failing layer from doctor and ask the user for next steps.
  3. If the user wants static output or dynamic is unavailable:
    • zotero-cli --json docx render-citations <input.docx> --output <final.docx> --force

Keep these files only as handoff artifacts:

  • Placeholder draft (<input.docx>)
  • Final converted draft (<final.docx>)
  • No intermediate DOCX should be exposed unless --debug-dir is explicitly requested.

Platform support for this optional workflow:

  • macOS: tested end-to-end with automatic open, conversion, save, and Word-compatible DOCX output.
  • Windows/Linux: the base CLI works, and docx doctor can report missing dependencies. Full automatic LibreOffice open/save for dynamic DOCX citations still needs real Windows/Linux desktop validation; users may need to open or save the LibreOffice document manually until platform automation is verified.

validate-placeholders, zoterify-preflight, and zoterify-probe are diagnostics for setup or failure cases. Add --debug-dir only when you want JSON artifacts for troubleshooting. docx prepare-zotero-import exists only as an experimental debugging command; it is not a supported writing workflow after Zotero 9 + LibreOffice testing. docx insert-citations and docx render-citations are the two supported outputs for AI-authored citation insertion. item citation and item bibliography render static previews; they are not refreshable Word/LibreOffice Zotero fields. BIB export is a separate export feature and is not part of the DOCX writing workflow.

Write & Manage

zotero-cli item update KEY --field title="New Title"
zotero-cli item tag KEY --add "important"
zotero-cli item tag KEY1 KEY2 KEY3 --add "reviewed"     # one bridge call for all keys
zotero-cli item attach KEY ./paper.pdf
zotero-cli item find-pdf KEY
zotero-cli note add KEY --text "My note"
zotero-cli sync

Bulk operations

# Tag everything a search returns, in one call
zotero-cli --json item find "graph" | jq -r '.[].key' | zotero-cli item tag --keys-from - --add reviewed

# Many write operations from one JSONL file, in one process
zotero-cli --json batch ops.jsonl --dry-run          # validate only, change nothing
zotero-cli --json batch ops.jsonl --jsonl-progress   # run, one result line per operation

ops.jsonl holds one operation per line:

{"op": "tag", "key": "ABCD1234", "add": ["reviewed"], "remove": ["unread"]}
{"op": "update", "key": "ABCD1234", "fields": {"extra": "checked 2026-11"}}
{"op": "note", "key": "ABCD1234", "file": "notes/ABCD1234.md"}
{"op": "add-doi", "doi": "10.1371/journal.pcbi.1003285", "collection": "COLLKEY1", "tags": ["to-read"], "fetch_pdf": true}
{"op": "add-pmid", "pmid": "32015507", "tags": ["to-read"]}

Every line is validated before anything runs, so a typo on one line does not leave the lines before it applied. Operations then run in order and a failed one does not stop the rest (pass --stop-on-error to stop). Consecutive tag lines go to Zotero in a single bridge call; with --op tag, lines can leave out "op". Note files ending in .md are read as Markdown, and relative paths resolve against the JSONL file. The exit code is 1 when any operation failed; a DOI imported without an open-access PDF still counts as done and is reported under partial.

Advanced

zotero-cli item search-annotations "risk"
zotero-cli item annotations KEY
zotero-cli item metrics KEY                   # NIH citation metrics
zotero-cli collection stats COLLECTION_KEY
zotero-cli js "return await Zotero.Items.getAll(1).then(i => i.length)"

Full command reference: docs/COMMANDS.md


Optional Features

These require extra services. Everything else works without them.

Any OpenAI-compatible /v1/embeddings endpoint (Ollama, LM Studio, OpenAI, etc.).

zotero-cli item build-index                            # one-time
zotero-cli item semantic-search "cardiovascular risk"
zotero-cli item similar ITEM_KEY
Variable Default Description
ZOTERO_EMBED_API http://127.0.0.1:8080/v1/embeddings Embedding API endpoint
ZOTERO_EMBED_MODEL nomic-embed-text Model name
ZOTERO_EMBED_KEY (empty) API key (if needed)

AI Analysis

export OPENAI_API_KEY=sk-...
zotero-cli item analyze ITEM_KEY --question "What are the main findings?"

Legacy MCP Users

MCP support is frozen at v0.9.5. To keep using the previous MCP server, install:

pip install "cli-anything-zotero[mcp]==0.9.5"

You can also use the legacy/mcp branch for source installs. Starting with v1.0.0, the maintained package installs only CLI/SDK surfaces and no longer provides the zotero-mcp command.

There are several great tools in the Zotero ecosystem. Each has different strengths depending on your use case:

cli-anything-zotero zotero-mcp zotero-cli-cc pyzotero-cli
Approach Local JS Bridge Web API + MCP Web API + CLI Web API + CLI
Best for Local-first, full control MCP-native workflows Agent-driven research Scripting & automation
Write ops Local (no API key) Via Web API Via Web API Via Web API
MCP support Legacy via v0.9.5 Yes 45 tools No
Terminal CLI Yes No Yes Yes
Zotero JS access Yes No No No
License Apache 2.0 MIT CC BY-NC 4.0 MIT

License

Apache 2.0

Metadata

Release files for cli-anything-zotero 1.4.1

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

Source distribution (sdist)

Source distribution for cli-anything-zotero 1.4.1
File Size Uploaded Provenance Actions
cli_anything_zotero-1.4.1.tar.gz 190.6 kB Without provenance Details for cli_anything_zotero-1.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cli-anything-zotero 1.4.1
File Interpreter ABI Platform Actions
cli_anything_zotero-1.4.1-py3-none-any.whl Python 3 none any Details for cli_anything_zotero-1.4.1-py3-none-any.whl

Total release size: 394.5 kB

Release files / cli_anything_zotero-1.4.1.tar.gz

Download URL cli_anything_zotero-1.4.1.tar.gz
Size 190.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6163e58148f8c5d249b4b7a1b0eeeae0144ae077d1a92e9c3a01a489d64cf172
BLAKE2b-256 checksum
How to use checksums
473698f156c2ded1e5d08903e8f48a492ce9380887b67dc22d5d6b274daaffb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / cli_anything_zotero-1.4.1-py3-none-any.whl

Download URL cli_anything_zotero-1.4.1-py3-none-any.whl
Size 203.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6cd3705f305311d70bed7cda3c1706e05bcbffbd5a94e1dd5e8416210904719b
BLAKE2b-256 checksum
How to use checksums
c683bf6ad9d4aacea7d10c4a420369ce3369f21089f6c73c738bc669d5e38edd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Security for cli-anything-zotero 1.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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