Zotero MCP

by 54yyyu

Not rated
GitHub

About

Connect your Zotero research library with AI assistants. Supports local/web API access, PDF annotation extraction, and advanced search.

Details

Author
54yyyu
Categories
Productivity, Other, Knowledge Base
Tags
#document, #research, #pdf

Setup

Install Zotero MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/54yyyu/zotero-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

Zotero MCP: Chat with your Research Library—Local or Web—in Claude, ChatGPT, and more.

Zotero MCPseamlessly connects yourZoteroresearch library withChatGPT,Claude, and other AI assistants (e.g.,Cherry Studio,Chorus,Cursor) via theModel Context Protocol. Review papers, get summaries, analyze citations, extract PDF annotations, and more!

- Vector-based similarity searchover your entire research library (requires[semantic]extra)
- Multiple embedding models: Default (free, local), OpenAI, Gemini, and Ollama
- Intelligent resultswith similarity scores and contextual matching
- Auto-updating databasewith configurable sync schedules

- Find papers, articles, and books by title, author, or content
- Perform complex searches with multiple criteria
- Browse collections, tags, and recent additions
- Semantic search for conceptual and topic-based discovery

- Retrieve detailed metadata for any item (markdown or BibTeX export)
- Get full text content (when available)
- Look up items by BetterBibTeX citation key

- Extract and search PDF annotations with page numbers
- Access Zotero's native annotations
- Create and update notes and annotations
- Extract PDF table of contents / outlines (requires[pdf]extra)

- Add papers by DOIwith auto-fetched metadata and open-access PDF cascade (Unpaywall, arXiv, Semantic Scholar, PMC)
- Add papers by URL(arXiv, DOI links, generic webpages) or from local files
- Create and manage collections, update item metadata, batch-update tags
- Find and merge duplicate items with dry-run preview
- Hybrid mode: local reads + web API writes for local-mode users

📊 Scite Citation Intelligence (optional[scite]extra)

- Citation tallies: See how many papers support, contrast, or mention each item — the MCP version of theScite Zotero Plugin
- Retraction alerts: Scan your library for retracted or corrected papers
- No Scite account required — uses public API endpoints

- Local mode for offline access (no API key needed)
- Web API for cloud library access
- Hybrid mode: read from local Zotero, write via web API

- Search, browse, and edit your library directly from the terminal — no AI assistant required
- Ideal for scripting, automation, and quick lookups
- Short aliases (s,g,ann,coll) for interactive use

New to the command line?Try the community-builtZotero MCP Setup— includes a macOS GUI installer (DMG), one-click install scripts for Mac/Windows, and a step-by-step guide. No Terminal experience needed.

The base install is lightweight — it includes search, metadata retrieval, annotations, and write operations. No ML/AI dependencies are pulled in.

uv tool install zotero-mcp-server zotero-mcp setup # Auto-configure (Claude Desktop supported)
pip install zotero-mcp-server zotero-mcp setup # Auto-configure (Claude Desktop supported)
pipx install zotero-mcp-server zotero-mcp setup # Auto-configure (Claude Desktop supported)

Heavy ML/PDF dependencies are separated into optional extras so the base install stays fast and small:

uv tool install "zotero-mcp-server[all]" # Full install with all features uv tool install "zotero-mcp-server[semantic]" # Just semantic search

If you only need basic library access (search, read, annotate, write), the default install with no extras is all you need.

Keep zotero-mcp up to date with the smart update command:

# Check for updates zotero-mcp update --check-only # Update to latest version (preserves all configurations) zotero-mcp update

Zotero MCP now includes powerful AI-powered semantic search capabilities that let you find research based on concepts and meaning, not just keywords.

During setup or separately, configure semantic search:

# Configure during initial setup (recommended) zotero-mcp setup # Or configure semantic search separately zotero-mcp setup --semantic-config-only

- Default (all-MiniLM-L6-v2): Free, runs locally, good for most use cases
- OpenAI: Better quality, requires API key (text-embedding-3-smallortext-embedding-3-large)
- Gemini: Better quality, requires API key (gemini-embedding-001)
- Ollama: Runs locally via Ollama API (requires model name, e.g., 'qwen3-embedding')

Install and start Ollama, then pull an embedding model before runningzotero-mcp update-db:

ollama serve # Small model: fast and lightweight ollama pull nomic-embed-text # Medium model: better multilingual retrieval quality ollama pull bge-m3

When prompted byzotero-mcp setup --semantic-config-only, chooseOllamaand use eithernomic-embed-textorbge-m3as the model name. If you change embedding models later, rebuild the index:

Twosemantic_search.embedding_configkeys tune the Ollama path for slower hardware or very large libraries:

"embedding_config": { "model_name": "bge-m3", "timeout": 600, // HTTP timeout per /api/embed call (default 120s) "request_batch_size": 64 // documents per request (default 64) }

Raisetimeoutif indexing reportsRead timed out; lowerrequest_batch_sizeto make each request cover less GPU work, which usually fixes timeouts more reliably than raising the timeout alone.

When you choose OpenAI, setup also asks whether database updates should use OpenAI Batch API. Batch updates are cheaper for large libraries, but they are asynchronous: submit the batch, wait for completion, then import the embeddings.

- Manual: Update only when you runzotero-mcp update-db
- Auto on startup: Update database every time the server starts
- Daily: Update once per day automatically
- Every N days: Set custom interval

After setup, initialize your search database:

# Build the semantic search database (fast, metadata-only) zotero-mcp update-db # Submit OpenAI embeddings through Batch API for this update zotero-mcp update-db --openai-batch # Check and import completed OpenAI Batch API embeddings zotero-mcp openai-batch-status zotero-mcp openai-batch-import # Force realtime OpenAI embeddings even if Batch API is enabled in config zotero-mcp update-db --no-openai-batch # Build with full-text extraction (slower, more comprehensive) zotero-mcp update-db --fulltext # Use your custom zotero.sqlite path zotero-mcp update-db --fulltext --db-path "/Your_custom_path/zotero.sqlite" # If you have embedding conflicts or changed models, force a rebuild zotero-mcp update-db --force-rebuild # Check database status zotero-mcp db-status

Example Semantic Queries in your AI assistant:

- "Find research similar to machine learning concepts in neuroscience"
- "Papers that discuss climate change impacts on agriculture"
- "Research related to quantum computing applications"
- "Studies about social media influence on mental health"
- "Find papers conceptually similar to this abstract: [paste abstract]"

The semantic search provides similarity scores and finds papers based on conceptual understanding, not just keyword matching.

PDFs are parsed withpdf-inspector, which produces Markdown with the document's heading structure intact. These keys live undersemantic_search.extractionin~/.config/zotero-mcp/config.json:

{ "semantic_search": { "extraction": { "pdf_max_pages": 50, "fulltext_display_max_pages": 10, "attachment_priority": ["markdown", "pdf", "html", "other"] } } }

attachment_priorityexists for the case where you have converted a paper to clean Markdown yourself and attached it next to the original PDF. By default the PDF still wins; listing"markdown"first makes your converted copy the one that gets read and indexed. Valid entries arepdf,html,markdown,textandother.otheris a catch-all matching every kind not named elsewhere in the list, so the default sweeps Markdown and plain text into one bucket where the larger file wins. Omittingothermeans anything unlisted is never chosen.

Changing this setting marks affected items for re-extraction, so a followingzotero-mcp update-dbrefreshes text that came from a now-deprioritized attachment rather than leaving stale embeddings behind.

To read one specific attachment regardless of priority, pass that attachment's own key tozotero_get_item_fulltext(find it withzotero_get_item_children) — an attachment key bypasses the priority order and reads exactly that file.

Full documentation is available atZotero MCP docs.

- Python 3.10+
- Zotero 7+ (for local API with full-text access)
- An MCP-compatible client (e.g., Claude Desktop, ChatGPT Developer Mode, Cherry Studio, Chorus)

For ChatGPT setup: see theGetting Started guide.

The Zotero local API must be enabled for the MCP server to work.

In Zotero 9, the local API toggle is under Settings → Advanced → 'Allow other applications on this computer to communicate with Zotero'.

For Claude Desktop / Claude Code (MCP client)

Manual configuration: For Claude Desktop, add this toclaude_desktop_config.json. For Claude Code, add this to~/.claude.json:

{ "mcpServers": { "zotero": { "command": "zotero-mcp", "env": { "ZOTERO_LOCAL": "true", "ZOTERO_API_KEY": "YOUR_API_KEY", "ZOTERO_LIBRARY_ID": "YOUR_LIBRARY_ID" } } } }

Forlocal read-only use,ZOTERO_LOCAL: "true"is all you need — drop theZOTERO_API_KEYandZOTERO_LIBRARY_IDlines entirely.

The local API is fast but read-only, so the MCP server uses the Zotero web API for write operations.

- KeepZOTERO_LOCAL: "true"— with API credentials set, the server runs in hybrid mode (fast local reads, web API writes)
- Click
hereto generate a Zotero API key and replaceYOUR_API_KEYwith it
- ZOTERO_LIBRARY_IDis your numericuserID, shown on that same page (for a group library, use the group's ID and also setZOTERO_LIBRARY_TYPE: "group").

Important Note: Environmental variables set in the shell you runclaudein will override these values.

Tip:If Claude Desktop reports it can't find thezotero-mcpcommand, use the absolute path instead (runzotero-mcp setup-infoorwhich zotero-mcpto find it) — GUI apps don't always inherit your shellPATH.
- Start Zotero desktop (make sure local API is enabled in preferences)
- Launch Claude Desktop / Claude Code
- For Claude Desktop, access the Zotero-MCP tool through Claude Desktop's tools interface. For Claude Code, run the/mcpcommand, and make sure the Zotero MCP server is connected.

- "Search my library for papers on machine learning"
- "Find recent articles I've added about climate change"
- "Summarize the key findings from my paper on quantum computing"
- "Extract all PDF annotations from my paper on neural networks"
- "Search my notes and annotations for mentions of 'reinforcement learning'"
- "Show me papers tagged '#Arm' excluding those with '#Crypt' in my library"
- "Search for papers on operating system with tag '#Arm'"
- "Export the BibTeX citation for papers on machine learning"
- "Find papers conceptually similar to deep learning in computer vision"(semantic search)
- "Research that relates to the intersection of AI and healthcare"(semantic search)
- "Papers that discuss topics similar to this abstract:
[paste text]"(semantic search)

After installing Zotero MCP, add a local read-only server with:

autohand mcp add zotero env ZOTERO_LOCAL=true zotero-mcp

Add--scope projectafteraddto keep the server configuration in the current project. For hybrid or web API access, add the credentials described above to theenvcommand. SeeAutohand Codefor current installation and CLI details.

Go to Settings -> MCP Servers -> Edit MCP Configuration, and add the following:

{ "mcpServers": { "zotero": { "name": "zotero", "type": "stdio", "isActive": true, "command": "zotero-mcp", "args": [], "env": { "ZOTERO_LOCAL": "true" } } } }

Cherry Studio also provides a visual configuration method for general settings and tools selection.

For accessing your Zotero library via the web API (useful for remote setups):

zotero-mcp setup --no-local --api-key YOUR_API_KEY --library-id YOUR_LIBRARY_ID

- ZOTERO_LOCAL=true: Use the local Zotero API (default: false)
- ZOTERO_API_KEY: Your Zotero API key (for web API)
- ZOTERO_LIBRARY_ID: Your Zotero library ID (for web API)
- ZOTERO_LIBRARY_TYPE: The type of library (user or group, default: user)
- ZOTERO_WEBDAV_URL: Optional WebDAV folder URL for direct attachment downloads in remote mode
- ZOTERO_WEBDAV_USERNAME: Optional WebDAV username
- ZOTERO_WEBDAV_PASSWORD: Optional WebDAV password

- ZOTERO_EMBEDDING_MODEL: Embedding model to use (default, openai, gemini, ollama)
- OPENAI_API_KEY: Your OpenAI API key (for OpenAI embeddings)
- OPENAI_EMBEDDING_MODEL: OpenAI model name (text-embedding-3-small, text-embedding-3-large)
- OPENAI_BASE_URL: Custom OpenAI endpoint URL (optional, for use with compatible APIs)
- OpenAI Batch API indexing is configured byzotero-mcp setupand can be overridden withzotero-mcp update-db --openai-batchor--no-openai-batch
- GEMINI_API_KEY: Your Gemini API key (for Gemini embeddings)
- GEMINI_EMBEDDING_MODEL: Gemini model name (gemini-embedding-001)
- GEMINI_BASE_URL: Custom Gemini endpoint URL (optional, for use with compatible APIs)
- OLLAMA_EMBEDDING_MODEL: Ollama embedding model name (qwen3-embedding by default)
- OLLAMA_BASE_URL: Ollama server URL (default:http://localhost:11434)
- ZOTERO_DB_PATH: Customzotero.sqlitepath (optional). When unset, the database is located automatically: a data directory configured in Zotero's preferences (read from the profile'sprefs.js) is tried first, then the default~/Zoterolocation.

- ZOTERO_MCP_TOOLSETS: Which optional tool groups to expose. Every tool the server registers is sent to the model oneveryrequest, so the tool list is a fixed cost on your context window. Groups that need an external service, serve maintenance rather than research, or apply only to some users are off by default. SeeTool Groupsbelow.

- ZOTERO_MCP_SCHEMA_REFRESH=0: Disable the weekly background refresh of Zotero's item-type schema fromapi.zotero.org. The schema is what routes a generictitle=update to the field a type actually stores it under (a statute'snameOfAct, a case'scaseName). A copy ships with the package, so disabling the refresh only means new item types added by Zotero after this release won't be picked up until you upgrade.zotero-mcp schema-refreshstill refreshes on demand.
- ZOTERO_MCP_SCHEMA_CACHE: Custom path for the refreshed schema cache (default:~/.cache/zotero-mcp/schema.json).

# Run the server directly zotero-mcp serve # Specify transport method zotero-mcp serve --transport stdio|streamable-http|sse # Setup and configuration zotero-mcp setup --help # Get help on setup options zotero-mcp setup --semantic-config-only # Configure only semantic search zotero-mcp setup-info # Show installation path and config info for MCP clients # Updates and maintenance zotero-mcp update # Update to latest version zotero-mcp update --check-only # Check for updates without installing zotero-mcp update --force # Force update even if up to date # Semantic search database management zotero-mcp update-db # Update semantic search database (fast, metadata-only) zotero-mcp update-db --openai-batch # Submit OpenAI embeddings through Batch API zotero-mcp update-db --no-openai-batch # Force realtime OpenAI embeddings for this run zotero-mcp openai-batch-status # Check latest OpenAI embedding batch status zotero-mcp openai-batch-import # Import completed OpenAI batch embeddings zotero-mcp update-db --fulltext # Update with full-text extraction (comprehensive but slower) zotero-mcp update-db --force-rebuild # Force complete database rebuild zotero-mcp update-db --fulltext --force-rebuild # Rebuild with full-text extraction zotero-mcp update-db --fulltext --db-path "your_path_to/zotero.sqlite" # Customize your zotero database path zotero-mcp db-status # Show database status and info # General zotero-mcp version # Show current version

This repository publishes multi-arch container images to GitHub Container Registry:

- ghcr.io/<owner>/zotero-mcp:<tag>-core- lightweight install (no optional extras)
- ghcr.io/<owner>/zotero-mcp:<tag>-all- full install with
[semantic,pdf,scite]
- Unsuffixed tags (for example:latest,:vX.Y.Z) point to theallflavor

Detailed publishing and runtime notes are indocs/docker-images.md.

- Release tags:vX.Y.Z,vX.Y,vX(plus-coreand-allvariants)
- Main branch:latest(pluslatest-coreandlatest-all)
- Immutable SHA tags:sha-<shortsha>-core,sha-<shortsha>-all(and unsuffixed SHA forall)

The image supports both MCP server and standalone CLI modes.

- Server mode (default): runszotero-mcp serve --transport stdio
- CLI mode: setZOTERO_APP=cliand pass normalzotero-cliarguments

- Container runtime vars:ZOTERO_APP(serverorcli) andZOTERO_TRANSPORT(default:stdio)
- All standard Zotero MCP vars are supported in containers (ZOTERO_LOCAL,ZOTERO_API_KEY,ZOTERO_LIBRARY_ID, embedding provider keys, etc.)
- ChromaDB persistence path in the container is/home/app/.config/zotero-mcp/chroma_db/
- Persist config + ChromaDB by mounting/home/app/.config/zotero-mcp

# Default MCP server mode (stdio) docker run --rm ghcr.io/<owner>/zotero-mcp:latest # MCP server mode with explicit transport docker run --rm ghcr.io/<owner>/zotero-mcp:latest serve --transport streamable-http --host 0.0.0.0 --port 8000 # Standalone CLI mode docker run --rm -e ZOTERO_APP=cli ghcr.io/<owner>/zotero-mcp:latest search "machine learning" # Persist config + ChromaDB across runs docker run --rm -v zotero-mcp-data:/home/app/.config/zotero-mcp --env-file .env ghcr.io/<owner>/zotero-mcp:latest
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.