Skip to main content
Glama
README.md
# 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

B3.4/5.0

Scored across 15 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness3/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues