
Zotero Library Mcp
io.github.RaulSimpetruPublished by GitHub account RaulSimpetruv0.5.0Updated Oct 24, 2026
Add papers and books to Zotero by DOI, arXiv ID, or ISBN and manage your library
Overview
MCP server that lets an assistant add papers and books to a Zotero library by DOI, arXiv ID or ISBN, and search, organize and annotate the library.
- What you can do
- Add papers and books by DOI, arXiv ID or ISBN, in batches, or from manual metadata, with duplicate detection
- Search and browse the library, full text, recent or unfiled items, duplicates, attachments and item details
- Read items: full text, BibTeX export, PDF highlights and annotations, and notes
- Create, edit and delete notes, annotations and tags, including tag colors and library-wide renames
- Manage collections: create, nest, rename, move, add or remove items
- Attach, download and save files, verify items against CrossRef, and trash, restore or delete items
- When to use it
- Useful for researchers and students who keep a Zotero library and want an assistant to file new papers and books, look up what is already saved, export citations, or tidy collections, tags and annotations without switching apps.
- Requirements
- Runs locally as a Python package launched with uvx, so uv must be installed. Needs a Zotero account, a Zotero API key with read/write permissions (ZOTERO_API_KEY) and a library ID (ZOTERO_LIBRARY_ID). Optional WebDAV storage needs ZOTERO_WEBDAV_URL, ZOTERO_WEBDAV_USER and ZOTERO_WEBDAV_PASSWORD. Network access to Zotero, CrossRef, arXiv and Open Library. An HTTP transport exists for hosted clients.
Installation
In SourceWeft
- Open Zotero Library Mcp in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
zotero-library-mcp
An MCP server that lets Claude, Codex, and ChatGPT add papers and books to your Zotero library by DOI, arXiv ID, or ISBN — and manage your collections, tags, and items.
The server supports both MCP transports used by these clients:
- stdio (default) for Claude Code, Claude Desktop, Codex CLI/IDE, and the ChatGPT desktop app
- Streamable HTTP for a hosted ChatGPT app or any remote MCP client
Tools
Adding papers
add_paper_by_doi— Resolve a DOI via CrossRef and add the paper to Zotero (with duplicate detection)add_papers_by_dois— Batch-add up to 50 papers at onceadd_paper_by_arxiv_id— Add a preprint by arXiv ID (uses DOI when available, falls back to arXiv metadata)add_item_from_metadata— Create any supported Zotero item type from validated manual metadata
Adding books
add_book_by_isbn— Resolve an ISBN via Open Library and add the book to Zotero (with duplicate detection)
Searching & browsing
list_libraries— Discover the API key owner's personal library and shared group libraries, with IDs and key permissionssearch_library— Search your Zotero library by title, author, tag, etc., paginated viastart/limit(falls back to fuzzy matching when the exact search returns no results)get_item_details— View full metadata for any itemget_recent_items— List recently added itemsget_unfiled_items— Get items not in any collectionsearch_fulltext— Search Zotero metadata and indexed full textfind_duplicates— Find duplicate items by DOI, ISBN, or normalized titlelist_attachments— List every attachment and choose a specific PDF keyhealth_check— Verify library credentials, access, and storage configuration
Reading & annotating
get_item_fulltext— Return bounded plain text from Zotero's index or a PDF, without leaking temporary pathsget_bibtex— Read-only BibTeX/BibLaTeX export for items, a collection, or the full librarysave_bibtex— Save an export to an authorized local pathget_annotations— List all highlights and annotations on a paper's PDFcreate_annotation— Highlight a text passage in a PDF (searches for the exact text, creates a visible highlight in Zotero's reader, and returns a preview image for verification). Smart overlap handling: exact duplicates update the existing comment; sub-passages get a contrasting highlight color automatically.add_note— Add a note to an itemlist_notes,update_note,delete_note— Manage existing notesupdate_annotation,delete_annotation— Edit or remove annotations
File attachments
attach_file— Attach a local file over stdio or a ChatGPT file input over HTTPdownload_pdf— Return a remote-safe MCP file resourcesave_pdf— Save a PDF to an authorized local path
Collections
list_collections— List all collections (with nesting)create_collection— Create a new collection (optionally nested under a parent)get_collection_items— Browse items in a collection, paginated viastart/limitadd_to_collection— Add an existing item to a collectionremove_from_collection— Remove an item from a collection (keeps it in your library)rename_collection,move_collection— Reorganize collections
Tags
list_tags— List all tags in your libraryadd_tags— Add one or more tags to an item (with optional color)remove_tags— Remove tags from an itemdelete_tags— Delete tags from the entire libraryset_tag_color— Assign a color to a tag (appears in Zotero's tag selector)rename_tag— Rename a tag across all items in your libraryunset_tag_color— Remove a tag color without deleting the tag
Verification
verify_items— Re-check recent items against CrossRef to catch bad DOIs or title mismatches
Deleting
delete_item— Permanently delete an item from your librarydelete_collection— Permanently delete a collectiontrash_item,restore_item— Prefer reversible trash operations for ordinary cleanup
The server also exposes the standard read-only search and fetch tool shapes used by ChatGPT company knowledge and deep research.
Prerequisites
- A Zotero account
- A Zotero API key with write permissions: https://www.zotero.org/settings/keys
- Your Zotero library ID (shown on the same page, or in your profile URL)
- uv installed
Quick Start
Codex and the ChatGPT desktop app
Codex and the ChatGPT desktop app share MCP configuration on the same Codex host. Add the server once:
Then restart Codex or the ChatGPT desktop app. In Codex, use /mcp to confirm that zotero is connected. In ChatGPT desktop, open Settings → MCP servers to view the same server.
For WebDAV storage, add the three ZOTERO_WEBDAV_* values shown in the WebDAV example. If the desktop app cannot find uvx, replace it with the full path returned by which uvx.
You can also configure the server directly in ~/.codex/config.toml:
With env_vars, start Codex/ChatGPT from an environment that contains those variables. Use [mcp_servers.zotero.env] instead if you intentionally want to store their values in the config file.
Claude Code
Install it as a plugin (recommended):
On older Claude Code versions, run /plugin marketplace add RaulSimpetru/zotero-library-mcp
first, then /plugin install zotero@zotero-library-mcp. Claude Code asks for your
library ID and API key (plus optional WebDAV and Unpaywall settings) when you enable
the plugin, and keeps the API key and WebDAV password in your system keychain. To get
a new release, run /plugin marketplace update zotero-library-mcp, or turn on
auto-update for the marketplace in /plugin.
Plugin tools are named mcp__plugin_zotero_zotero__<tool> rather than mcp__zotero__<tool>;
update any permission rules that name the old tools. If you previously added the
server with claude mcp add, remove that entry (claude mcp remove zotero -s user)
so the two copies don't both run.
Or add it as a plain MCP server:
WebDAV setup
To use WebDAV file storage (e.g. Synology, Nextcloud), include the WebDAV variables:
Claude Desktop
Add this to your claude_desktop_config.json:
Note: Claude Desktop doesn't inherit your shell's PATH, so you need the full path to
uvx. Find it withwhich uvxin your terminal.
ChatGPT on the web (Apps SDK / developer mode)
ChatGPT web connects to an HTTPS Streamable HTTP endpoint. Start the server locally with the HTTP transport, then make it reachable through Secure MCP Tunnel or another authenticated HTTPS deployment:
The MCP endpoint is https://your-tunnel.example.com/mcp. Enable developer mode in ChatGPT, create a developer-mode app, and enter that URL as the MCP server URL. See OpenAI's Connect from ChatGPT guide for the current UI flow.
Security: The safest personal setup is OpenAI Secure MCP Tunnel with the MCP server bound to loopback. HTTP mode disables all server-path reads and writes by default.
attach_fileaccepts ChatGPT's authorized file object, whiledownload_pdfreturns an opaque MCP resource link. Safety annotations are approval hints, not an authorization boundary.
For a public deployment, configure an external OAuth 2.1 identity provider. The server validates JWT access tokens against its JWKS endpoint:
The authorization server must publish OAuth/OIDC discovery metadata, support the MCP OAuth 2.1 flow with PKCE, issue tokens for ZOTERO_MCP_OAUTH_RESOURCE, and include the configured scopes. See OpenAI's authentication guide. For testing behind an already authenticated gateway only, --allow-unauthenticated-http explicitly acknowledges an unauthenticated non-loopback listener.
This process still uses one server-side Zotero API key. Every authenticated MCP client can target libraries available to that key, including shared groups. Use a key scoped to the libraries intended for those clients. A true multi-user service must map the verified OAuth identity to separate Zotero credentials and enforce per-user authorization; that deployment architecture is intentionally outside this personal-server package.
If an HTTP deployment genuinely needs server paths, enable them only inside confined roots:
HTTP launch settings can also be supplied as environment variables:
Run standalone
Personal and shared group libraries
The environment variables select the default library. Existing calls that omit library arguments continue to use that default.
Call list_libraries() to discover the key owner's personal library and shared
groups. Results include name, library_id, library_type, is_default, and
key_permissions. Group results are paginated with limit and start; follow
next_start until it is null. Discovery also works when the default is a group.
Every other tool accepts optional library_id and library_type arguments:
Pass both arguments to select a library, or omit both. Use IDs returned by
list_libraries, rather than group names. Selection applies to one call and never
changes the environment or another client's target, including concurrent calls.
Item and collection keys must come from the selected library. Zotero enforces the
API key's permissions and the user's group rights; a denied group request fails
without falling back to the personal library. health_check accepts the same
arguments to verify a specific library without writing to it.
Group attachments use Zotero's built-in storage. WebDAV is used only for the configured personal library, even when the same server accesses shared groups.
Environment Variables
Note: If all three
ZOTERO_WEBDAV_*variables are set, attachments in the configured personal library use WebDAV instead of Zotero's built-in storage. Group attachments always use Zotero storage. The server automatically appends/zoteroto the WebDAV base URL, matching Zotero Desktop's behavior.
Version 0.10.2
- Install as a Claude Code plugin:
/plugin install zotero --marketplace RaulSimpetru/zotero-library-mcp. - An empty
ZOTERO_LIBRARY_TYPEnow means the default (user), as plugin installs pass unset optional settings as empty strings.
Version 0.10.1
- Attaching files to Zotero storage works again (group libraries and setups without WebDAV): Zotero rejects the full local path Pyzotero sent as the filename. Uploads are now confirmed, and a rate-limited or failed upload is reported instead of leaving an empty attachment.
list_tagsreturns every tag; Zotero's tag paging metadata is wrong past 200 tags, which made the old listing drop the rest.- Leftover query parameters no longer leak between calls (e.g. a duplicate check after fetching an item template only searched items of that type).
- Searches and tag renames containing the word "tags" no longer crash.
- Tagging, filing, and editing notes or annotations works on trashed items.
- Highlights land correctly on rotated pages with offset crop boxes, match
whole words, check for duplicates at the same location only, and report a
missing
occurrenceinstead of highlighting a different passage. - arXiv imports detect existing copies of any version of the paper.
- CrossRef imports keep organization authors and editors and map books, edited books, chapters, and dissertations to the right item types; Open Library books get their authors from the work record.
verify_itemshandles DataCite DOIs (arXiv, Zenodo), HTML in CrossRef titles, and subtitles;health_checkreports read-only keys aswrite_access: false.- BibTeX exports keep Zotero's order and unique citekeys across pages.
- Lists of child items (attachments, notes, annotations) are no longer capped at 100; linked PDFs are skipped, and standalone PDFs can be read.
- Removing the last tag color works; deleting tags containing
||is refused. - Hardening for hosted HTTP deployments: downloads connect to the validated IP (DNS rebinding), JWKS refetches are rate-limited, and file saves use exclusive temporary files.
- DOI imports no longer create duplicates. Zotero's search does not index
DOIs, so the old check never matched; imports now search the resolved title
and compare DOIs (including
DOI:lines in Extra). - ISBN imports no longer create duplicates of books stored with hyphenated ISBNs; ISBN-10 and ISBN-13 forms now match each other.
search_libraryreturns papers instead of matching attachments and notes.- Rate-limited writes are never retried (a retry could duplicate the item) and now fail instead of reporting success.
add_papers_by_dois(attach_pdfs=True)downloads PDFs in parallel.search_fulltextandsearchquery top-level items (about 20x faster).- Fuzzy search and
find_duplicatesreuse a library cache that is kept current with Zotero's incremental sync (since=), so repeat calls take well under a second. - CrossRef requests use
UNPAYWALL_EMAILas the polite-pool contact whenCROSSREF_MAILTOis unset, and retry rate-limited requests. create_annotationhighlights quotes that wrap across lines in full, countsoccurrenceacross pages, and uses the PDF's own page labels.- PDFs attached during DOI/arXiv import are named after the item title, and the result now says why a PDF was not attached.
- List output shows the correct year for dates like
12/1/1993. health_checkreturnslibrary_typeasuser/groupand reports whether open-access PDF lookup (UNPAYWALL_EMAIL) is configured.- New
list_trashtool for finding keys to pass torestore_item. - Faster
get_bibtexfor item keys,rename_tag,get_recent_items, fuzzy searches, andfind_duplicates; Zotero API connections are reused across calls. - Full-library and collection
get_bibtexexports stop downloading oncemax_charsis exceeded. get_item_fulltextprefers a PDF's index over a web snapshot's.find_duplicatesreportsitems_scannedandscan_capped.searchfalls back to the item's zotero.org link when it has no URL.- Shorter tool descriptions; library targeting is explained once in the server instructions.
Version 0.10.0
- Discover personal and shared libraries with
list_libraries. - Target a library on each tool call using
library_idandlibrary_type; existing calls keep the configured default. - Keep concurrent calls and nested exports scoped to the selected library.
- Use Zotero storage for shared-library attachments and personal WebDAV only for the configured personal library.
- Keep current dependency imports and HTTP logging compatible with MCP stdio.
Restart the MCP connection after upgrading to load the new tool schemas.
Upgrading to 0.8
Two path-writing operations were split from their read-only counterparts so remote clients can apply correct safety approvals:
get_bibtex(save_path=...)is nowsave_bibtex(save_path=...);get_bibtexonly returns data.download_pdf(save_path=...)is nowsave_pdf(save_path=...);download_pdfreturns an opaque MCP resource link.
Existing read-only calls to get_bibtex and download_pdf continue to work.
0.8.1
- PDF and annotation-preview resources now keep their precise MIME type when read by clients.
- PDF downloads report progress and return a clear WebDAV timeout error.
health_checkreports API-key write permission without modifying the library.- Server instructions are shorter, reducing repeated client context usage.
How it works
- You provide a DOI, arXiv ID, or ISBN
- The server queries the appropriate API to get full metadata:
- DOI → CrossRef API
- arXiv ID → arXiv API (with CrossRef fallback when a DOI exists)
- ISBN → Open Library API
- Metadata is mapped to Zotero's item format (title, authors, journal/publisher, date, etc.)
- The item is created in your Zotero library via the Zotero Web API
License
MIT
mcp-name: io.github.RaulSimpetru/zotero-library-mcp
Source: README.md at commit 4e1c089
Tools
0Version history
1- v0.5.0LatestSep 16, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.