Skip to main content

MCP Server PyPI License: MIT

Access your Zotero library with your favorite AI tool.

Demo

This MCP server for Zotero 8+ gives Claude and Codex access to your library via search and citekeys. It talks directly to Zotero's local API and aims to keep token usage low. Fulltext is fetched only on demand.

Quick Start

  1. Make sure Zotero 8+ is running with the local API enabled (Settings → Advanced → "Allow other applications on this computer to communicate with Zotero").
  2. Install the Claude Code plugin:
/plugin marketplace add statzhero/zotero-fulltext
/plugin install zotero@zotero-fulltext
  1. Run /mcp to confirm the server is connected, then try a slash command:
/zotero:find sustainability reporting

Also works with Claude Desktop, Codex, and as a standalone MCP server without slash commands.

Commands

The Claude Code plugin provides four slash commands:

Command What it does
/zotero:find <query> Search the whole library
/zotero:lookup <citekey> Exact citekey metadata lookup
/zotero:read <citekey> Numbered fulltext paragraphs
/zotero:within <citekey> <query> Search inside one paper's fulltext

find searches the whole library. lookup is lightweight metadata confirmation. read returns the actual paper text. within searches only one item's indexed fulltext.

Without the plugin, all the same functionality is available through the MCP tools directly (see Tools).

Installation

Claude Code (plugin with slash commands)

/plugin marketplace add statzhero/zotero-fulltext
/plugin install zotero@zotero-fulltext

This installs the MCP server and slash commands. Run /mcp to confirm the server is connected.

Claude Desktop

Requires uv (install with brew install uv or curl -LsSf https://astral.sh/uv/install.sh | sh).

Open Claude Desktop → Settings → Developer → Edit Config, and add:

{
  "mcpServers": {
    "zotero": {
      "type": "stdio",
      "command": "uvx",
      "args": ["zotero-fulltext"]
    }
  }
}

Save the file, then fully quit and reopen Claude Desktop (closing the window is not enough). Open a new chat and confirm the server is available.

Codex (plugin with skills)

Note: The Codex plugin marketplace is still rolling out. The install flow below may change.

codex plugin marketplace add statzhero/zotero-fulltext
codex plugin install zotero

This installs the MCP server and four skills (find, lookup, read, within).

Codex (manual MCP only)

Requires uv (install with brew install uv or curl -LsSf https://astral.sh/uv/install.sh | sh).

Add to ~/.codex/config.toml:

[mcp_servers.zotero]
command = "uvx"
args = ["zotero-fulltext"]

Restart Codex, then run codex mcp list to verify the server appears.

Design

The server is intentionally simple and read-only. It relies on Zotero's own search index rather than building a second one.

  • Startup builds a metadata index mapping citekeys to items and attachments.
  • Library changes are tracked with Zotero version headers and incremental sync.
  • Fulltext is fetched only on demand and cached in memory (TTL/LRU).
  • All outputs are bounded by default: 10 search hits, 80 paragraphs with a character budget, 20 fulltext matches.
  • Item results include item_uri and fulltext_uri so clients can attach standard zotero://... resources directly.
  • Creator roles (author, editor, translator, etc.) are preserved and grouped in results.
  • If a lookup finds no citekey, it returns found=false. If a search finds nothing, it returns results=[]. There is no web fallback.

Tools

The server exposes five MCP tools. The slash commands above are convenience wrappers.

lookup(citekey)

Exact citekey lookup. Citekeys are resolved in order:

  1. Native Zotero 8 citationKey
  2. Legacy Better BibTeX Citation Key: line in Extra
  3. Deterministic generated fallback

If an item later gains a real citekey, the generated key is kept as an alias.

search(query, collection?, tag?, limit?)

Searches Zotero with qmode=everything, collapses attachment hits to parent items, and ranks exact citekey matches first.

collections()

Lists collections in the current library.

fulltext(citekey, offset?, limit?)

Fetches indexed attachment fulltext, splits it into numbered paragraphs, and returns a bounded slice (default: 80 paragraphs). Large extracted paragraphs are split into smaller chunks, and each response has a soft character budget. If the response includes truncated=true, request the same citekey again with offset=next_offset to continue reading.

Fulltext responses include paging metadata:

Field Meaning
paragraph_count Total available paragraph chunks for the item
returned_count Number of paragraph chunks in this response
returned_chars Approximate text characters returned
max_chars Character budget used for this response
truncated Whether more paragraph chunks remain
next_offset Offset to pass into the next fulltext call, or null when complete

fulltext_search(citekey, query, before?, after?, limit?)

Searches within a single item's paragraphized fulltext and returns matching paragraphs with surrounding context.

Environment Variables

By default the server connects to a local personal library with no authentication. Set these variables to change that:

Variable Default Description
ZOTERO_LIBRARY_TYPE user user for personal libraries, group for group libraries
ZOTERO_LIBRARY_ID 0 Zotero user or group ID (required for group libraries)
ZOTERO_API_KEY — API key for authenticated or remote access
ZOTERO_API_BASE_URL http://127.0.0.1:23119/api Base URL for the Zotero API
ZOTERO_MAX_PARAGRAPH_CHARS 1800 Maximum characters per returned fulltext chunk
ZOTERO_MAX_FULLTEXT_CHARS 60000 Soft character budget for each fulltext response; continue with next_offset
ZOTERO_CACHE_DIR ~/.cache/zotero-fulltext Directory for the persistent metadata index
ZOTERO_STARTUP_SYNC true Sync the library index once at startup
ZOTERO_INDEX_REFRESH_MIN_INTERVAL_SEC 15 Minimum seconds between incremental index refreshes
ZOTERO_PARAGRAPH_CACHE_TTL_SEC 7200 Time-to-live for cached fulltext paragraphs
ZOTERO_PARAGRAPH_CACHE_SIZE 128 Maximum number of documents kept in the paragraph cache
ZOTERO_DEFAULT_SEARCH_LIMIT 10 Default number of search results
ZOTERO_DEFAULT_FULLTEXT_LIMIT 80 Default number of paragraphs per fulltext response
ZOTERO_DEFAULT_FULLTEXT_CONTEXT 1 Default paragraphs of context around each fulltext_search match

ZOTERO_USER_ID is accepted as an alias for ZOTERO_LIBRARY_ID. The ZOTERO_LIBRARY_ID default of 0 applies to user libraries; group libraries require an explicit ID.

Example for a group library in Claude Code:

{
  "mcpServers": {
    "zotero": {
      "type": "stdio",
      "command": "zotero-fulltext",
      "env": {
        "ZOTERO_LIBRARY_TYPE": "group",
        "ZOTERO_LIBRARY_ID": "12345"
      }
    }
  }
}

Other MCP servers for Zotero, with different design goals:

  • 54yyyu/zotero-mcp — Feature-rich: read-write operations, optional semantic search via ChromaDB, Web API support. Heavier dependencies.
  • kujenga/zotero-mcp — Minimal read-only server with Web API support via pyzotero. No citekey resolution or in-document search.
  • kaliaboi/mcp-zotero — Cloud-only (Zotero Web API). Metadata browsing, no fulltext.

To remove an existing Zotero MCP server before switching:

claude mcp remove zotero

Or delete the zotero entry from .mcp.json / claude_desktop_config.json / ~/.codex/config.toml manually.

Requirements

  • Zotero 8+ with the local API enabled
  • Python 3.11+
  • Better BibTeX (optional but recommended)

License

MIT • Ulrich Atz (ulrichatz)

Metadata

Release files for zotero-fulltext 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zotero-fulltext 0.5.1
File Size Uploaded Provenance Actions
zotero_fulltext-0.5.1.tar.gz 1.1 MB Without provenance Details for zotero_fulltext-0.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zotero-fulltext 0.5.1
File Interpreter ABI Platform Actions
zotero_fulltext-0.5.1-py3-none-any.whl Python 3 none any Details for zotero_fulltext-0.5.1-py3-none-any.whl

Total release size: 1.1 MB

Release files / zotero_fulltext-0.5.1.tar.gz

Download URL zotero_fulltext-0.5.1.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
5f34a3589f40a19dbe2a7327a6f410c4b7470b7b74dca3979b99697e9707a7cc
BLAKE2b-256 checksum
How to use checksums
7a8720c1ec513b3ef88975d0f7a5102dac7c3194f9e743fe7b6f180962f31c9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / zotero_fulltext-0.5.1-py3-none-any.whl

Download URL zotero_fulltext-0.5.1-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0369c4fbbed63b843fb3d99ce08c5e025fe607af55cbb66cbad00c448ff9b08e
BLAKE2b-256 checksum
How to use checksums
c47acb87f860d670579f4c0d55704e30c7455f03ed4a62a4c8d4e77113c2df93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for zotero-fulltext 0.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page