Pyzotero: An API Client for the Zotero API
Quickstart
uv add pyzoteroorpip install pyzoteroorconda install conda-forge::pyzotero- You'll need the ID of the personal or group library you want to access:
Your userID for use in API calls
- For group libraries, the ID can be found by opening the group's page: https://www.zotero.org/groups/groupname, and hovering over the group settings link. The ID is the integer after /groups/
- You'll also need† to get an API key [here][2]
- Are you accessing your own Zotero library?
library_typeis'user' - Are you accessing a shared group library?
library_typeis'group'.
`` python
from pyzotero import Zotero
zot = Zotero( library_id, library_type, api_key ) # local=True to use a running Zotero instead of the web API items = zot.top(limit=5)
we've retrieved the latest five top-level items in our library
we can print each item's item type and ID
for item in items: print(f"Item: {item['data']['itemType']} | Key: {item['data']['key']}")python from pyzotero import Zotero# Documentationlocal=TrueFull documentation of available Pyzotero methods, code examples, and sample output is available on [Read The Docs][3].
Local Zotero API
Passing
directs Pyzotero at a running Zotero installation instead of the web API. Reads do not require authentication; writes require consent via a dialog in Zotero, and a Zotero version that supports local writes:
zot = Zotero("0", "user", local=True) auth = zot.authorize_local("My Application") # Zotero prompts the user zot.create_items([item])
bashpyzotero search -q "machine learning" --json pyzotero search -q "climate change" --fulltext pyzotero listcollections pyzotero authorize --app-name "My tool" # store a local API key, which the write commands need pyzotero createitem items.json --collection FD9AUNP2 --tag "to read"A key granted with "Always Allow" can be stored and passed back later aslocal_api_key. Versions and keys are scoped to a single Zotero instance, identified byzot.server_id. See the [local API documentation][12] for how this works, how-to guides, and reference material.uv add pyzoteroInstallation
- Using [uv][11]:
pip install pyzoteroUsing [pip][10]: conda install conda-forge::pyzoteroUsing Anaconda: Pyzotero also provides an optional CLI and MCP server for working with a local Zotero library. Both require Zotero >= 7 (>= 10 for local writes) with local API access enabled: Zotero > Settings > Advanced > "Allow other applications on this computer to communicate with Zotero". Both are read-only unless you runpyzotero authorize, which stores a local API key. Both console scripts are installed whichever extra you choose.uv add "pyzotero[cli]"Command-Line Interface
Pyzotero includes an optional CLI for searching your local Zotero library, adding items to it, and managing its collections.
- Using [uv][11]:
pip install "pyzotero[cli]"Using [pip][10]: uvx --from "pyzotero[cli]" pyzotero search -q "your query"Without installing:
json { "mcpServers": { "zotero": { "command": "pyzotero-mcp" } } }Runpyzotero --helpfor the full list of commands, and see the [CLI documentation][13] for details of the write commands, search behaviour, and output formats.uv add "pyzotero[mcp]"MCP Server
Pyzotero includes an optional MCP server that exposes your local Zotero library and Semantic Scholar integration as tools.
- Using [uv][11]:
pip install "pyzotero[mcp]"Using [pip][10]: uv tool install "pyzotero[mcp]"As a standalone tool: Add it to your Claude Desktop configuration:
bash git clone git://github.com/urschrei/pyzotero.git cd pyzotero git checkout mainThe server is read-only by default. Starting it with--enable-writesregisters tools that create and modify items, notes and collections, add items by DOI, arXiv ID or ISBN (with open-access PDFs) or from BibTeX and CSL JSON, and merge duplicates;--enable-deletesadditionally registers permanent deletion.--groupselects a group library, and--transport streamable-httpserves over HTTP. See the [MCP server documentation][14] for the configuration, the full list of tools, and how the write tools behave.Development
Installing from Source
specify --dev if you're planning on running tests
uv sync `
Testing
Run
pytest . from the top-level directory. This requires the dev dependency group to be installed: uv sync --dev / pip install --group dev
Issues
The latest commits can be found on the [main branch][9], although new features are currently rare. If you encounter an error, please open an issue.
Pull Requests
Pull requests are welcomed. Please read the contribution guidelines. In particular, please base your PR on the
main` branch.
Versioning
As of v1.0.0, Pyzotero is versioned according to Semver; version increments are performed as follows:
- MAJOR version will increment with incompatible API changes,
- MINOR version will increment when functionality is added in a backwards-compatible manner, and
- PATCH version will increment with backwards-compatible bug fixes.
Citation
Pyzotero has a DOI:
You may also cite Pyzotero using CITATION.cff.
A sample citation (APA 6th edition) might look like:
Stephan Hügel, The Pyzotero Authors (2019, May 18). urschrei/pyzotero: Version v1.3.15. http://doi.org/10.5281/zenodo.2917290
License
Pyzotero is licensed under the [Blue Oak Model Licence 1.0.0][8]. See LICENSE.md for details.
[1]: https://www.zotero.org/support/dev/web_api/v3/start [2]: https://www.zotero.org/settings/keys/new [3]: http://pyzotero.readthedocs.org/en/latest/ [7]: https://nose2.readthedocs.io/en/latest/ [8]: https://opensource.org/license/blue-oak-model-license [9]: https://github.com/urschrei/pyzotero/tree/main [10]: http://www.pip-installer.org/en/latest/index.html [11]: https://docs.astral.sh/uv [12]: https://pyzotero.readthedocs.io/en/latest/#the-local-zotero-api [13]: https://pyzotero.readthedocs.io/en/latest/#command-line-interface-usage [14]: https://pyzotero.readthedocs.io/en/latest/#mcp-server † This isn't strictly true: you only need an API key for personal libraries and non-public group libraries.