zotero-mcp
# zotero-mcp
`zotero-mcp` is the Research Workbench's capability-honest stdio adapter for Zotero 7.
It uses Zotero's built-in, GET-only local API for reads and the separately installed
Research Workbench Zotero extension for authenticated writes. It never opens
`zotero.sqlite` or the Zotero data directory.
The stdio entry supports MCP `2026-07-28`'s stateless `server/discover` lifecycle and
legacy initialize-based clients. Its static tool catalog is publicly cacheable for five
minutes, reducing repeated catalog transfer and prompt churn.
## Requirements and setup
- Node.js 20 or newer
- Zotero 7 for live use
- The Research Workbench Zotero extension for write tools
```sh
npm install
npm run build
npm test
node dist/src/index.js
```
Configuration:
- `ZOTERO_MCP_BASE_URL` defaults to `http://127.0.0.1:23119`. Only plain-HTTP URLs using the exact loopback hostnames `127.0.0.1`, `localhost`, or `[::1]` are accepted; userinfo is rejected and redirects are never followed.
- `ZOTERO_MCP_TOKEN_FILE` defaults to
`~/.research-workbench/zotero-bridge.json`.
The server always starts and advertises all 15 contracted tools. When Zotero or the
extension is unavailable, calls return the shared structured error envelope with an
actionable code and message.
## Capability notes
- Reads are local and read-only.
- Writes are narrow Zotero data-layer operations provided by the extension.
- Moving an item to trash is supported; permanent deletion is not exposed.
- Linked-URL attachments are supported; file-content upload is not.
- The item full-text endpoint is probed only when requested. Zotero on the target
machine currently returns 404 for `/api/users/0/items/<key>/fulltext`, so the tool
returns `unsupported_capability` rather than claiming abstract metadata is full text.
- `zotero_health.writeAuth` is true only when extension health explicitly confirms the
supplied token; the existence of a token file alone is not reported as valid auth.
## Tests
`npm test` is fully offline. A mock HTTP server replays checked-in, synthetic local-API
fixtures and covers Zotero-down, token-missing, extension-absent, stale-version, and
full-text-unsupported behavior. No automated test writes to a real Zotero library.
License: MIT. See [LICENSE](LICENSE).
TDQS
Scored across 15 tools
Most tools target a distinct Zotero resource and action, such as search_items, get_item, list_collections, and add_tags. There is minor overlap where get_item can optionally return children while get_item_notes specifically lists note children, but descriptions are clear enough to usually guide correct selection.
All tools use the zotero_ prefix and follow a consistent verb_noun snake_case pattern: search_items, get_item, list_collections, create_item, update_item, add_tags, trash_item. The one exception, zotero_health, is a simple and recognizable single-purpose action rather than a confusing deviation.
With 15 tools, this server sits at the upper boundary of a well-scoped toolset, and each tool maps to a meaningful Zotero operation. Read operations, write operations, collection management, tagging, attachments, and health checking are all represented without obvious redundancy.
The toolset covers core item search/read/create/update, note creation, tag adding, collection creation, and item trashing, but there are notable gaps: no remove-from-collection, no remove-tags, no note update/delete, and no restore-from-trash. The attach_link tool also explicitly does not support file-content uploads, which limits one common attachment workflow.