Skip to main content

Zotero Project Manager (zpm)

Zotero Project Manager 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.

Right-click a collection to use:

Zotero Project Manager
    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.

Native links (1.2.0)

Right-click a collection, paper record, or PDF attachment and choose Zotero Project Manager → 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.

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.

Zotero Project Manager is released under the MIT License.

For a paper inside a collection, Zotero Project Manager → 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.2.0

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.2.0
File Size Uploaded
zotero_project_manager-1.2.0.tar.gz 105.9 kB Details

Built distribution (wheel)

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

Total release size: 151.6 kB

Release files / zotero_project_manager-1.2.0.tar.gz

Download URL zotero_project_manager-1.2.0.tar.gz
Size 105.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ae4a1be003cf9f50e98bb2c0d5fafbc8e062be3d76f5452e97b010fbe657422f
BLAKE2b-256 checksum
How to use checksums
d9edd27e67e7b9a31d207153807db670ba93f54391f6b806c9351c4a363519c1
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 14, 2026.

Transparency log

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

Download URL zotero_project_manager-1.2.0-py3-none-any.whl
Size 45.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
69184e8344d7c22768dc5e18fefd543bb51ddc32066f939ca49928f49f79d25d
BLAKE2b-256 checksum
How to use checksums
d48d336b4b0b820b6ec6df1526c048298105ede4e6050c2a950f1fe0a154e360
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 14, 2026.

Transparency log

Release history Release notifications | RSS feed

1.3.1

2 release files

1.3.0

2 release files

This release

1.2.0 This release

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