zotero-claude-mcp
Integrates with Zotero to read the user's local Zotero database and zotero.org account, including group libraries. Provides tools for searching references and full-text PDFs, browsing collections and tags, retrieving attachments, generating citations in CSL styles, and creating items or adding notes via the web API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@zotero-claude-mcp find my PDFs about contact-angle hysteresis"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
zotero-claude-mcp
An MCP server that gives Claude access to your Zotero library — both the local database on your own machine and your zotero.org account, including group libraries.
Python standard library only. No pip install, no virtualenv, no dependencies to keep patched. If you have Python 3.9+, it runs.
What it does
Ask Claude things like "what do I have saved on contact-angle hysteresis?", "which of my PDFs mention level-set methods?", "summarise the abstracts in my Reading collection", or "cite these three in IEEE style" — and it reads your actual library instead of guessing or searching the web.
It can also open the PDFs: zotero_attachments returns real file paths, which Claude can
then read directly.
And it can organise the library for you — "put everything tagged FSW-voids into a new FSW
collection", "rename the tag ML to machine-learning", "add the DOI to this one", "move
these duplicates to the trash". Collections can be named in plain words (or as
Parent/Child); you never need to look up a key. These changes go through zotero.org and
reach the desktop app on its next sync.
Related MCP server: principia-mcp
Install
git clone https://github.com/ARHashemi/zotero-claude-mcp.git
cd zotero-claude-mcp
./install.shThat is the whole install. install.sh checks your Python, finds your Zotero library,
registers the server with Claude Code at user scope (so it works in every project and
session), and tells you what it found. It is safe to re-run.
Then restart Claude Code.
Nothing to configure for local use — no account, no API key, no paths. Your Zotero data directory is read from Zotero's own preferences, and your numeric user ID from the local database.
If your library lives somewhere unusual and is not found automatically, install.sh says so
and offers to take the path. You can also set it any time:
bin/zotero-mcp setup --data-dir=/path/to/your/ZoteroZotero shows that path under Settings -> Advanced -> Files and Folders.
Other MCP clients
Point any stdio-capable client at bin/zotero-mcp:
"mcpServers": {
"zotero": {
"command": "/absolute/path/to/zotero-claude-mcp/bin/zotero-mcp"
}
}Where things are looked for
Platform | Zotero profile | Default data directory |
Linux |
|
|
Linux (snap) |
|
|
Linux (flatpak) |
|
|
macOS |
|
|
Windows |
|
|
A custom directory set in Zotero is picked up automatically from its preferences, on every
platform. bin/zotero-mcp status reports which of these it used.
The two sources
Every read tool takes a source argument.
local (default) — reads zotero.sqlite from your Zotero data directory. Fast, works
offline, works whether or not Zotero is running, and is the only source that can return PDF
file paths.
Zotero holds an exclusive lock on that file while it runs, so the server reads from a
snapshot copy under ~/.cache/zotero-mcp/, refreshed automatically whenever the live
database changes. Nothing is ever written to your local Zotero files.
web — api.zotero.org with your API key. Needed for group libraries, for items that
have not synced to this machine, for real CSL citation formatting, and for all the write
tools. Writes appear in the desktop app (and in local reads) after Zotero's next sync.
Configuration
Everything is autodetected except the API key. The Zotero data directory and your numeric user ID are read from Zotero's own profile, so for local-only use there is nothing to configure.
To add a web API key — create one at https://www.zotero.org/settings/keys/new, then:
bin/zotero-mcp setup # prompts, hiding the key as you type
bin/zotero-mcp setup --key=... --user-id=... # or non-interactivelyThe prompt hides the key as you type and writes ~/.config/zotero-mcp/config.json with
mode 600. Every field is optional:
{
"api_key": "...",
"user_id": "YOUR_NUMERIC_USER_ID",
"data_dir": "~/Zotero",
"library_type": "user",
"default_source": "local"
}Environment variables override the file: ZOTERO_API_KEY, ZOTERO_USER_ID,
ZOTERO_DATA_DIR, ZOTERO_BASE_ATTACHMENT_PATH, ZOTERO_LIBRARY_TYPE,
ZOTERO_DEFAULT_SOURCE.
Give the key read/write permission if you want the write tools (saving items, notes, collections, tags, trash) to work; read-only is fine for everything else.
Tools
Tool | Purpose |
| find references by keyword, author, tag, type, year, collection |
| full record: every field, notes as plain text, attachment paths |
| search inside PDFs and notes, not just metadata |
| collection tree with item counts |
| items in a collection, optionally recursive |
| tags with item counts |
| recently added or modified |
| on-disk PDF paths, ready to read |
| citations in any CSL style (apa, ieee, nature, vancouver, …) |
| local libraries and zotero.org groups |
| configuration diagnostics |
Write tools — all go through the web API and need a key with write permission. Collections
can be named by key, by name, or by Parent/Child path.
Tool | Purpose |
| save a new reference, optionally into a collection |
| attach a note to an item, or a standalone note |
| edit fields, replace creators, add/remove tags on one item |
| add/remove tags on many items at once |
| rename (or merge) a tag across the library |
| remove tags from the whole library |
| move items to the trash, or restore them (never permanent) |
| new collection, optionally nested; no duplicates |
| rename or move a collection |
| delete an empty-of-subcollections collection (items are kept) |
| file items into a collection ( |
| take items out of a collection (items are kept) |
Write safety
Every write goes through the zotero.org API with version checks, so an edit made elsewhere in the meantime makes the write fail with a clear message rather than overwrite it.
Only the fields you change are sent; everything else on an item is left alone.
Nothing is deleted permanently:
zotero_trash_itemsuses Zotero's trash (restorable), and deleting a collection keeps its items.zotero_create_collectionreturns an existing collection of the same name instead of making a duplicate, andzotero_add_to_collectionskips items already filed.Claude is instructed to confirm before writing unless you asked for the change.
CLI
Useful for checking things without going through Claude:
bin/zotero-mcp status # diagnostics
bin/zotero-mcp setup # store API key / user ID
bin/zotero-mcp tools # list tools
bin/zotero-mcp tool zotero_search '{"query":"x"}' # run one tool
bin/zotero-mcp tool zotero_add_to_collection \
'{"keys":["ABCD2345"],"collection":"Reading","create":true}' # a write
bin/zotero-mcp # serve over stdio (what Claude runs)Privacy
Your library never leaves your machine unless you use source: "web", which talks to
zotero.org and nowhere else. The local database is only ever read, never written; every
change goes through zotero.org and reaches it by Zotero's normal sync. There is no telemetry and no third-party network code — the
only outbound requests in the codebase are to api.zotero.org.
The API key is stored only in ~/.config/zotero-mcp/config.json (mode 600), never in the
repository, and is never logged.
How the local backend works
It queries Zotero's SQLite tables directly (items, itemData, itemCreators,
collections, itemTags, itemAttachments, itemNotes) and uses the FTS5 index in
fulltext.sqlite for full-text search.
That schema is a Zotero implementation detail and can change between releases. The code is written against userdata schema v129 (Zotero 7); on a newer schema it prints a note to stderr and keeps going, rather than failing. Since every local query is read-only against a snapshot copy, a schema change can at worst produce wrong output — never a damaged library.
Zotero's own HTTP local API (localhost:23119/api, off by default) is not used; reading the
database directly works whether or not it is enabled.
Troubleshooting
"Zotero database not found" — run bin/zotero-mcp setup --data-dir=/your/path. Find the
real path in Zotero under Settings -> Advanced -> Files and Folders. bin/zotero-mcp status
shows where it looked and why.
Claude does not see the tools — restart Claude Code, then check claude mcp list.
Attachment shows FILE MISSING — the item's file has not synced to this machine yet;
open it once in Zotero, or use source: "web".
Full-text search finds nothing — only attachments Zotero has indexed are searchable. Check Settings → Search in Zotero.
License
MIT — see LICENSE.
Not affiliated with, endorsed by, or supported by Zotero (Corporation for Digital Scholarship) or Anthropic. "Zotero" and "Claude" are their respective trademarks, used here only to describe what this tool connects.
Available Tools
23 toolszotero_add_noteB
Attach a note to an existing Zotero item (or add a standalone note) via the web API. Requires a configured API key with write access.
Inputs: text (required), tags, library, parentKey.
zotero_add_to_collectionA
File existing items into a collection via the web API (items can be in several collections at once; this does not remove them from others). Works in batches, so pass all the keys in one call. Set create=true to make the collection if it doesn't exist.
Inputs: keys (required), collection (required), create, library.
zotero_attachmentsA
Resolve the on-disk paths of files (PDFs, HTML snapshots) attached to the given items, so the PDF can then be read with the Read tool. Local source only.
Inputs: keys (required), library, contentType.
zotero_bibliographyA
Format references as a bibliography or in-text citations in any CSL style (apa, chicago-note-bibliography, ieee, nature, vancouver, …). Uses zotero.org's citation processor when a web API key is configured; otherwise falls back to a plain author–date rendering from local metadata.
Inputs: keys (required), mode, style, locale, +1 more.
zotero_collection_itemsA
List the references in a collection, by collection key or (local) name.
Inputs: collection (required), limit, source, library, +1 more.
zotero_collectionsA
List the library's collections as a tree, with item counts and collection keys.
Inputs: source, library.
zotero_create_collectionA
Create a collection (folder) in the user's Zotero library via the web API, optionally nested under a parent. If a collection with the same name already exists under that parent, its key is returned instead of making a duplicate. Returns the collection key.
Inputs: name (required), parent, library.
zotero_create_itemA
Save a new reference to the user's Zotero library via the web API (it then syncs to the desktop app). Requires a configured API key with write access. Ask the user before writing unless they clearly asked you to save something.
Inputs: title (required), itemType (required), DOI, url, +8 more.
zotero_delete_collectionA
Delete a collection via the web API. The items in it are NOT deleted — they stay in the library and in any other collections. Refuses if the collection has subcollections. Always confirm with the user first.
Inputs: collection (required), library.
zotero_delete_tagsA
Remove tags from the whole library (from every item) via the web API. Items are untouched otherwise. Confirm with the user first.
Inputs: tags (required), library.
zotero_fulltext_searchA
Search the full text of PDFs and notes stored in the library (not just metadata), returning the parent references that contain the phrase. Use when the user asks which of their papers discuss or mention something.
Inputs: query (required), limit, source, library.
zotero_get_itemA
Fetch the complete record for one or more Zotero items by item key: every metadata field, all creators, tags, collections, attached notes (as plain text) and attachment file paths. Use after zotero_search when you need abstracts, DOIs, notes or the PDF path.
Inputs: keys (required), source, library.
zotero_librariesA
List available libraries: local libraries on this machine and group libraries on zotero.org.
Inputs: no named parameters.
zotero_recentA
List the most recently added or modified references — useful for 'what have I saved lately'.
Inputs: by, limit, source, library.
zotero_remove_from_collectionA
Take items out of a collection via the web API. The items themselves stay in the library.
Inputs: keys (required), collection (required), library.
zotero_rename_tagA
Rename a tag on every item that carries it (merging into the new name if it already exists), via the web API.
Inputs: tag (required), newName (required), library.
zotero_searchA
Search the user's Zotero library for references by keyword, author, tag, item type, year or collection. Returns a ranked list with title, authors, year, venue and the item key needed by the other tools. Use this first for any question about what is in the user's library or to find a paper they have saved.
Inputs: tag, mode, sort, year, +7 more.
zotero_statusA
Report how this connector is configured: data directory, item counts, whether the web API key works, and what to fix if something is missing.
Inputs: no named parameters.
zotero_tag_itemsA
Add and/or remove tags on many items at once via the web API.
Inputs: keys (required), add, remove, library.
zotero_tagsA
List tags used in the library with how many items carry each one.
Inputs: limit, source, library, contains.
zotero_trash_itemsA
Move items to the Zotero trash (recoverable), or restore them from it with restore=true, via the web API. Never deletes permanently. Confirm with the user first.
Inputs: keys (required), library, restore.
zotero_update_collectionA
Rename a collection and/or move it under another parent (or to the top level) via the web API.
Inputs: collection (required), name, parent, library.
zotero_update_itemA
Edit an existing item's metadata via the web API: set or clear any fields (title, date, DOI, abstractNote, volume, pages, extra, …), replace its creators, add or remove tags. Only the fields you pass are changed.
Inputs: key (required), fields, addTags, library, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 23 tools
Each tool targets a distinct resource or action: search vs fulltext search vs recent, item retrieval vs attachment path resolution, and separate collection/tag operations are clearly scoped. The descriptions reinforce the boundaries, so an agent should rarely misselect.
All tools share the zotero_ prefix and most action tools follow verb_noun (create_item, update_collection, rename_tag, trash_items). A few noun-only names like zotero_recent, zotero_attachments, and zotero_collections break the otherwise consistent pattern, but the convention remains predictable and readable.
23 tools is on the heavy end for an MCP server, though the Zotero domain legitimately spans items, collections, tags, notes, search, bibliography, and configuration. The count feels justified but is slightly beyond the ideal well-scoped range.
The tool surface covers the core library lifecycle thoroughly: search and retrieval, item creation/update/trash, notes, collection CRUD, tag management, bibliography generation, attachment resolution, and status diagnostics. There are no major dead ends or obvious missing operations for the stated purpose.
Maintenance
Related MCP Connectors
Zotero MCP server for Claude and ChatGPT: search, citations, safe writes, PDF passages and pages.
Connect Claude to your Platform7n workspaces: chat, links, work and decks. One-click OAuth.
Academic literature search, retrieval, and private library management on top of OpenAlex.
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Related MCP Servers
- AlicenseAqualityBmaintenanceConnects your Zotero research library with Claude and other AI assistants via the Model Context Protocol, allowing you to search your library, access content, discuss papers, get summaries, and analyze citations.357,494 PyPI5,838MIT
- FlicenseNot gradedqualityNot gradedmaintenanceEnables Claude to access and search a local Zotero library by querying metadata and providing direct paths to PDF files. This allows the model to browse research collections and natively read academic papers without requiring text extraction or manual exports.-
- FlicenseNot gradedqualityDmaintenanceGives Claude full read/write access to your Zotero reference library, enabling search, collection management, and article addition through natural language.-
- AlicenseNot gradedqualityCmaintenanceConnects Zotero to Claude Desktop, allowing Claude to read, search, and organize a user's Zotero library through local and web APIs.MIT