Skip to main content

Fast fulltext Zotero MCP for Codex and Claude.

Project description

zotero-fulltext

Access your Zotero library with your favorite AI tool.

This MCP server for Zotero 8+ gives Claude and Codex citekey-native access to your library. 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 server:
uv tool install zotero-fulltext
  1. Add the plugin to Claude Code:
claude plugin add /absolute/path/to/zotero-fulltext
  1. Restart Claude Code if needed, run /mcp to confirm the server is connected, and try a slash command:
/zotero:find attention

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

uv tool install zotero-fulltext
# or
pipx install zotero-fulltext

This makes the zotero-fulltext command permanently available. You can also use uvx zotero-fulltext to run without installing.

Configuration

Claude Code (plugin with slash commands)

Clone this repo and add it as a plugin:

claude plugin add /absolute/path/to/zotero-fulltext

This registers the MCP server and adds the slash commands. Restart Claude Code if needed and run /mcp to confirm the server is connected.

If you only want the MCP tools without slash commands:

claude mcp add --transport stdio --scope project zotero -- zotero-fulltext

Claude Desktop

Add the server to claude_desktop_config.json:

{
  "mcpServers": {
    "zotero": {
      "type": "stdio",
      "command": "zotero-fulltext"
    }
  }
}

Restart Claude Desktop, open a chat, and confirm the server is available.

Codex

Add to ~/.codex/config.toml:

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

Restart Codex, then run codex mcp list to verify it is configured.

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, 20 fulltext matches.
  • Item results include item_uri and fulltext_uri so clients can attach standard zotero://... resources directly.
  • 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).

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

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

Roadmap

  • Remote API support (beyond local)
  • Write-back (notes, annotations)
  • Embeddings or semantic search
  • Web fallback for items not in the local library

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

Example for a group library in Claude Code:

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

Related Projects

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zotero_fulltext-0.1.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zotero_fulltext-0.1.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file zotero_fulltext-0.1.0.tar.gz.

File metadata

  • Download URL: zotero_fulltext-0.1.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","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}

File hashes

Hashes for zotero_fulltext-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3efb16e4cf265d3d0c78a016a4a07e5d71ddcef68e667dc205654223567226f5
MD5 e0d97ebe7eb9233e8982d8da4a260326
BLAKE2b-256 dd1685fbe4d355e9464144b40f580a27683ba956f227c796d27b4f70886de89f

See more details on using hashes here.

File details

Details for the file zotero_fulltext-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zotero_fulltext-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","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}

File hashes

Hashes for zotero_fulltext-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8c356834bc9684e83b979da55c1d0e1da626d20fc434ef6d23aacae570924aba
MD5 bb6c1be09c152986a022213a2d67cc66
BLAKE2b-256 ec2abbad4e769a37d9f3b0932e4359a53bc92605d3247d3c21e61f2965b4c052

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page