Zoteus: use your whole Zotero library from Claude or any AI (free and open source)

Hi all,

I built a small open source tool called Zoteus and wanted to share it here.

Zoteus lets you use your Zotero library straight from Claude, Cursor, or any AI app that supports MCP. From a normal chat you can:

- search your library, including the full text of your PDFs, by keyword or by meaning
- add papers by DOI, ISBN, PMID, or arXiv
- make citations and bibliographies in about 2,800 styles, built from your own
- add, edit, tag, and organize items (changes ask you to confirm first and go to the trash, so they are reversible)

It is not a Zotero plugin. It runs alongside Zotero on your own computer and talks to it, so your data stays with you. Reading works against the desktop app with no key. For writes and group libraries you add your own Zotero API key.

It installs with one command: npx -y @oscardvs/zoteus
Code and setup: https://github.com/oscardvs/zoteus
Docs: https://zoteus.com

It is still new, so I would really like feedback, bug reports, or ideas for what to add. Thanks!
  • Could you do a step-by-step for a person that doesnt know a inch about coding?
    I really want to try it but even reading all that you have in github, I still dont know what I should do after installed the zip, how to plug it to my claude desktop or what should I do with the Zotero Key.
    (would be great to have something like screenshots, of stepss of small vid, somehtign like this for the not great with tech ppl)
  • I'm struggling to get Zoteus to build the search index. I have enabled local API and added an API key (read only API access). Still the index command times out without indexing a single item.

    Here is an error report from Claude Cowork (desktop):
    ug: zotero_index build consistently times out, no partial progress written

    Environment

    OS: Windows
    Client: Claude Desktop (Cowork mode)
    Zoteus transport: stdio (npx -y @oscardvs/zoteus)
    ZOTEUS_LOCAL: on
    ZOTEUS_EMBEDDINGS: local (@huggingface/transformers installed)
    Cloud API: connected (read access to personal library)
    Local API: connected (Zotero 7 running, "Allow other applications" enabled)
    Library size: very large

    Steps to reproduce

    Call zotero_index with action: "build"
    Call zotero_index with action: "status" after

    Expected: Index builds (possibly slowly); status shows incremental progress
    Actual: build returns Error: Request timed out every attempt; status always returns {"documents":0,"vectors":0,"items":0,"embedder":"local","builtFromVersion":0} — no partial progress is ever written to disk

    Notes

    zotero_whoami and zotero_index status both work fine
    Retried 6+ times; status never advances beyond 0
    The build appears to fail before writing anything, suggesting it may be crashing/timing out before the first flush
  • Hi @aguiarla. Thank you, this is useful feedback, and you're right: the docs assume a bit too much. Quick good news: you don't need the GitHub ZIP and you don't need to write any code. Zoteus installs by either double-clicking one file or pasting a small config block into Claude Desktop.

    Option A. one click (easiest):
    1. Download zoteus.mcpb from the latest release: https://github.com/oscardvs/zoteus/releases/latest
    2. Double-click it. Claude Desktop opens and asks to add the extension, accept.
    3. If it shows a small settings form, you can paste a Zotero API key there (see below) or leave it empty.

    Option B. manual:
    1. Install Node.js LTS from https://nodejs.org (click the big LTS button, then just Next -> Next -> Finish).
    2. In Claude Desktop: Settings -> Developer -> Edit Config. A file called claude_desktop_config.json opens.
    3. Paste this (or, if the file already has content, just add the "zoteus" block inside
    the existing "mcpServers"):
    {
    "mcpServers": {
    "zoteus": {
    "command": "npx",
    "args": ["-y", "@oscardvs/zoteus"],
    "env": { "ZOTERO_API_KEY": "PASTE_YOUR_KEY_HERE" }
    }
    }
    }

    4. The key: go to https://www.zotero.org/settings/keys (logged into zotero.org) ->
    Create new private key -> give it any name -> tick "Allow library access" (that's the only permission Zoteus needs for reading) -> copy the key into the config above. That key is simply how Zoteus talks to your Zotero library. Optional: if you use the Zotero desktop app and prefer to skip the key entirely, instead enable Zotero -> Settings -> Advanced -> "Allow other applications on this computer to communicate with Zotero" and delete the ZOTERO_API_KEY line.
    5. Save the file, fully quit and restart Claude Desktop.
    6. Start a new chat and try.

    I'm writing a step-by-step beginner guide for exactly this flow. Are you on Windows or Mac? And if you get stuck at any step above, tell me which one and what you see, and I'll walk you through it personally.

    Best, Oscar
  • Hi @Oby. Excellent bug report, thank you. This is a real limitation in how the build works today, not a setup mistake on your side.

    Here is what's happening: zoteroindex build currently does everything inside one blocking tool call, fetch all items (Web API, 100/page), chunk them, embed every passage, and only then write the index to disk. With local embeddings the passages are embedded one at a time on CPU, and the first run also downloads the 25 MB model. On a large library that's many minutes, so Claude Desktop's tool-call timeout fires long before, hence "Request timed out". And because nothing is persisted until the build fully completes, status stays at 0 and every retry starts from scratch.

    Workaround you can try directly, skip the embedding step for the first build by adding "ZOTEUS_EMBEDDINGS": "off" to Zoteus' env block in your Claude Desktop config:

    "env": { "ZOTEUS_EMBEDDINGS": "off", "ZOTERO_API_KEY": "..." }

    Restart Claude Desktop and build again. You'll get the full keyword (BM25) index much faster; semantic ranking comes back once the fix below ships. This also confirms the diagnosis: if the keyword-only build succeeds, we know the timeout is the embedding pass.

    The fix: reworking it now so that (1) build starts a background job and returns immediately, (2) status reports live progress (items fetched / passages / vectors), (3) partial progress is persisted to disk as it goes, so an interrupted build eaves a usable index and can resume, and (4) embeddings run in batches.

    Btw, roughly how many items is your library, and do you see CPU activity in the node/zoteus process while a build attempt runs?
  • Oby
    edited 9 days ago
    Thanks for the swift reply! As I installed Zoteus using the .dxt file I don't relly know where I would input the env variable. But I have the patience to wait until this is implemented, and test the new version.

    (I saw that you pushed out v1.2.0 today, but from the changelog it didn't seem like batch processing was part of today's updates.)


    EDIT: I now saw that an earlier part of the changelog had this improvement, and upon presenting Claude Cowork with the github commit message it seems like it was able to start asynchronous indexing. However, that was not the case when I first just asked it to do a sync. Perhaps the asynchronous mode is not well enough documented for the agent?

    If you want to continue this on github, I can make an issue there an post e.g. the log of the conversation in question if that is useful for debugging.
  • edited 9 days ago
    Hi @Oby. Right, v1.2.0 (today) is exactly the release that fix landed in; it's the "Semantic-search first-use UX" entry in the changelog. Everything from my last post shipped: zotero_index action:"build" now starts a background job and returns immediately, action:"status" reports live progress (items fetched / passages / vectors), partial progress is written to disk as it goes so an interrupted build resumes instead of starting over, there's an action:"stop", and embeddings run in batches instead of one at a time.

    On the .dxt: no env variable needed anymore. Just update the extension, download zoteus.dxt from the latest release (https://github.com/oscardvs/zoteus/releases/latest) and double-click it; Claude Desktop updates the existing install and keeps your settings.

    Your discoverability point is fair, and 1.2.0 tries to remove the need for the agent to know about the index tool at all: the first zotero_semantic_search now starts the build automatically in the background and replies with live progress plus an instruction to poll status and retry. The tool descriptions were also rewritten to steer agents to that flow without needing a commit message. (One note: asking the agent to "sync" likely routed it to zotero_sync, which is about Zotero's own syncing, not the search index, a plain "search my library for your topic" is what triggers everything automatically.)

    A GitHub issue with the conversation log would still be very welcome: https://github.com/oscardvs/zoteus/issues, especially if status ever stops advancing on your very large library after you update. The first successful build still downloads the 25 MB embedding model once, and a very large library takes a while to embed, but you should see the counters moving within seconds now.

    Best, Oscar
Sign In or Register to comment.