zotero-mcp-server
Provides tools for searching, reading, and writing items, collections, tags, and notes in a Zotero library via the Zotero Web API v3.
Click on "Install 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-mcp-serverFind recent articles in my Zotero tagged 'cybersecurity'"
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-server
An MCP (Model Context Protocol) server for the Zotero Web API v3 — search, read, and write items, collections, tags, and notes in a Zotero library.
Built for use with Claude (or any MCP client), aimed at literature-review workflows: pulling existing references into a "registro maestro," filing newly-found sources back into Zotero, tagging items by theoretical line, and attaching notes.
Tools
Tool | Read/Write | Description |
| Read | Quick-search items by text, type, tag, or collection |
| Read | Full metadata for one item, optionally with a formatted citation |
| Read | Notes/attachments of an item |
| Read | List collections, optionally scoped to a parent |
| Read | List tags in use, with item counts |
| Write | Create a new bibliographic item |
| Write | Attach a note to an existing item |
| Write | Add/remove tags on an item (version-checked) |
| Write | Create a new collection/subcollection |
This is a focused set covering the core research workflow, not full API coverage. Not included (would need to be added if you need them): saved searches, file/attachment uploads, full item updates beyond tags, deletion, group-membership management.
Related MCP server: zotero-mcp-server
1. Get a Zotero API key
Go to https://www.zotero.org/settings/keys and create a new private key.
Grant it read/write access to the library you want to use (your personal library, and/or specific groups).
Note your numeric user ID, shown on the same page — this is not your username.
For a group library, the group ID is the number in the group's URL, or from
GET https://api.zotero.org/users/<userID>/groups.
2. Configure environment variables
Variable | Required | Description |
| Yes | The key generated above |
| Yes |
|
| Yes | Numeric user ID or group ID |
| No | Override for the local Zotero desktop API ( |
| No |
|
| No | Port for |
Never commit these values or hardcode them in source — set them as environment variables or secrets in whatever you use to run the server.
3. Build
npm install
npm run build4. Run
Locally, over stdio (for local MCP clients, e.g. Claude Desktop's local server config):
ZOTERO_API_KEY=... ZOTERO_LIBRARY_TYPE=user ZOTERO_LIBRARY_ID=... node dist/index.jsAs a remote server, over Streamable HTTP (needed to add it as a custom connector in claude.ai):
TRANSPORT=http PORT=3000 \
ZOTERO_API_KEY=... ZOTERO_LIBRARY_TYPE=user ZOTERO_LIBRARY_ID=... \
node dist/index.jsThis exposes POST /mcp (the MCP endpoint) and GET /health (a plain liveness check). Deploy it somewhere reachable over HTTPS (Render, Fly.io, Railway, a small VM behind a reverse proxy with TLS, etc.) — claude.ai's custom connector setup needs a public https:// URL, not localhost.
A Dockerfile is included, so any of the platforms below can build and run it with no extra configuration beyond setting environment variables.
Deploying to a public HTTPS endpoint
Pick one. Render is the easiest if you don't mind pushing to GitHub; Fly.io is the easiest if you'd rather stay in a terminal.
Option A — Render (dashboard, needs a GitHub repo)
Push this project (this whole folder) to a new GitHub repository.
In the Render dashboard, click New → Web Service and connect that repository.
Render will detect the
Dockerfileautomatically — leave Environment as Docker. Leave build/start commands blank (the Dockerfile handles both).Under Environment Variables, add:
ZOTERO_API_KEYZOTERO_LIBRARY_TYPE(userorgroup)ZOTERO_LIBRARY_ID(
TRANSPORT=httpis already set inside the Dockerfile — no need to add it.)
Click Create Web Service. Render builds the image and deploys it; this takes a few minutes the first time.
Once live, Render shows a URL like
https://zotero-mcp-server.onrender.com. Your MCP endpoint ishttps://zotero-mcp-server.onrender.com/mcp.Sanity check:
curl https://zotero-mcp-server.onrender.com/healthshould return{"status":"ok"}.
Free-tier note: Render's free web services sleep after inactivity and take a few seconds to wake on the next request — fine for testing, worth upgrading if you'll use this daily.
Option B — Fly.io (CLI, no GitHub needed)
Install the CLI:
curl -L https://fly.io/install.sh | sh(or see fly.io/docs/flyctl).fly auth loginFrom inside the
zotero-mcp-serverfolder:fly launchIt detects the
Dockerfileand proposes an app name and region — accept or edit.Say no to adding a Postgres/Redis database (not needed).
Say no to deploying immediately if it asks — set secrets first (next step).
Set your credentials as secrets (never as plain fly.toml values):
fly secrets set ZOTERO_API_KEY=your_key ZOTERO_LIBRARY_TYPE=user ZOTERO_LIBRARY_ID=your_idOpen the generated
fly.tomland confirminternal_port = 3000under[http_service](it should be auto-detected from the Dockerfile'sEXPOSE 3000; fix it manually if not).Deploy:
fly deployYour MCP endpoint is
https://<your-app-name>.fly.dev/mcp. Checkhttps://<your-app-name>.fly.dev/health.
Option C — Railway (CLI or dashboard)
Install the CLI (
npm install -g @railway/cli) or use the Railway dashboard connected to a GitHub repo — same idea as Render.CLI path:
railway login, then from the project folderrailway initandrailway up. Railway detects theDockerfileautomatically.Set env vars:
railway variables set ZOTERO_API_KEY=... ZOTERO_LIBRARY_TYPE=user ZOTERO_LIBRARY_ID=...(or via the dashboard's Variables tab).Railway services aren't public by default — go to Settings → Networking → Generate Domain to get a public
https://your-app.up.railway.appURL.MCP endpoint:
https://your-app.up.railway.app/mcp.
Option D — Self-hosted VM (full control, more steps)
Provision a small Ubuntu 22.04+ VM (DigitalOcean, Linode, a spare EC2 instance, etc.) and point a DNS A record at its IP, e.g.
zotero-mcp.yourdomain.com.SSH in and install Node 20 and Caddy (Caddy handles HTTPS automatically via Let's Encrypt — much less setup than nginx + certbot):
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - sudo apt-get install -y nodejs sudo apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt-get update && sudo apt-get install -y caddyCopy the project to the VM (
scpthe zip, thenunzip) and build:cd zotero-mcp-server && npm install && npm run buildCreate
/etc/systemd/system/zotero-mcp.service:[Unit] Description=Zotero MCP server After=network.target [Service] Environment=TRANSPORT=http Environment=PORT=3000 Environment=ZOTERO_API_KEY=your_key Environment=ZOTERO_LIBRARY_TYPE=user Environment=ZOTERO_LIBRARY_ID=your_id ExecStart=/usr/bin/node /home/youruser/zotero-mcp-server/dist/index.js Restart=always User=youruser [Install] WantedBy=multi-user.targetThen:
sudo systemctl daemon-reload && sudo systemctl enable --now zotero-mcpPoint Caddy at it — edit
/etc/caddy/Caddyfile:zotero-mcp.yourdomain.com { reverse_proxy localhost:3000 }Then:
sudo systemctl reload caddy. Caddy fetches a TLS certificate automatically on first request.Check
https://zotero-mcp.yourdomain.com/health. MCP endpoint:https://zotero-mcp.yourdomain.com/mcp.
5. Connect it to Claude
Once deployed and reachable over HTTPS:
In claude.ai, go to Settings → Connectors → Add custom connector.
Enter the deployed URL, e.g.
https://your-deployment.example.com/mcp.Claude will discover the 9 tools above automatically.
For Claude Desktop with a local stdio server instead, add an entry to its MCP server config pointing at node /absolute/path/to/dist/index.js, with the environment variables from step 2 set in that config.
Testing
npx @modelcontextprotocol/inspector node dist/index.jsThis opens a local UI to call each tool by hand before wiring it up to Claude.
Notes on the Zotero API this server relies on
Auth:
Zotero-API-Keyheader, per request.Versioning for writes:
zotero_update_item_tagsreads the item's currentversionbefore patching, and sends it viaIf-Unmodified-Since-Version— if the item changed elsewhere in the meantime, Zotero returns412and the tool reports it clearly instead of silently overwriting.Rate limits: Zotero may return
429with aRetry-Afterheader, or aBackoffheader on any response. This server surfaces both as actionable error text; it does not currently auto-retry.Item creation fetches the field template for the requested
itemTypefromGET /items/newfirst, so only valid fields for that type are sent.
Official API docs: https://www.zotero.org/support/dev/web_api/v3/
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceRead-only MCP server for browsing, searching, and exporting a Zotero library from AI assistants.
- Flicense-qualityCmaintenanceAn MCP server that integrates with Zotero to manage research references, enabling search, citation, and organization of your library.
- Alicense-qualityAmaintenanceMCP server that lets AI assistants search, create, organize, and cite from a Zotero library.3MIT
- Flicense-qualityCmaintenanceMCP server for interacting with a Zotero library via the local API. Enables searching, retrieving, creating, updating, and deleting Zotero items, managing collections and tags, and generating citations.
Related MCP Connectors
The everything Zotero MCP server — Web API v3 + local API, safe writes, citations, search.
Remote MCP server for full read/write access to a Zotero library
MCP server for Altmetric APIs - track research attention across news, policy, social media, and more
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/andresrocha99/zotero-mcp-server-v2'
If you have feedback or need assistance with the MCP directory API, please join our Discord server