Zotero MCP
Provides tools for searching, reading, citing, organizing, and analyzing an online Zotero library, including items, collections, tags, notes, attachments, duplicate detection, and optional semantic search.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Zotero MCPFind my recent articles about machine learning and summarize the titles."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Zotero MCP
An MCP server that gives an AI assistant full access to your online Zotero library — with 82 tools.
One environment variable, no local Zotero desktop app, no service to deploy, no tokens to manage.
Independent open-source project. Not affiliated with or endorsed by Zotero.
Languages: English · 简体中文
Why this one
The existing Zotero MCP servers are either light on tools or awkward to run. This one is both the most complete and the simplest to start:
Tools | Setup | Writes | |
zotero-mcp (this project) | 82 | one env var | preview + confirm |
cookjohn (Zotero plugin) | ~20 | install a Zotero plugin | needs Zotero running |
kaliaboi | 5 | two env vars | none |
54yyyu | ~52 | Python + config file | direct |
It works with online libraries only — the same data Zotero syncs to zotero.org. Local files, desktop selections and unsynced items are out of reach by design, which is what lets it run anywhere without touching your computer's Zotero install.
Related MCP server: Zotero MCP Server
Quick start
1. Create a Zotero API key at https://www.zotero.org/settings/keys/new. Tick the permissions you want (reading is enough to start).
2. Install and build:
git clone https://github.com/4965898/zotero-online-mcp.git && cd zotero-online-mcp
npm ci
npm run build3. Put your key in a file. Run setup-local.cmd (Windows) — it copies .env.local.example
to .env — then paste your key into .env:
ZOTERO_API_KEY=your-key-hereKeeping the key in .env rather than in the client config means one file to edit and no secret
duplicated across every client you own.
4. Point your MCP client at it.
Cherry Studio
Settings → MCP Servers → Add → type stdio, then:
{
"command": "D:/path/to/zotero-online-mcp/start-stdio.cmd",
"args": []
}start-stdio.cmd reads .env for you, so no key appears here at all.
Claude Desktop / Cursor
Add to claude_desktop_config.json (or mcp.json for Cursor):
{
"mcpServers": {
"zotero": {
"command": "D:/path/to/zotero-online-mcp/start-stdio.cmd",
"args": []
}
}
}Restart the client. You should see 82 tools, 51 of them read-only.
Point the client straight at the built entry point and pass the key as an env var:
{
"command": "node",
"args": ["/path/to/zotero-online-mcp/dist/stdio.js"],
"env": { "ZOTERO_API_KEY": "your-key-here" }
}On Windows this works too — use forward slashes in the path, or double backslashes.
NoteGen
NoteGen speaks standard MCP over HTTP, so start the server in HTTP mode first:
npm run setup # creates .env with a fresh encryption key
npm start # listens on http://localhost:3000Then add the server in NoteGen:
{
"mcpServers": {
"zotero-online": {
"url": "http://YOUR-HOST:3000/mcp",
"headers": {
"Authorization": "Bearer YOUR_ZOTERO_API_KEY"
}
}
}
}NoteGen infers the transport from the fields:
commandmeans stdio,urlmeans http, so the JSON needs notype.If the import appears to do nothing, NoteGen skips servers whose name already exists — it never overwrites. Delete the old entry in the MCP server list and import again.
If your NoteGen build can launch local processes, use the stdio config above instead and skip the server entirely.
A regression test in this repo pins NoteGen's actual wire behaviour (protocol version negotiation, session headers, notification and SSE response framing), so the transport layer is aligned with what the app sends.
RikkaHub (Android)
RikkaHub supports SSE and Streamable HTTP but cannot launch a local process, so a phone must use HTTP mode — and the phone has to be able to reach the machine running the server.
On the PC (Windows):
Run
setup-local.cmdand paste your Zotero key into the generated.env.npm ci && npm run build.Run
allow-firewall.cmdas Administrator to add the inbound rule for TCP 3000. It applies to Private/Domain networks only, so nothing is opened on café or airport Wi-Fi.Run
start-http.cmdto start the server.npm run addressprints every reachable address plus ready-to-paste configs.
In RikkaHub on the phone:
Field | Value |
Name |
|
Transport type |
|
Server URL |
|
Header | name |
Bearer and the credential are separated by exactly one space.
If it will not connect, switch the transport type to SSE and use /sse instead.
The server accepts every local interface address as a valid
Host, which is what lets a phone reachhttp://192.168.x.x:3000directly. Requests carrying an unknownHostare still refused with 403.Off that network the phone cannot connect — the physical limit of having no public entry point. For access from anywhere, put the server behind a reachable domain with TLS (see
compose.production.yml).
Configuration
Variable | Required | Purpose |
| yes | Your Zotero API key |
| no | Your numeric Zotero user ID. Omit it and the server looks it up for you |
| no | Set |
| no | HTTPS embedding endpoint for semantic search |
| no | Embedding model name |
| no | Key for the embedding endpoint |
| no | Attachment size limit, default |
| no | HTTP mode only. |
| no | Extra web origins to admit (comma separated). Desktop client origins and this machine's own http origins are already allowed by default |
Writes are opt-in and always previewed
Read-only until you set ZOTERO_WRITE=true. When enabled, every change still returns an exact
preview and a confirmation token first — the AI shows you what it intends to change, and nothing
reaches Zotero until you approve it. Deletions are recoverable through Zotero's trash.
What you get
82 tools across the full research flow. Highlights:
Find — search a library or every group library, advanced field filters, recent additions, tags, saved searches, DOI and ISBN lookup, BibTeX/RIS/CSL import
Read — item details and batches, children, abstracts, notes, annotations, synced full text, real PDF page extraction, outlines, attachment download
Cite — bibliography and citation generation from your own items
Organize — collections, tags, relations, item-to-collection membership (all previewed)
Analyse — library statistics, duplicate detection, duplicate merge
Optionally — semantic search and "find similar" over your library, with an embedding provider
Full catalog with schemas: docs/TOOLS.md.
Using it on several machines, or from a phone
In stdio mode the server is a process your client starts, so it runs wherever that client runs. There is nothing to reach over a network and no address to configure. The practical consequence:
Client | Works? | How |
Desktop app on the same PC (Cherry Studio, Claude Desktop, Cursor) | yes | steps above; nothing else needed |
Desktop app on a second PC | yes | same steps on that PC — clone, build, |
NoteGen | yes | stdio config, or the HTTP URL if your build cannot launch processes |
A phone or tablet app that can run local processes (e.g. Termux) | yes | same steps on the device |
RikkaHub and other URL-only mobile apps | needs the HTTP mode below | RikkaHub setup; the device must be able to reach the host |
Any client on a different network | needs the HTTP mode below | requires a host those devices can reach |
Installing it on each machine is the recommended path, and it is what makes the setup immune to port forwarding, tunnels, TLS and uptime. Your API key gets copied to each device, which is the one cost — Zotero keys are revocable per-key, so you can issue one key per device and revoke any of them independently at https://www.zotero.org/settings/keys.
Optional: run it as a service
Some clients — most mobile AI apps, for instance — can only connect to a URL and cannot launch a local process. Those need the HTTP mode: the same 82 tools run as a server, and clients reach it over the network. This requires a host the devices can reach, so it is only worth it if you have one.
npm run setup # creates .env with a fresh encryption key
npm startThen open http://localhost:3000, paste your key once, and copy the generated client config.
See .env.example for all settings and SECURITY.md for the
security model. Both transports are supported: Streamable HTTP at /mcp and legacy SSE at /sse.
Serving a phone on your own network
Windows helpers for the common single-user case:
setup-local.cmd— creates.envfrom the template. Paste your key into it.npm ci && npm run build— install and compile.allow-firewall.cmd— adds an inbound rule for TCP 3000. Run as Administrator, once. It applies to Private/Domain networks only, so nothing is opened on café or airport Wi-Fi.start-http.cmd— starts the server and prints the exact config to paste into each client.
npm run address prints the same information on its own, listing every local address this machine
can be reached at plus ready-to-paste configs for Cherry Studio, RikkaHub and stdio clients.
The server accepts every local interface address as a valid
Host, which is what lets a phone reachhttp://192.168.x.x:3000directly. Requests carrying an unknownHostare still refused with 403.
Sending the Zotero key directly
By default a client sends a service token issued by this server. If you would rather skip that
step, set PASSTHROUGH_KEYS=true and clients send their Zotero API key as the bearer credential
instead — nothing else to generate, nothing to copy out of the landing page:
{
"mcpServers": {
"zotero": {
"type": "streamable-http",
"url": "http://YOUR-HOST:3000/mcp",
"headers": { "Authorization": "Bearer YOUR_ZOTERO_API_KEY" }
}
}
}For SSE clients, point url at /sse instead.
The key is verified against Zotero once and cached briefly, so repeat requests cost nothing extra. Both credential kinds keep working while this is on, so existing service tokens are not invalidated.
The trade-off is real: the Zotero key gets copied into every client config, and you lose
per-client revocation — revoking one device means revoking the Zotero key itself. Leave
PASSTHROUGH_KEYS=false (the default) when more than one person uses the instance.
Tokens never expire
Tokens issued by this mode never expire unless you set TOKEN_TTL_DAYS to a positive number;
they stay valid until you revoke them on the landing page or delete the connection.
For a public deployment behind a domain and TLS, use compose.production.yml with
deploy/nginx.conf.example.
Development
npm run check # typecheck + tests + build
npm run stdio # build and run the stdio server directly
npm run docs:tools # regenerate docs/TOOLS.md from the registered schemasTests use in-memory SQLite and synthetic upstream responses; no Zotero account is required. See
CONTRIBUTING.md before opening a pull request.
Limits
Online, synced content only.
Large libraries cannot be enumerated in one call; scans report their coverage and flag truncation.
Extracted PDF text is reliable for prose, unreliable for maths and tables.
License
MIT. See LICENSE and THIRD_PARTY_NOTICES.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Live data gateway for AI — 3,300+ tools across 750+ sources, with citations
The media memory layer for AI agents and their humans. Your AI client gets 29 tools to search your collection, add items, update ratings, preview music, and find patterns across everything you've read, watched, and listened to.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
Related MCP Servers
- AlicenseCqualityDmaintenanceEnables interaction with Zotero libraries for searching, managing collections, items, tags, and attachments, plus optional semantic search across PDFs via local embeddings.382MIT
- FlicenseBqualityDmaintenanceEnables AI assistants to search, cite, and manage research references directly from a Zotero library.99-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search and retrieve metadata, abstracts, and notes from a user's Zotero library through tools like search, get item, and list collections.-
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to search, access, and interact with your Zotero research library, including semantic search, metadata retrieval, PDF annotations, and library management.MIT