zotero-mcp: an MCP server that moved inside the Zotero plugin
It's a plugin extension in Zotero. Zotero MCP Plugin enables integration between AI assistants and Zotero through MCP. Zotero MCP Plugin 是一个 Zotero 插件,通过 MCP协议实现 AI 助手与 Zotero深度集成。插件支持文献检索、元 数据管理、全文分析和智能问答等功能,让 Claude、ChatGPT 等 AI 工具能够直接访问和操作您的文献库。
At a glance
- What is it?
- zotero-mcp is a TypeScript Zotero 7 plugin with the Model Context Protocol server folded into it, serving Claude Desktop, Cherry Studio and Cursor over Streamable HTTP on port 23120. The packaging change is settled and the release cadence is steady, but the write operations, the unstated embedding provider behind semantic search and the missing authentication story are the parts to read twice.
- Who is it for?
- Adopt zotero-mcp if your references live in a Zotero 7 library on the machine where you run Claude Desktop, Cherry Studio or Cursor, and you want search, annotation lookup and note writing without writing an MCP server yourself. Do not adopt it as a shared or scheduled service, because the server is a Zotero plugin feature and stops when Zotero stops.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The architecture changed shape, and old configs are the casualty
The README describes a unified architecture with a single moving part:
AI Client ↔ Streamable HTTP ↔ Zotero Plugin (with integrated MCP server)
The project used to consist of a Zotero plugin and a separate MCP server that had to be started together. The current text is explicit about what changed: it eliminates the need for a separate MCP server process. Everything now lives inside zotero-mcp-plugin/, which is the only component listed under Project Structure alongside IMG/ and the two README files.
The transport change matters more than the packaging change. The plugin serves MCP over Streamable HTTP on a configurable port, default 23120. A configuration written against the earlier stdio arrangement will not connect, because there is no longer a subprocess for the client to spawn and no longer a stdio channel to speak on. The README's own example is the check: it names a transport of streamable_http and a URL, not a command and an argument list. If you are following an older tutorial or a cached post, that field is the first thing to change.
What the plugin exposes once running is a tool server over your library: search across title, creator, year, tags, full-text and semantic fields with boolean operators and relevance scoring, content extraction from PDFs, notes, abstracts and webpage snapshots with mode control, annotation search by colour, tag and keyword, collection browsing, write operations, and access to a cached full-text database.
Port 23120, a generated config, and an endpoint that also writes
Installation for an ordinary user is two steps and involves no Node.js at all, which is the clearest sign of the unified design.
You download zotero-mcp-plugin-x.x.x.xpi from the project's Releases page, install it in Zotero through Tools -> Add-ons, and restart Zotero. Then you open Preferences -> Zotero MCP Plugin, set Enable Server, confirm the Port, which defaults to 23120, and press Generate Client Configuration. That button is worth crediting. MCP client configuration is a JSON file in a per-application config directory, and hand-writing it is where most setups go wrong. You copy the generated block into your client.
For Claude Desktop the result looks like this:
{
"mcpServers": {
"zotero": {
"transport": "streamable_http",
"url": "http://127.0.0.1:23120/mcp"
}
}
}You should see the tools appear in the client once Zotero is running with Enable Server ticked, because the server is a plugin feature rather than a daemon you can start independently.
One gap deserves naming. The same endpoint that serves search and read operations is described as serving write operations too: creating notes, managing tags, updating metadata, creating new items and attaching PDFs. The example URL is bound to 127.0.0.1 and the port is fixed at 23120 by default, and the README excerpt documents no access token, password or origin check on that HTTP server. On a single-user desktop that is a defensible default. It also means the protection is the loopback interface and nothing else, and a user who changes the port to reach Zotero from another machine has changed that assumption with no documented control to replace it.
Semantic search promises embeddings the README never explains
Semantic search is the feature most likely to surprise you at setup.
The feature list claims AI-powered concept matching through embedding vectors and describes it as discovering related literature across languages. What the README does not say is where the vectors come from. Embedding a query and embedding a library both need a model, and the Quick Start has no configuration step for an API key, no provider name, no local model option and no statement about whether the index is stored in the plugin, in the Zotero database, or rebuilt on every start. Contrast that with the port and the transport, which are specified to the digit. The gap sits in the one feature most likely to fail first.
The same asymmetry runs through the rest of the list. Full-text search, boolean operators, relevance scoring and filters by title, creator, year, tags and item type are described precisely enough to reason about in advance. Content extraction mentions fine-grained mode control without naming a single mode. The full-text database is described as a cache of PDF full text, and the README does not say what triggers a re-index, whether indexing is incremental, or what happens when a PDF is replaced in place. None of this makes the tool wrong. It makes the operational questions answerable only by experiment.
What the repository root holds that an .xpi does not need
The root contains four entries that a .xpi deliverable does not require, and they say something about how the project is run.
There is layout-mockup.html, which neither README references and which is not part of the plugin build. There is AUTO_UPDATE_GUIDE.md, a document the README never mentions, whose name implies the plugin can replace itself. There is IMG/ holding screenshots and documentation images, and there are two parallel READMEs, README.md and README-zh.md.
The two-README arrangement has a consequence for English readers. The Quick Start says that for detailed client-specific configuration instructions, see the Chinese README. The English documentation therefore routes you to the Chinese documentation for the exact step where a wrong transport name or a malformed JSON block costs an afternoon. The generated-configuration button mitigates that, but the button is the mitigation, and the documentation is what you fall back on when the button is not enough.
The lockfile placement is also odd. package-lock.json sits at the repository root, while the documented build runs npm inside zotero-mcp-plugin/. The root package.json is not shown in the README, so from the repository listing alone there is no way to tell which dependency tree that lockfile pins, and the plugin tree is the one you would want pinned for a reproducible build.
There is also no CHANGELOG file in the repository listing, which is a gap given the release history. v1.4.7, v1.5.0 and v1.6.0 all carry a bare version string with no summary of what changed.
Building from source is three commands and one preference screen
The developer path is short, and the prerequisite list is the real specification of what this project is.
The README asks for Zotero 7.0 or higher, Node.js 18.0 or higher, npm or yarn, and Git. The badges agree on Zotero 7, Node.js 18+ and TypeScript 5.4. Start from a clone:
git clone https://github.com/cookjohn/zotero-mcp.git
cd zotero-mcpThen the plugin build:
cd zotero-mcp-plugin
npm install
npm run buildFor a development loop with auto-reload the README gives npm run start, and npm run build as the alternative when you would rather install the built .xpi manually. That distinction is the whole of the developer story. There is no server to launch in a second terminal, no environment file to fill in, and no port to pass on the command line, because the port is a preference inside Zotero and the server starts with the plugin.
The shape of the code follows from that. There is no server directory in the project structure, so the MCP transport, the tool handlers and the Zotero plugin interface all live in one package. That is what makes installation a single .xpi and the port a UI setting, and it is also what means every dependency of the MCP layer is loaded inside Zotero's own process, where a memory leak or a crash affects the reference manager itself.
The reverse architecture, and why the boundary is hard
zotero-mcp is a desktop integration, and the boundary is not a matter of configuration.
There is no hosted mode, no server deployment and no multi-user arrangement, because the thing on the other end of the connection is a running copy of Zotero with one person's library open in it. Every capability listed, including the cached full-text database, is derived from what that installation holds. If your references live in a shared institutional repository rather than in your own library, the semantic search and the collection browsing described here have nothing to index.
The alternative worth naming is the reverse architecture: keep the MCP server as a separate process, let the client launch it over stdio, and let that process talk to Zotero through its own database or web API. That shape can run on a schedule, works when Zotero is closed, and can be pointed at a library on another machine. It pays for that with coupling to Zotero internals that a plugin embedding simply does not have to accept. Folding the server into the plugin is the more durable of the two designs, because it uses a supported extension point instead of a private one. The price is the one already named: you get zotero-mcp only while Zotero is open.
For a researcher who wants an assistant to search and cite what is already on disk, that is a good trade. For a team that wants a shared literature service, it is the wrong shape entirely, and no amount of configuration closes that gap.
MIT, a regular tag cadence, and no homepage
The licence is the easy half. The repository is MIT licensed with a LICENSE file present at the root, so the plugin can be redistributed and modified with attribution and no source-disclosure obligation. That matters if you need a fork for an institutional Zotero build. The MIT grant covers this code only; it says nothing about Zotero itself, and it does not oblige you to keep using the upstream update channel. A fork for a managed deployment leaves you owning the merge cost afterwards.
On cadence, the history is regular and current. v1.4.7 was tagged 2026-03-22, v1.5.0 on 2026-06-11, and v1.6.0 on 2026-09-02. The last push was on 2026-09-09, a week after that tag. The version badge in the README reads 1.6.0, so the documented state matches the newest release rather than trailing an in-progress branch.
Two absences are worth noting. No homepage is declared for the project, so the Releases page and the two READMEs are the whole of the official surface. And with no CHANGELOG in the repository listing, the transport field is the thing to check in each release before you upgrade, because a change there silently invalidates every client config you have written. The auto-update document in the root implies the plugin expects to be able to replace itself, so that check may not be one you get to do by hand.
Editorial conclusion
Adopt zotero-mcp if your references live in a Zotero 7 library on the machine where you run Claude Desktop, Cherry Studio or Cursor, and you want search, annotation lookup and note writing without writing an MCP server yourself. Do not adopt it as a shared or scheduled service, because the server is a Zotero plugin feature and stops when Zotero stops. Verify three things first: that your client accepts the streamable_http transport on port 23120, that semantic search has a working embedding provider on your setup given that the README names none, and that you are content with an unauthenticated local HTTP endpoint that also exposes metadata writes. The plugin fits one person at one desk and does not fit a lab-wide deployment, and the deciding detail is where your library actually lives.
Frequently asked questions
How do I install the zotero-mcp plugin?
Download the latest zotero-mcp-plugin-x.x.x.xpi from the project's Releases page, install it in Zotero through Tools -> Add-ons, and restart Zotero. Then open Preferences -> Zotero MCP Plugin and enable the server. No separate server installation is needed, because the MCP server is integrated into the plugin.
Does zotero-mcp still need a separate MCP server process?
No. The current architecture folds the MCP server into the Zotero plugin, so the plugin communicates with AI clients directly over the Streamable HTTP protocol. Older configurations that relied on launching a separate server over stdio need to be rewritten to use the HTTP transport.
What port does the zotero-mcp server use, and how do I point Claude Desktop at it?
The plugin preference screen has an Enable Server toggle and a Port field that defaults to 23120, plus a Generate Client Configuration button that produces the client config for you. The README's example for Claude Desktop uses the transport streamable_http and the url http://127.0.0.1:23120/mcp. Claude Desktop, Cherry Studio and Cursor IDE are all listed as supported clients.
What do I need to build zotero-mcp from source?
Zotero 7.0 or higher, Node.js 18.0 or higher, npm or yarn, and Git. You clone the repository, change into zotero-mcp-plugin, then run npm install and npm run build, or npm run start for a development loop with auto-reload.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cookjohn-zotero-mcp)