Skip to main content
Glama
MCP Zotero

MCP Zotero

by bindresearch
WARNING

This is entirely vibe-coded (but human-reviewed)

MCP Zotero

This project provides read-only MCP access to one Zotero group library. It uses the Zotero Web API v3 and can run over Streamable HTTP or stdio.

The server is stateless. It does not keep a local index. It does not download or parse PDF files. Zotero performs the search and supplies synchronized attachment text.

Tools

search_papers

Search Zotero with qmode=everything. The server resolves attachment, note, and annotation results to their parent bibliographic items. It then removes duplicate papers.

The Zotero Web API currently supports phrase search. For broad discovery, use separate short queries and synonyms. Zotero does not provide a relevance sort for item requests, so results use the most recently modified items first. Zotero's result count is a count of raw matching items, not unique parent papers.

get_paper

Get all metadata and the attachment list for one bibliographic item.

get_paper_text

Get synchronized text from Zotero's /items/{attachmentKey}/fulltext endpoint. The tool does not request the attachment file.

The tool returns a bounded character range by default. Supply query to get excerpts around literal matches. Zotero full text has no reliable page boundaries, so the tool uses character offsets.

Related MCP server: zotero-mcp

Requirements

  • Python 3.13 or later

  • Zotero group ID (find from the URL)

  • A read-only Zotero API key with access to the group and its files

Create a dedicated key in your Zotero account settings. The MCP endpoint has no authentication and must stay on a private network.

Configuration

Copy the example configuration:

cp .env.example .env

Set these required values:

ZOTERO_GROUP_ID=123456
ZOTERO_API_KEY=replace-with-a-read-only-api-key

The main optional settings are:

MCP_TRANSPORT=streamable-http  # or stdio
MCP_HOST=127.0.0.1
MCP_PORT=8000
MCP_LOG_LEVEL=INFO
MCP_MAX_TEXT_CHARACTERS=12000
ZOTERO_TIMEOUT_SECONDS=30
ZOTERO_MAX_RETRIES=3
ZOTERO_MAX_SEARCH_PAGES=20

Install and run

Install the project with uv:

uv sync

Start the server. The default is Streamable HTTP:

uv run mcp-zotero

Set MCP_TRANSPORT=stdio in .env to run over standard input/output instead:

MCP_TRANSPORT=stdio uv run mcp-zotero

Streamable HTTP

The MCP endpoint is:

http://127.0.0.1:8000/mcp

Point the LiteLLM MCP server configuration at this URL. No MCP authorization header is required. Use MCP_HOST=0.0.0.0 when LiteLLM connects from another container or host on the private network.

stdio

Run in stdio mode for a local MCP client that launches the process directly.

For interactive development, use the MCP Inspector:

uv run mcp dev src/mcp_zotero/server.py

Test

uv run pytest

API behavior

The client sends these headers to Zotero:

Zotero-API-Key: ...
Zotero-API-Version: 3

It observes Zotero Backoff and Retry-After headers. It sends no more than four concurrent Zotero requests. Parent items are retrieved in batches of at most 50 keys, as required by the API.

A PDF can have no synchronized text even when its attachment metadata exists. In this case, get_paper_text returns status="not_available".

Zotero documentation

Available Tools

3 tools
get_paperA
Read-onlyIdempotent

Get a paper's complete Zotero metadata and attachment list.

Inputs: item_key (required). Returns: summary, creators, metadata, attachments

get_paper_textA
Read-onlyIdempotent

Read bounded text from Zotero's synchronized full-text endpoint.

This tool does not download or parse the PDF. Zotero does not provide reliable page boundaries, so returned segments use character offsets.

Inputs: item_key (required), query, offset, attachment_key, +1 more. Returns: query, status, message, item_key, +10 more

search_papersA
Read-onlyIdempotent

Search paper metadata and Zotero-indexed full text with a phrase query.

Attachment, note, and annotation matches are resolved to their parent paper. The result does not claim which attachment field matched. Use get_paper_text with a returned attachment key to inspect synchronized PDF text.

Inputs: query (required), limit, offset. Returns: limit, query, offset, papers, +6 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 3 tools

    Disambiguation5/5

    Each tool has a clear, distinct purpose: searching, retrieving full text, and fetching metadata. No overlap or ambiguity.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern (search_papers, get_paper_text, get_paper) with clear actions and targets.

    Tool Count5/5

    Three tools is well-scoped for a focused read-only Zotero server, covering the essential operations without redundancy.

    Completeness4/5

    Covers the primary use cases of searching and retrieving papers, but lacks management operations (e.g., create, update, delete) which may be outside the intended scope. Minor gap for full CRUD, but adequate for a search/retrieval tool.

    Maintenance

    ActivityStale
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables searching and reading full text of papers in a Zotero library by converting PDF attachments to Markdown and exposing a full-text search index to LLM tools.
      124 PyPI
      2
      MIT
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to search a Zotero library, retrieve item metadata, and access the full text of PDF attachments.
      -
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to search a Zotero library, retrieve complete item metadata, and fetch the full text of attached PDFs through the Zotero API.
      -