Skip to main content

A read-only CLI for browsing and exporting a Zotero library

Project description

zotcli (zot)

alt text

A "crazy" good read-only command-line interface for your local Zotero library. Queries zotero.sqlite directly — no Zotero app running, no API key, no internet required. Never writes to the database.

Library stats on this machine: 3,771 items · 200 collections · 3,201 tags · 6.2 GB storage


Installation

pip install zotcli

Verify:

zot --help

The database at ~/Zotero/zotero.sqlite is auto-detected on WSL. Override anytime with --db PATH.


Repository layout

zotcli/
├── PLAN.md                          # Original design document
├── SKILL.md                         # Agent skill descriptor
├── pyproject.toml                   # Package metadata and dependencies
├── docs/
│   └── commands.md                  # Full command reference
├── src/
│   └── zotcli/
│       ├── __init__.py
│       ├── __main__.py              # python -m zotcli entrypoint
│       ├── db.py                    # Read-only SQLite connection + auto-discovery
│       ├── config.py                # TOML config (~/.config/zotcli/config.toml)
│       ├── models.py                # Pydantic v2 models: Item, Collection, Creator, Attachment, Note
│       ├── queries/
│       │   ├── items.py             # Core item fetch (_build_items — fields, creators, tags,
│       │   │                        #   collections, attachments, notes in one go)
│       │   ├── collections.py       # Collection tree queries
│       │   ├── attachments.py       # Attachment path resolution helpers
│       │   ├── tags.py              # Tag queries
│       │   └── search.py           # Field search, author search, DOI, year, fulltext
│       ├── export/
│       │   ├── json_.py             # Full-fidelity JSON dump
│       │   ├── csv_.py              # Flat CSV (one row per item)
│       │   ├── bibtex.py            # BibTeX with auto citation keys
│       │   └── markdown.py          # Markdown table report
│       └── cli/
│           ├── main.py              # Root Click group + global options
│           ├── render.py            # Shared Rich helpers (tables, panels, trees)
│           ├── collections.py       # `zot collections` subcommands
│           ├── items.py             # `zot items` subcommands
│           ├── attachments.py       # `zot attachments` subcommands
│           ├── search.py            # `zot search`
│           ├── stats.py             # `zot stats` subcommands
│           └── export.py            # `zot export` subcommands
└── tests/
    ├── conftest.py                  # In-memory SQLite fixture with seeded test data
    ├── test_db.py                   # Database layer tests
    ├── test_queries.py              # Query layer tests (items, collections, search, tags)
    ├── test_export.py               # Export format tests (JSON, CSV, BibTeX, Markdown)
    └── test_cli.py                  # CLI integration tests via CliRunner

Architecture

CLI layer  (cli/)
    ↓  Click commands call query functions
Query layer  (queries/)
    ↓  Batch SQL via sqlite3.Row
Database layer  (db.py)       ← read-only URI: file:zotero.sqlite?mode=ro
    ↓
zotero.sqlite

Every item fetch runs 6 batched queries in one call — fields, creators, tags, collection memberships, attachments (with resolved absolute paths), and notes — so all data is available everywhere without extra round-trips.


Global options

These go before the subcommand:

zot [--db PATH] [--library ID] [--format table|json|csv] [--no-color] <command>

Examples with output

zot stats — library overview

zot stats
   Library Summary
┌─────────────┬──────┐
│ Items       │ 3771 │
│ Collections │  200 │
│ Tags        │ 3201 │
│ Creators    │ 3959 │
└─────────────┴──────┘
       Items by Type
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Type             ┃ Count ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ annotation       │  2188 │
│ journalArticle   │   864 │
│ conferencePaper  │   234 │
│ webpage          │   179 │
│ book             │    77 │
│ report           │    75 │
│ preprint         │    43 │
│ thesis           │    32 │
│ bookSection      │    25 │
└──────────────────┴───────┘
zot stats years
              Publications by Year
┏━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Year ┃ Count ┃ Bar                            ┃
┡━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 2026 │    10 │                                │
│ 2025 │    36 │ ██                             │
│ 2024 │   110 │ █████████                      │
│ 2023 │   361 │ ██████████████████████████████ │
│ 2022 │   144 │ ███████████                    │
│ 2021 │   120 │ █████████                      │
│ 2020 │   101 │ ████████                       │
│ 2019 │    96 │ ███████                        │
└──────┴───────┴────────────────────────────────┘
zot stats tags --top 10
           Top 10 Tags
┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Tag                   ┃ Items ┃
┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ Topology              │    89 │
│ Voltage measurement   │    77 │
│ Network topology      │    75 │
│ State estimation      │    65 │
│ Distribution networks │    53 │
│ thesis                │    50 │
│ Smart meters          │    48 │
│ notion                │    47 │
│ Real-time systems     │    46 │
│ _EndnoteXML import    │    38 │
└───────────────────────┴───────┘

zot collections — browse the library tree

zot collections list
Collections
├── 00_Reading Tracker (2)
│   ├── Read (12)
│   ├── Reading (15)
│   └── To Read (31)
├── Energy Management (6)
│   ├── AI based Energy Management (2)
│   ├── Demand Response (14)
│   │   └── Home Energy Management System (3)
│   ├── Energy Market (75)
│   ├── Energy Storage (4)
│   ├── Felixibility (8)
│   └── Power Flow (16)
├── PhD Research (...)
│   ├── Distribution Systems (...)
│   └── State Estimation (...)
└── ...
zot collections items "Energy Market"
                            Energy Market (73 items)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type               ┃ Title                               ┃ Authors      ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ RBUU6AM2  │ journalArticle     │ New coordination framework for      │ Hussain      │ 2023   │
│    │           │                    │ smart home peer-to-peer trading…    │ et al.       │        │
│  2 │ 8DE2V7ZZ  │ journalArticle     │ Integrating Distributed Flexibility │ Tsaousoglou  │ 2023   │
│    │           │                    │ into TSO-DSO Coordinated Markets…   │ et al.       │        │
│  3 │ GKG9XUBE  │ thesis             │ Adoption of Blockchain in European  │ Meyer        │ 2023   │
│    │           │                    │ Electricity Markets                 │              │        │
└────┴───────────┴────────────────────┴─────────────────────────────────────┴──────────────┴────────┘

Include all sub-collections recursively:

zot collections items "Energy Management" --recursive

zot items — inspect individual items

zot items list --limit 5
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type               ┃ Title                                       ┃ Authors     ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ L54VEEWV  │ journalArticle     │ Three-phase feeder parameter estimation…    │ Yang et al. │ 2026   │
│  2 │ B8CNX4LI  │ journalArticle     │ Coordinated State Estimation of Power…      │ Sharma      │ 2025   │
│  3 │ MXYF8V3J  │ journalArticle     │ Towards Digital Twin of Distribution…       │ Idlbi       │ 2026   │
│  4 │ YN89DKH4  │ book               │ 41st European Photovoltaic Solar Energy…    │             │ 2024   │
│  5 │ 5UFZMSLU  │ journalArticle     │ UNLOCKING DATA CENTRE HOSTING CAPACITY…     │ Numair      │ 2026   │
└────┴───────────┴────────────────────┴─────────────────────────────────────────────┴─────────────┴────────┘
zot items show 5UFZMSLU
╭────────────────── journalArticle #6439  5UFZMSLU ──────────────────╮
│ Title    UNLOCKING DATA CENTRE HOSTING CAPACITY AND FLEXIBILITY     │
│          THROUGH DYNAMIC CABLE RATING                               │
│ Authors  Numair, Mohamed; ElKholy, Ahmed M; Martins-Britto,         │
│          Amauri G; Hertem, Dirk Van; Vanin, Marta                   │
│ Year     2026                                                       │
│ abstractNote  The unprecedented pace of Distributed Energy          │
│               Resource (DER) integration and electr…               │
│ language      en                                                    │
│                                                                     │
│ Attachments                                                         │
│   ✓ Numair et al. - 2026 - UNLOCKING DATA CENTRE…pdf               │
│                                                                     │
│ Notes (1)                                                           │
│   • Annotations(2/25/2026) (Numair et al., 2026, p. 1) …           │
╰─────────────────────────────────────────────────────────────────────╯

zot search — find items

By title keyword:

zot search "bayesian" --field title
                                5 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors        ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ LVTG4KLQ  │ journalArticle  │ An Improved Recursive Bayesian Approach   │ Chen et al.    │ 2013   │
│    │           │                 │ for Transformer Tap Position Estimation   │                │        │
│  2 │ 6BR3CYQA  │ conferencePaper │ Bayesian distribution system state        │ Angioni et al. │ 2016   │
│    │           │                 │ estimation in presence of non-Gaussian…   │                │        │
│  3 │ K2YXXPX7  │ journalArticle  │ A Recursive Bayesian Approach for         │ Singh et al.   │ 2010   │
│    │           │                 │ Identification of Network Configuration…  │                │        │
│  4 │ CRJWMH2X  │ journalArticle  │ Real-Time Topology Estimation Using       │ Liu et al.     │ 2023   │
│    │           │                 │ Graph-Bank Transformer…                   │                │        │
│  5 │ TJH8CGUT  │ conferencePaper │ Bayesian Methods for the Identification   │ Brouillon      │ 2021   │
│    │           │                 │ of Distribution Networks                  │ et al.         │        │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴────────────────┴────────┘

By author name (queries the creators table, partial match):

zot search --author "Numair"
                               12 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors       ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ MDLX3G4P  │ conferencePaper │ A Proposed IoT Architecture for Effective │ Numair et al. │ 2020   │
│    │           │                 │ Energy Management in Smart Microgrids     │               │        │
│  2 │ W3P98AE9  │ conferencePaper │ On the UK smart metering system and value │ Numair et al. │ 2023   │
│    │           │                 │ of data for distribution system…          │               │        │
│  3 │ UIMHSHNV  │ journalArticle  │ Fault Detection and Localisation in LV    │ Numair et al. │ 2023   │
│    │           │                 │ Distribution Networks Using Smart Meter…  │               │        │
│  4 │ TAVRNAY6  │ bookSection     │ Infrastructure for the 4th Industrial     │ Numair et al. │ 2024   │
│    │           │                 │ Revolution Technologies                   │               │        │
│  5 │ 5UFZMSLU  │ journalArticle  │ UNLOCKING DATA CENTRE HOSTING CAPACITY…   │ Numair et al. │ 2026   │
│  … │ …         │ …               │ …                                         │ …             │ …      │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴───────────────┴────────┘

By DOI:

zot search --doi "10.1016/j.epsr.2020.106394"
                                1 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type           ┃ Title                                     ┃ Authors          ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ ZGYGL35J  │ journalArticle │ Preventative high impedance fault         │ Langeroudi       │ 2020   │
│    │           │                │ detection using distribution system…      │ et al.           │        │
└────┴───────────┴────────────────┴───────────────────────────────────────────┴──────────────────┴────────┘

By year range:

zot search --year 2023 --type conferencePaper
361 result(s)  [truncated to first 5 shown]
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors         ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ ZRF8IFPI  │ journalArticle  │ Fault Location Method for an Active       │ Zhao et al.     │ 2023   │
│    │           │                 │ Distribution Network Based on…            │                 │        │
│  2 │ G3USAIB9  │ journalArticle  │ PMU Measurements-Based Short-Term         │ Li et al.       │ 2023   │
│    │           │                 │ Voltage Stability Assessment…             │                 │        │
│  3 │ RBUU6AM2  │ journalArticle  │ New coordination framework for smart      │ Hussain et al.  │ 2023   │
│    │           │                 │ home peer-to-peer trading…                │                 │        │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴─────────────────┴────────┘

zot attachments — locate files

Get the PDF path for a single item:

zot attachments path 5UFZMSLU
~/Zotero/storage/RIB344FW/Numair et al. - 2026 - UNLOCKING DATA CENTRE HOSTING CAPACITY AND FLEXIBILITY THROUGH DYNAMIC CABLE RATING.pdf

List all attachments for an item (with existence check):

zot items attachments W3P98AE9
                       Attachments for W3P98AE9
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key      ┃ Type            ┃ Mode         ┃ Exists ┃ Path                                      ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ GKHSKIP4 │ text/html       │ imported_url │ ✓      │ …/storage/GKHSKIP4/10136487.html          │
│ 7PZKGWIJ │ application/pdf │ imported_url │ ✓      │ …/storage/7PZKGWIJ/Numair et al. - 2023…  │
└──────────┴─────────────────┴──────────────┴────────┴───────────────────────────────────────────┘

Find all missing attachments:

zot attachments list --missing

Open a PDF in the system viewer:

zot attachments open 5UFZMSLU
# Opening: ~/Zotero/storage/RIB344FW/Numair et al. - 2026 - ...pdf

zot export — export to files

BibTeX:

zot export bib --collection "Energy Market" --output refs.bib
@article{hussain_new_2023,
  title = {New coordination framework for smart home peer-to-peer trading…},
  author = {Hussain, Sadam and Azim, M. Imran and Lai, Chunyan and Eicker, Ursula},
  year = {2023},
  journal = {Energy},
  volume = {284},
  pages = {129297},
  doi = {10.1016/j.energy.2023.129297},
}

@article{tsaousoglou_integrating_2023,
  title = {Integrating Distributed Flexibility into TSO-DSO Coordinated Electricity Markets},
  author = {Tsaousoglou, Georgios and Junker, Rune and …},
  year = {2023},
  doi = {10.1109/TEMPR.2023.3319673},
}

CSV:

zot export csv --collection "Energy Market" --output refs.csv
item_id,key,item_type,title,year,doi,journal,…,author_1,author_2,…,tags
10,RBUU6AM2,journalArticle,New coordination framework…,2023,10.1016/…,Energy,…,"Hussain, Sadam","Azim, M. Imran",…,Smart grid;Flexibility
18,8DE2V7ZZ,journalArticle,Integrating Distributed Flexibility…,2023,10.1109/…,…

JSON (includes fully resolved attachment paths and notes):

zot export json --collection "Energy Market" --output refs.json
[
  {
    "item_id": 10,
    "key": "RBUU6AM2",
    "item_type": "journalArticle",
    "title": "New coordination framework for smart home peer-to-peer trading…",
    "year": "2023",
    "attachments": [
      {
        "key": "PXW7M26P",
        "content_type": "application/pdf",
        "file_exists": true,
        "absolute_path": "~/Zotero/storage/PXW7M26P/Hussain et al. - 2023 - …pdf"
      }
    ],
    "notes": [],
    "tags": ["Smart grid", "Distribution transformer", "Flexibility"],
    
  }
]

Markdown:

zot export markdown --collection "Energy Market" --output refs.md
zot export markdown --all --notes --output full-library.md   # include notes sections

Workflow: search → get attachment paths

Find all papers with "bayesian" in the title or authored by "Numair", then print the PDF path for each:

from zotcli.db import ZoteroDatabase
from zotcli.queries.search import search_items, search_by_author

DB = "~/Zotero/zotero.sqlite"

with ZoteroDatabase(DB) as db:
    bayesian = search_items(db, "bayesian", fields=["title"])
    numair   = search_by_author(db, "Numair")

    seen = set()
    for item in bayesian + numair:
        if item.item_id in seen:
            continue
        seen.add(item.item_id)
        for att in item.attachments:
            if att.file_exists and "pdf" in att.content_type.lower():
                print(f"{item.key}\t{att.absolute_path}")
LVTG4KLQ    ~/Zotero/storage/LVTG4KLQ/Chen2013_BayesianTap.pdf
5UFZMSLU    ~/Zotero/storage/RIB344FW/Numair et al. - 2026 - UNLOCKING DATA CENTRE…pdf
W3P98AE9    ~/Zotero/storage/7PZKGWIJ/Numair et al. - 2023 - On the UK smart metering…pdf
…

Running tests

python3 -m pytest tests/ -q
........................................
40 passed in 31s

Tests use an in-memory SQLite fixture seeded with synthetic Zotero data. No real database needed.


Configuration

Optional persistent config at ~/.config/zotcli/config.toml:

[database]
path = "~/Zotero/zotero.sqlite"
library_id = 1

[output]
default_format = "table"
color = true
page_size = 50

Safety

  • Database opened with sqlite3://…?mode=ro — the OS-level read-only URI flag makes writes impossible
  • WAL journal detection warns if Zotero is currently open (pending writes may not be visible yet)
  • No network calls, no Zotero API, no authentication

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

zotcli-0.1.1.tar.gz (215.7 kB view details)

Uploaded Source

Built Distribution

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

zotcli-0.1.1-py3-none-any.whl (34.3 kB view details)

Uploaded Python 3

File details

Details for the file zotcli-0.1.1.tar.gz.

File metadata

  • Download URL: zotcli-0.1.1.tar.gz
  • Upload date:
  • Size: 215.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zotcli-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1b269f18c610c44bbb4a555aee905923d6cb62771c69a59f0f4613332136c873
MD5 bbeb7d5145ab092a0132d4336e01dad6
BLAKE2b-256 3f10cb6e8ee16f4a155dc2399e84c30d69e4a96e7ad091cb54118102b1bcd8dc

See more details on using hashes here.

File details

Details for the file zotcli-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: zotcli-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 34.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zotcli-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5d019f13b34d9437a6f5b65631e17796af034b426f8f6af3c1ce66f69c725b80
MD5 69efbfc181feb5caf612ae8209d07229
BLAKE2b-256 f65859bea17c6ef7c902fb266111a7b1acc334fe7ea1f8790a9dc83c6d77507c

See more details on using hashes here.

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