Manage Zotero reference libraries via the Web API. Search, list, add items by DOI/ISBN/PMID (with duplicate detection), delete/trash items, update metadata and tags, export in BibTeX/RIS/CSL-JSON, batch-add from files, check PDF attachments, cross-reference citations, find missing DOIs via CrossRef, and fetch open-access PDFs. Supports --json output for scripting. Use when the user asks about academic references, citation management, literature libraries, PDFs for papers, bibliography export, or Zotero specifically.
Interact with Zotero personal or group libraries via the REST API v3.
Requires two environment variables:
```
ZOTERO_API_KEY — Create at https://www.zotero.org/settings/keys/new
ZOTERO_USER_ID — Found on the same page (numeric, not username)
```
For group libraries, set `ZOTERO_GROUP_ID` instead of `ZOTERO_USER_ID`.
Optional env var for CrossRef/Unpaywall polite pool (improves DOI lookup success rate):
```
CROSSREF_EMAIL — Your email (optional; uses fallback if unset)
```
If credentials are missing, tell the user what's needed and link them to the key creation page.
All operations use `scripts/zotero.py` (Python 3, zero external dependencies).
```bash
python3 scripts/zotero.py <command> [options]
```
| Command | Description | Example |
|---------|-------------|---------|
| `items` | List top-level items | `zotero.py items --limit 50` |
| `search` | Search by query | `zotero.py search "cognitive load"` |
| `get` | Full item details + attachments | `zotero.py get ITEMKEY` |
| `collections` | List all collections | `zotero.py collections` |
| `tags` | List all tags | `zotero.py tags` |
| `children` | List attachments/notes for item | `zotero.py children ITEMKEY` |
| `add-doi` | Add item by DOI (dedup enabled) | `zotero.py add-doi 10.1234/example` |
| `add-isbn` | Add item by ISBN (dedup enabled) | `zotero.py add-isbn 978-0-123456-78-9` |
| `add-pmid` | Add item by PubMed ID | `zotero.py add-pmid 12345678` |
| `delete` | Move items to trash (recoverable by default) | `zotero.py delete KEY1 KEY2 --yes` |
| `update` | Modify item metadata/tags | `zotero.py update KEY --add-tags "new"` |
| `export` | Export as BibTeX/RIS/CSL-JSON | `zotero.py export --format bibtex` |
| `batch-add` | Add multiple items from file | `zotero.py batch-add dois.txt --type doi` |
| `check-pdfs` | Report which items have/lack PDFs | `zotero.py check-pdfs` |
| `crossref` | Match citations vs library | `zotero.py crossref bibliography.txt` |
| `find-dois` | Find & add missing DOIs via CrossRef | `zotero.py find-dois --limit 10` |
| `fetch-pdfs` | Fetch open-access PDFs for items | `zotero.py fetch-pdfs --dry-run` |
```bash
python3 zotero.py add-doi "10.1093/jamia/ocaa037" --tags "review"
```
Duplicate detection: translates DOI to metadata, searches library by first author, compares DOI fields.
```bash
python3 zotero.py batch-add dois.txt --type doi --tags "imported"
```
Skips duplicates. Reports summary: added/skipped/failed.
```bash
python3 zotero.py export --format bibtex --output refs.bib
python3 zotero.py export --format csljson --collection COLLKEY
```
```bash
python3 zotero.py update ITEMKEY --add-tags "important" --remove-tags "unread"
python3 zotero.py update ITEMKEY --title "Corrected Title" --date "2024"
python3 zotero.py update ITEMKEY --doi "10.1234/example"
python3 zotero.py update ITEMKEY --url "https://example.com/paper"
python3 zotero.py update ITEMKEY --add-collection COLLKEY
```
```bash
python3 zotero.py delete KEY1 KEY2 --yes # Trash (recoverable, default)
python3 zotero.py delete KEY1 --permanent --yes # Permanent delete
```
```bash
python3 zotero.py crossref my-paper.txt
```
Extracts `Author (Year)` patterns from text and matches against library.
```bash
python3 zotero.py find-dois --limit 20
python3 zotero.py find-dois --apply
python3 zotero.py find-dois --collection COLLKEY --apply
```
Scans journalArticle and conferencePaper items missing DOIs, queries CrossRef, and matches
by title similarity (>85%), exact year, and first author last name. Dry run by default — use
`--apply` to write. Only patches the DOI field; never touches other metadata. 1s delay between
CrossRef requests (polite pool with mailto).
```bash
python3 zotero.py fetch-pdfs --dry-run --limit 10
python3 zotero.py fetch-pdfs --limit 20
python3 zotero.py fetch-pdfs --download-dir ./pdfs
python3 zotero.py fetch-pdfs --upload --limit 10
python3 zotero.py fetch-pdfs --sources unpaywall,semanticscholar
```
Tries three legal OA sources in order: Unpaywall → Semantic Scholar → DOI content negotiation.
By default creates linked URL attachments (no Zotero storage quota needed). Use `--upload` for
full S3 upload to Zotero storage. Use `--download-dir` to also save PDFs locally.
**Sources:** `unpaywall`, `semanticscholar`, `doi` (default: all three)
**Rate limits:** 1s between Unpaywall/Semantic Scholar requests, 2s between DOI requests.
```bash
python3 zotero.py --json items --limit 100 | jq '.items[].DOI'
python3 zotero.py --json get ITEMKEY | jq '.title'
```
Leave a review
No reviews yet. Be the first to review this skill!