Skip to main content

ZPM — Zotero Project Manager

ZPM exports Zotero collections into clean, ordinary research folders. Zotero remains the source of truth: the project reads Zotero data and copies attachments outward without modifying the library, database, or original files.

Use the self-contained Zotero 9 plugin for native note links and interactive exports, or the Python CLI for batch operations, automation, verification, and safe pruning.

Choose an interface

Capability Zotero plugin Python CLI
PDFs and optional non-PDF attachments Yes Yes
Metadata, annotations, notes, and cached annotation images Yes Yes
Recursive hierarchy, filename presets, and three annotation layouts Yes Yes
Incremental SHA-256 synchronization and legacy workspace migration Yes Yes
Multiple root collections in one operation One at a time Yes
Dry-run, status, pruning, full verification, and workspace adoption No Yes
Diagnostics, named projects, saved configuration, and automation No Yes
Runs without Python or direct SQLite access Yes No

Both interfaces produce the same managed workspace format. The plugin stays focused and conservative; the CLI provides explicit administrative controls.

Zotero 9 plugin

Exports run inside Zotero and do not require Python, Homebrew, pipx, or an executable path. Exports create and update local workspaces without launching other apps, running AppleScript, or uploading files.

Download the XPI from the latest GitHub release, then open Zotero → Tools → Plugins → gear menu → Install Plugin From File…. Existing installations can be upgraded in place.

Menu names below use ZPM starting with 1.3.1. Versions through 1.3.0 display Zotero Project Manager instead.

Right-click a collection to use:

ZPM
    Copy Link → Org / Markdown / Zotero URI
    Export → Collection / Collection + Annotations
    Settings…

Settings control:

  • the default export folder;
  • whether non-PDF attachments such as README.md, text, images, and data are included;
  • attachment filename ordering;
  • separate, sidecar, or bundle annotation layout.

The first export asks for a destination if no valid default exists. Zotero can install future releases automatically when Update Add-ons Automatically is enabled in the Plugins gear menu; Check for Updates provides a manual check.

Right-click a collection, paper record, or PDF attachment and choose ZPM → Copy Link. Copy Org links for Emacs, Markdown links for Obsidian, or plain Zotero URIs. The PDF reader also offers page and annotation links. Explicit Copy Multiple Links commands copy selected paper records and PDFs, one per line. Only My Library is supported; unsupported entries disable copying and batches never skip invalid entries. These commands use Zotero’s native clipboard and need neither Actions & Tags nor zotxt, bibliography styles, or an export folder.

See installation, Emacs setup, examples, and testing. Version 1.2.0 includes these native link commands.

Emacs collection picker (1.3.0)

From an Org note, run M-x zpm-insert-paper-link or M-x zpm-open-paper to browse papers in the selected Zotero collection by author, year, and title. Remember a collection per note with zpm-remember-collection. This local, read-only bridge requires plugin 1.3.0 or newer and Zotero's local API permission. Existing native links and exports remain unchanged. See the beginner picker guide. Version 1.3.0 is the stable release of the picker.

One workspace, your choice of app

Export a collection once and use its standard folder wherever you need it. For example, selecting My-AI → Agentic_AI exports to Agentic_AI/ and preserves its descendants inside that workspace. Re-exporting updates the same workspace. Choose Export Collection + Annotations to include annotations and child notes.

Open the target app yourself and select the exported files you want to use. zpm has no app-specific Send commands, stored notebook-link UI, automatic app indexing, uploading, or separate Notebook export format. The hidden .zpm/ directory is bookkeeping, not material to upload or import. You choose the files and compatible types in the destination app.

Stable 1.1.0 keeps the public 1.0.0 feature set and fixes Settings/Choose while adding concurrent-export protection. The experimental Gemini Notebook/DT4 preview integrations are not included; standard exports and naming/layout settings remain. Existing export folders (including old - NotebookLM folders), Google notebooks, DT4 records, and Zotero originals are not deleted or migrated. Old notebook-link preferences are left unused; the simplified plugin does not read or clear them. The earlier implementation remains in Git history.

The CLI no longer accepts --to, --notebook-url, --devonthink-group, --prepare-only, or --profile. Existing standard named projects still work. A saved project with export_profile = "notebooklm" is rejected with a migration message: review its output directory and layout, then remove that setting in its TOML config only if you want standard export. zpm never silently switches the project or rewrites the config on load.

See the Agentic_AI testing guide for installation and checks.

Python CLI

The CLI requires Python 3.11 or newer. Install it on macOS with Homebrew:

brew install sbilmis/tap/zpm

Or install the PyPI package with pipx:

brew install pipx
pipx install zotero-project-manager

Upgrade with brew upgrade zpm or pipx upgrade zotero-project-manager.

Quick start

List collections and export one recursively:

zpm list
zpm export "My-AI" --output ~/ResearchProjects

Include annotations and child notes:

zpm export "My-AI" --output ~/ResearchProjects --annotations

Preview changes, then safely prune files removed from Zotero:

zpm status "My-AI" --output ~/ResearchProjects --prune
zpm export "My-AI" --output ~/ResearchProjects --prune

Only manifest-owned files whose SHA-256 still matches are deleted.

Reusable projects and diagnostics

Save defaults or a named multi-collection project:

zpm config set --zotero-dir ~/Zotero --output ~/ResearchProjects
zpm project add ai "My-AI" "Claude" --annotations
zpm sync ai

Run a read-only readiness audit:

zpm doctor --output ~/ResearchProjects

Use zpm --help and zpm export --help for every command and option.

Workspace format

A typical export looks like this:

My-AI/
    Curie - 2024 - Paper title.pdf
    README.md
    Books/
        Author - 2023 - Book.pdf
    Annotations/
        Curie - 2024 - Paper title.md
    .zpm/
        manifest.json
        metadata.json
        INDEX.md
        export-summary.md

Generated control data lives under .zpm/, leaving ordinary project names such as README.md, INDEX.md, and metadata.json available for Zotero attachments.

The manifest supports incremental exports:

  • unchanged files are left alone;
  • new and changed attachments are copied;
  • missing or removed attachments are recorded without silently deleting prior copies;
  • identical files re-added under a new Zotero key are reconciled;
  • root-level manifest v1–v4 workspaces migrate under .zpm/ after a successful export.

Annotations and layouts

Annotation export includes highlights, comments, page labels, tags, child notes, and available cached image or ink previews. It is opt-in because research notes may contain private material.

Choose one of three layouts:

  • separate keeps generated Markdown under a parallel Annotations/ hierarchy;
  • sidecar places paper.annotations.md beside each PDF;
  • bundle creates one folder per paper containing the attachment and annotations.

The selected filename preset and layout are recorded in the manifest. Existing workspaces retain those settings to prevent surprising reorganizations.

Safety model

  • Zotero files, attachments, and annotation caches are never modified.
  • The CLI opens zotero.sqlite read-only with SQLite query-only protection.
  • The plugin reads through Zotero's in-process APIs and does not open SQLite directly.
  • Output paths inside the Zotero data directory are rejected.
  • Unmanaged workspaces and conflicting user files are not adopted silently.
  • Generated annotation and control files carry ownership markers.
  • Full verification and pruning require explicit CLI options.

Keep independent backups of important research data.

Development

git clone https://github.com/sbilmis/zotero-project-manager.git
cd zotero-project-manager
python -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/python -m pytest
node --test zotero-plugin/tests/*.test.cjs

Build the release XPI and verify its update-feed entry with:

.venv/bin/python scripts/build_zotero_plugin.py

Install dist/zpm-zotero-1.2.0.xpi using Zotero's Tools → Plugins → gear → Install Plugin From File…, or use the XPI from the matching GitHub release. The installed Homebrew/pipx release does not change when this checkout changes; use .venv/bin/python -m zotero_project_manager to run the CLI from this checkout. For unpublished development versions only, pass --development to build without a published feed entry. Release builds and CI verify the exact update-feed hash.

See CONTRIBUTING.md, PUBLISHING.md, the plugin guide, and CHANGELOG.md for focused development and release details.

ZPM is released under the MIT License.

For a paper inside a collection, ZPM → Copy Link in This Collection offers Org, Markdown, and Zotero URI formats that preserve that collection context. Ordinary item and PDF links remain unchanged.

Release files for zotero-project-manager 1.3.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 zotero-project-manager 1.3.1
File Size Uploaded
zotero_project_manager-1.3.1.tar.gz 119.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zotero-project-manager 1.3.1
File Interpreter ABI Platform
zotero_project_manager-1.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 165.4 kB

Release files / zotero_project_manager-1.3.1.tar.gz

Download URL zotero_project_manager-1.3.1.tar.gz
Size 119.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b1301fb6e5cf0afb2de7e341eb0c92460a845d5c60a4a7ed2e15d3ab9d991795
BLAKE2b-256 checksum
How to use checksums
2969ac841528d7f9ec57533e13e939c4ff0eb546cde649bb6576af01d32010e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / zotero_project_manager-1.3.1-py3-none-any.whl

Download URL zotero_project_manager-1.3.1-py3-none-any.whl
Size 46.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9c87fdcd3665ab28bffb71fd269b88c5b9f6a1e7310d07aed15be43bc1baf0d3
BLAKE2b-256 checksum
How to use checksums
2facef1901ff5d0b790f0a7543f2520fb2fa604065ac2240e5e2aaedb45436fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.3.1 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.8.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

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