zotero-library-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ZOTERO_API_KEY | Yes | API key with read/write permissions | |
| CROSSREF_MAILTO | No | Your email for CrossRef polite pool (faster API access) | |
| ZOTERO_LIBRARY_ID | Yes | Your Zotero user or group library ID | |
| ZOTERO_WEBDAV_URL | No | WebDAV URL for file storage | |
| ZOTERO_WEBDAV_USER | No | WebDAV username | |
| ZOTERO_LIBRARY_TYPE | No | Type of library: 'user' (default) or 'group' | user |
| ZOTERO_WEBDAV_PASSWORD | No | WebDAV password |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_librariesA | List the key owner's personal library and a page of shared group libraries. Use the returned library_id and library_type on subsequent tool calls. This does not change the default library. Pagination applies to groups; the personal library is included on each page. Key permissions are not a guarantee of group membership rights; Zotero enforces access on each call. |
| add_paper_by_doiA | Add a paper to your Zotero library by its DOI. Resolves metadata automatically via CrossRef and creates the item in Zotero. Optionally add it to a specific collection. Args: doi: The DOI of the paper (e.g. "10.1038/nature12373") collection_id: Optional Zotero collection key to add the paper to Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_papers_by_doisA | Add multiple papers to Zotero by their DOIs (batch, up to 50). Args: dois: List of DOIs to add collection_id: Optional Zotero collection key to add all papers to Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_paper_by_arxiv_idA | Add a paper to your Zotero library by its arXiv ID. Fetches metadata from the arXiv API. If the paper has a DOI, resolves it via CrossRef for richer metadata; otherwise creates a preprint entry directly. Optionally add it to a specific collection. Args: arxiv_id: The arXiv ID of the paper (e.g. "2301.07041") collection_id: Optional Zotero collection key to add the paper to Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_book_by_isbnA | Add a book to your Zotero library by its ISBN. Resolves metadata automatically via Open Library and creates the item in Zotero. Optionally add it to a specific collection. Args: isbn: The ISBN of the book (e.g. "9780262046824") collection_id: Optional Zotero collection key to add the book to Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_item_from_metadataA | Add an item from manual, CSL-like, or previously parsed metadata. The Zotero item template determines which fields are accepted for the requested item type, preventing invalid cross-type metadata. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_unfiled_itemsA | Get items that are not in any collection (unfiled items). Args: limit: Maximum number of items to return (default 25) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| search_libraryA | Search your Zotero library. Falls back to fuzzy matching if the exact search returns no results. Args: query: Search query (searches titles, authors, tags, etc.) limit: Maximum number of results per page (default 10, max 100) start: Offset of the first result; pass the value suggested by the previous call's footer to fetch the next page (default 0) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_item_detailsA | Get full details of a Zotero item by its key. Args: item_key: The Zotero item key Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_bibtexA | Export BibTeX entries from your Zotero library. Can export specific items, an entire collection, or your whole library. Use save_bibtex when the export should be written to a local file. Args: item_keys: Optional list of item keys to export. If omitted, exports collection or full library. collection_id: Optional collection key to export all items from. include_abstract: Include abstracts in BibTeX output (default False to save tokens). biblatex: Convert output to BibLaTeX format (default False). Remaps fields like journal→journaltitle, address→location, and merges year+month into date. max_chars: Maximum response size; use save_bibtex for larger full-library exports Pass both library_id and library_type to target another library; omit both to use the configured default. |
| save_bibtexA | Export BibTeX or BibLaTeX and atomically write it to a local file. Path writes are available by default over local stdio. HTTP deployments must explicitly allow a confined file root. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_item_fulltextA | Get bounded plain text from a paper's PDF or Zotero full-text index. Unlike download_pdf, this returns readable text directly and never exposes a server-local temporary path. Args: item_key: The Zotero item key (the parent item, not the attachment) attachment_key: Optional PDF attachment key when an item has several PDFs max_chars: Maximum number of characters to return (1,000-200,000) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| delete_itemA | Permanently delete an item from your Zotero library. Args: item_key: The Zotero item key to delete Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_recent_itemsA | Get recently added items from your Zotero library. Args: limit: Maximum number of items to return (default 10) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| verify_itemsA | Verify that recently added items have valid DOIs that match CrossRef metadata. Re-resolves each item's DOI via CrossRef and compares the title. Reports items that have no DOI, DOIs that don't resolve, or title mismatches. Args: limit: Number of recent items to check (default 10) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| health_checkA | Check Zotero credentials, library access, and optional file storage setup. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| list_attachmentsA | List attachment keys, filenames, MIME types, links, and sizes for an item. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| update_item_metadataA | Update selected bibliographic fields and optionally replace creators. Immutable/internal fields such as item type, key, version, parent item, collections, tags, and deletion state cannot be changed through this tool. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| trash_itemA | Move an item to Zotero's trash so it can be restored later. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| restore_itemA | Restore an item from Zotero's trash. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| find_duplicatesA | Find duplicate top-level items by DOI, ISBN, or normalized title. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| search_fulltextA | Search Zotero metadata and indexed full text using qmode=everything. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| searchA | Company-knowledge compatible search over Zotero items and full text. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| fetchB | Company-knowledge compatible fetch for one Zotero item key. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| list_collectionsA | List all collections in your Zotero library. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_to_collectionA | Add an existing Zotero item to a collection. Args: item_key: The Zotero item key (from search results) collection_id: The collection key to add it to Pass both library_id and library_type to target another library; omit both to use the configured default. |
| remove_from_collectionA | Remove an item from a collection without deleting it from the library. Args: item_key: The Zotero item key collection_id: The collection key to remove it from Pass both library_id and library_type to target another library; omit both to use the configured default. |
| create_collectionA | Create a new collection in your Zotero library. Args: name: Name for the new collection parent_collection_id: Optional parent collection key to nest under Pass both library_id and library_type to target another library; omit both to use the configured default. |
| delete_collectionA | Permanently delete a collection from your Zotero library. Items in the collection are NOT deleted — they remain in your library. Args: collection_id: The collection key to delete Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_collection_itemsA | Get items in a specific collection, one page at a time. Args: collection_id: The collection key to browse limit: Maximum number of items to return per page (default 25, max 100) start: Offset of the first item; pass the value suggested by the previous call's footer to fetch the next page (default 0) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| rename_collectionA | Rename a Zotero collection without changing its parent. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| move_collectionA | Move a collection under another collection, or to the library root. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| list_tagsA | List all tags in your Zotero library. Args: limit: Maximum number of tags to return (default 100) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| delete_tagsA | Delete tags from the entire Zotero library. This removes the tags from all items. Args: tags: List of tag names to delete from the library Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_tagsA | Add one or more tags to a Zotero item. Optionally assign a color to all added tags. Args: item_key: The Zotero item key tags: List of tags to add color: Optional hex color code (e.g. '#FF0000') to assign to the added tags Pass both library_id and library_type to target another library; omit both to use the configured default. |
| remove_tagsA | Remove one or more tags from a Zotero item. Args: item_key: The Zotero item key tags: List of tags to remove Pass both library_id and library_type to target another library; omit both to use the configured default. |
| set_tag_colorA | Assign a color to a tag in the Zotero library. Colored tags appear in the tag selector and item lists. Args: tag: The tag name to colorize color: Hex color code (e.g. '#FF0000' for red, '#3366CC' for blue) position: Sort position for the colored tag (0-8, lower = higher priority) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| rename_tagA | Rename a tag across all items in the Zotero library. Args: old_name: The current tag name new_name: The new tag name to replace it with Pass both library_id and library_type to target another library; omit both to use the configured default. |
| unset_tag_colorA | Remove a tag's assigned library color without deleting the tag. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| add_noteA | Add a note to a Zotero item. The note is created as a child of the specified item. Supports HTML formatting (e.g. bold, italic, lists). Args: item_key: The parent Zotero item key to attach the note to note: The note content (plain text or HTML) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| create_annotationA | Highlight a text passage in a PDF attached to a Zotero item. Searches the PDF for the quoted text and creates a visible highlight annotation in Zotero's PDF reader. Uses three strategies in order: exact match, normalized word match, and fuzzy match (for OCR errors, hyphenation differences, or minor transcription mismatches). Smart overlap handling:
Args: item_key: The Zotero item key (the parent item, not the attachment) quoted_text: The text passage to highlight in the PDF (fuzzy matching handles minor differences from the actual PDF text) comment: Optional comment to attach to the highlight color: Highlight color as hex (default "#ffd400" yellow) max_l_dist: Maximum Levenshtein distance for fuzzy matching. Default is ~20% of the search text length. Increase if the PDF has many OCR errors; decrease for stricter matching. attachment_key: Optional PDF attachment key when the item has multiple PDFs page_number: Optional one-based page number to search occurrence: One-based occurrence to highlight when text repeats Pass both library_id and library_type to target another library; omit both to use the configured default. |
| get_annotationsA | List all highlights and annotations on a paper's PDF. Args: item_key: The Zotero item key (the parent item, not the attachment) limit: Maximum number of annotations to return (default 100) Pass both library_id and library_type to target another library; omit both to use the configured default. |
| attach_fileB | Attach a ChatGPT file input or an authorized local file to an item. Args: item_key: The Zotero item key to attach the file to file: File object supplied by ChatGPT through openai/fileParams file_path: Local server path; stdio only unless HTTP roots are explicitly enabled Pass both library_id and library_type to target another library; omit both to use the configured default. |
| download_pdfA | Return a PDF as a remote-safe MCP resource link. Useful when Zotero's fulltext index is incomplete (e.g. for books) and you need to read the PDF directly with other tools. Args: item_key: The Zotero item key (the parent item, not the attachment) attachment_key: Optional PDF attachment key when the item has multiple PDFs Pass both library_id and library_type to target another library; omit both to use the configured default. |
| save_pdfA | Save a Zotero PDF to an authorized local server path. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| list_notesB | List child notes for an item with bounded note content. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| update_noteA | Replace the content of an existing Zotero note. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| delete_noteA | Permanently delete a Zotero note. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| update_annotationA | Update the comment and/or highlight color of an annotation. Pass both library_id and library_type to target another library; omit both to use the configured default. |
| delete_annotationA | Permanently delete a Zotero annotation. Pass both library_id and library_type to target another library; omit both to use the configured default. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 50 tools
Most tools map cleanly to a resource+action, but search_library, search_fulltext, and search are near-duplicates, and fetch largely duplicates get_item_details. An agent could struggle to pick the right retrieval tool despite generally helpful descriptions.
The vast majority follow a verb_noun pattern (add_paper_by_doi, get_collection_items, rename_tag, delete_annotation). Minor outliers like search, fetch, and health_check, plus the singular/plural mismatch in add_paper_by_doi vs add_papers_by_dois, keep it from being perfect.
With 50 tools this is a very large surface for an agent to navigate, exceeding the 'too many' threshold. Even though Zotero is a rich domain, many add/get/search variants could be consolidated without losing capability.
The toolset covers Zotero's core resources thoroughly: items, collections, tags, notes, annotations, attachments, exports, and search all have lifecycle operations. There are no obvious dead ends; trash/restore, annotation CRUD, and batch DOI import make the surface feel complete.