
MCP Zotero
io.github.Xevos117Published by GitHub account Xevos117v2.0.4Updated Nov 2, 2026
Unofficial Zotero server: search your library, add papers by DOI, import PDFs, cite in Word
Overview
Unofficial Zotero MCP server that lets an assistant search and organize a Zotero library, add papers by DOI, import PDFs, read full text and inject citations…
- What you can do
- Browse and search the library: list collections, list items in a collection, search or sort items, fetch batch metadata and read PDF full text
- Add content: add items by DOI with metadata resolution, add items of any Zotero type, create collections, import PDFs from a URL, attach open-access PDFs and add linked URL attachments
- Delete content: remove items permanently or delete a collection, only when explicitly enabled
- Cite and documents: inject live Zotero citations into a Word document in APA, IEEE, Vancouver, Harvard or Chicago style, and read the configured user ID
- When to use it
- Useful when you write or manage academic references and want an assistant to work directly with your Zotero library: finding sources, adding papers by DOI, attaching PDFs, pulling full text, or producing a Word document with live citations.
- Requirements
- Runs locally over stdio via npx (Node.js 22 or newer) or as a Claude Desktop extension bundle. Needs a Zotero Web API key with library read/write and file access in ZOTERO_API_KEY and a numeric ZOTERO_USER_ID; optional ZOTERO_LIBRARY_TYPE and ZOTERO_LIBRARY_ID for group libraries, UNPAYWALL_EMAIL for open-access PDF lookup, and UNSAFE_OPERATIONS to allow deletions. Network access to the Zotero API is required.
Installation
In SourceWeft
- Open MCP Zotero in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
MCP Zotero
Note: This is an unofficial community project and is not affiliated with, endorsed by, or supported by the Zotero team or the Corporation for Digital Scholarship. "Zotero" is a registered trademark of the Corporation for Digital Scholarship.
A Model Context Protocol server for Zotero integration. It gives any LLM full access to your Zotero library: search, organize, add papers by DOI, import PDFs, read full-text content, and inject live citations into Word documents.
Originally based on mcp-zotero by Abhishek Kalia. This project has since been extensively rewritten with a new architecture, 15 tools (up from 5), citation injection, PDF management, and Claude skill support.
How it works
The server is designed to be usable by any LLM without external documentation. On connection, it sends workflow instructions via the MCP instructions field, and each tool description includes cross-references and usage guidance. An LLM that has never seen this server before can discover the full workflow — from adding papers to producing a cited Word document — directly from the tool listing.
For advanced use cases (PDF upload policy, citation style guidance, source transparency), a Claude skill is included for Claude.ai Projects. But the skill is optional: the MCP server is fully self-documenting.
Local vs Remote LLMs
LLMs with filesystem access can use all tools directly, including inject_citations which reads and writes .docx files on disk.
LLMs without filesystem access — including Claude Desktop, which connects to MCP but cannot generate files locally — can use the included Claude skill (skills/zotero-skill-mcp-integrations/), which runs citation injection entirely inside a sandbox. MCP tools handle all Zotero API operations; the skill handles document assembly.
Claude Skill Setup (for Claude.ai Projects and Claude Desktop)
- Download the skill
.zipfrom the latest GitHub Release - Extract it and upload the folder to your Claude.ai Project as a skill
- The skill enables citation injection directly inside the sandbox, without requiring local filesystem access
Setup
Requires Node.js 22 or newer.
The server is listed in the official MCP Registry as
io.github.Xevos117/mcp-zotero (starting with the first release after 2.0.2), so registry-aware clients can find and install it from
there; the configuration below works with any MCP client.
-
Get your Zotero credentials:
-
Set environment variables:
Targeting a group library
By default the server targets your personal Zotero library (/users/<ZOTERO_USER_ID>/...).
To target a group library instead, set two additional environment variables:
Example for a group library:
The API key in ZOTERO_API_KEY must have access to the target group library — generate or scope keys at https://www.zotero.org/settings/keys.
The server refuses to start if ZOTERO_LIBRARY_TYPE=group is set without ZOTERO_LIBRARY_ID, or if a library ID is not numeric.
Per-call library override
Every tool accepts two optional args that override the env defaults for that single call:
library_type—"user"or"group"library_id— numeric library ID
Resolution order: per-call arg > env var > implicit default (user, ZOTERO_USER_ID). library_id must be numeric. Overriding library_type to group on a server configured for a user library requires library_id; overriding to user on a group server without library_id uses ZOTERO_USER_ID.
Note that per-call overrides let the LLM reach any library the API key can access. Scope the key to the libraries you want exposed; deletions remain gated by UNSAFE_OPERATIONS.
This lets a single MCP instance target multiple libraries (e.g., a staging group and a final-output group) without restarting:
Environment Variables
Unsafe Operations
By default, the MCP server does not allow any deletion. This is a safety measure to prevent an LLM from accidentally deleting items or collections from your library.
To enable deletion, set the UNSAFE_OPERATIONS environment variable to one of the following values:
Important notes:
- If
UNSAFE_OPERATIONSis not set, empty, or set to an unrecognized value, it defaults tonone. - The value is case-insensitive (e.g.
ALL,Items,NONEall work). delete_itemsdeletes items permanently: the Zotero Web API multi-item DELETE does not move them to the Zotero trash, so they cannot be restored from the desktop client.delete_collectionremoves the collection (folder) only — items inside it are not deleted and remain in your library.- The
allvalue includes both item and collection deletion because managing collections inherently requires item-level access.
Configuration example:
Integration with Claude Desktop
Install as a Claude Desktop extension (one click)
- Download
mcp-zotero.mcpbfrom the latest release (available from the first release after 2.0.2). - Open the file with Claude Desktop (macOS or Windows; e.g. double-click it) and confirm in the installation dialog.
The bundle itself is not platform-specific (
manifest.jsonlists macOS, Windows and Linux, and CI runs it on Linux), so other MCPB-compatible clients can install it too. - Fill in your Zotero API key and Zotero user ID (see Setup). Optional settings: library type and group ID (for a group library), the email for Unpaywall (open-access PDF lookup) and which deletions are allowed (default: none, see Unsafe Operations).
The extension bundles the server and all its dependencies, so no npm install is needed. It needs Node.js 22 or newer
(compatibility.runtimes.node in the manifest): according to the MCPB documentation, Claude Desktop runs Node.js
extensions with the runtime that ships with the app. The API key is declared as a sensitive setting (masked
input, stored securely by the client). Deletions stay disabled unless you change Deletions allowed in the
extension settings.
The extension contains only the MCP server: the Claude skills in skills/ (citation injection inside
the sandbox, scientific writing) are installed separately from their .zip files in the same release, as described
in Claude Skill Setup.
Manual configuration (any MCP client)
Add to your Claude Desktop configuration (or the equivalent file of another MCP client):
Integration with Claude Code
Add -e UNPAYWALL_EMAIL=... or -e UNSAFE_OPERATIONS=items as needed, and --scope user to make the server
available in every project (the default local scope covers only the current project). From a clone of this repository,
npx tsx src/server.ts runs the server from source instead (see Development).
Available Tools
Library browsing
Adding content
Deleting content
Citation & documents
Development
Testing
Every test case is listed in test/TEST_CASES.md.
Live tests locally use only ZOTERO_TEST_* variables, never your ZOTERO_API_KEY:
Against a personal library add ZOTERO_LIVE_SAFE_MODE=1: the suite only creates items and collections
named mzt-<runId>… and tagged mzt-run:<runId>, deletes only those, and skips collection deletion and
group writes. A dedicated test account is marked by a collection named __mzt_disposable__.
Dependencies are updated monthly by a Claude Code agent (workflow,
skill .claude/skills/deps-update); patch-only PRs are auto-merged after
all required checks pass, anything else waits for review. GitHub Actions versions are updated by Dependabot.
CI setup (repository owner)
The agents authenticate to the Claude API with Anthropic Workload Identity Federation (GitHub OIDC, no API key). Recommended: one federation rule per environment, as narrow as possible:
Claims are exact-match string pairs (only subject_prefix supports a trailing *), so a prefix such as
"this workflow on any ref" must be written as a CEL condition, as above; an exact job_workflow_ref
(claude-deps, main only) can be a plain claim.
Audience https://api.anthropic.com. The subject is an exact match unless it ends with *; jobs that use
an environment get the OIDC subject repo:Xevos117/mcp-zotero:environment:<environment>, so a rule
written for a branch or PR subject never matches. Numeric ids (not names) keep a renamed or re-created
repository/account from matching.
Trade-off for zotero-live: the "any ref" condition is needed for the agent smoke test to run on pull
requests, but it also accepts a modified copy of that workflow file pushed to any branch of this repository
(only people with write access can push). Pinning it to the exact claim
job_workflow_ref: Xevos117/mcp-zotero/.github/workflows/claude-agent-smoke.yml@refs/heads/main closes that
gap but disables the agent smoke test on PRs (it would then run only on manual runs from main).
Other owner settings:
- The Zotero test account needs a collection named
__mzt_disposable__. - Repository settings: "Allow auto-merge", and "Allow GitHub Actions to create and approve pull requests"
(the dependency workflow opens its PR with
GITHUB_TOKEN). Keep the ruleset at 0 required approvals: auto-merge of the dependency PR relies on it, and it is also what makes the second setting acceptable. That setting is a conscious trade-off: it lets workflows open PRs (needed) and approve them (not used by any workflow here); if approvals are ever required, it would let a workflow approve its own PR, so revisit it together with any approval requirement. - No GitHub App is used by any workflow (the agents authenticate to Anthropic with Workload Identity
Federation and use only
GITHUB_TOKENon GitHub, read-only for the agents). If the Claude GitHub App is installed on this repository, uninstall it. - Set a monthly spend limit on the Anthropic workspace used by the federation rules: it is the real cap on agent costs.
- Residual risk: the agent smoke job that holds the OIDC token also runs the MCP server built from the PR's
code (that is what it tests). It runs only for same-repository PRs by the owner or a bot, the token is
bound to the
zotero-liveenvironment and the workspace spend limit caps any misuse. - Required checks after the stack merges:
test (node 22),test (node 24),test (node 26),live-tests,agent-smoke.
Releasing
- Update
CHANGELOG.md(moveUnreleasedto the new version) and the version inpackage.json, inserver.json(versionandpackages[0].version) and inmanifest.json(npm testfails if they differ). - Make sure CI, live tests and the agent smoke test are green on
main. - Run the manual Word checklist on a document injected by the release candidate and record the results in its log.
- Before the first release that ships the Claude Desktop extension (and whenever
manifest.jsonor the Node.js requirement changes): build it withnpm run bundle, installdist/mcp-zotero.mcpbonce in a real Claude Desktop (macOS or Windows), fill in a test key and user ID, and check that the 15 tools appear andget_collectionsanswers. - Publish the GitHub release: the release workflow runs the tests, publishes
to npm, publishes
server.jsonto the MCP Registry and attaches the skill zips and the Claude Desktop extension (mcp-zotero.mcpb). The release tag must be the version (e.g.2.0.3): the registry and bundle jobs check out the tag and fail ifpackage.jsondiffers. - If only the
mcp-registryjob fails, use Re-run failed jobs on the run: Re-run all jobs stops at the npm publish (the version already exists) and so never reaches the registry.
Debug with MCP Inspector
License
MIT - see LICENSE for details.
Source: README.md at commit bc154a9
Tools
0Version history
2- v2.0.4LatestOct 26, 2026
- v2.0.3Oct 21, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.