MCP server for Zotero integration - search, retrieve, and extract PDF text from your Zotero library
The Zotero MCP server implements 3 read-only tools with basic descriptions and parameter schemas. All tools have descriptions (10-192 chars) and input schemas with type information, but the schemas lack depth in validation constraints and error handling guidance. Parameter descriptions are present but minimal. Output schemas are not formally documented, responses are plain text/string rather than structured JSON objects. Tool naming follows verb-noun conventions (search_items, get_item, read_pdf) which is good, but compositions lack pagination, chaining IDs, and structured result formats expected in production tools. Error messages are present in code (e.g., 'Invalid itemKey format') but don't guide recovery actions. This is solidly mid-tier for a community tool.
Retrieve the details of a specified item in the Zotero library by itemKey.
Read a PDF attachment from a Zotero item. attachment_index selects which PDF (1-indexed, default=1). page_number reads a single page (1-indexed); if omitted, all pages are read.
Search items in the Zotero library by author and title (excluding attachments, up to 30 results).
All tools return plain text strings instead of structured JSON objects. LLMs cannot extract fields reliably for downstream tool calls. zotero_search_items returns concatenated text lines; zotero_get_item and zotero_read_pdf also return unstructured strings. This violates pattern:response-shaper and makes chaining tools difficult.
Output schemas are not documented. The MCP tool definitions do not declare what fields will be returned or their types. zotero_search_items returns item list details, but the agent cannot know in advance what fields are included (e.g., whether DOI or metadata are present). This prevents LLMs from planning downstream operations.
No pagination support in zotero_search_items. Search is capped at 30 results (hardcoded in code), but the tool does not expose limit/offset parameters or a next_cursor. If a user's Zotero library has >30 matching items, the agent cannot iterate beyond the first page.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 37 | - | v1 |
Parameter 'q' in zotero_search_items lacks validation and has no format constraint. The description says 'Search query string' but doesn't explain what query syntax is supported (does Zotero API accept AND/OR? wildcards? quoted phrases?). LLMs will guess and may pass invalid syntax.
itemKey validation is strict (8 uppercase alphanumeric only, checked in _validate_item_key), but the parameter description only says '8 uppercase alphanumeric character item key' without examples or enforcement guidance. If an LLM passes a lowercase key, the error 'Invalid itemKey format' is returned but doesn't explain the constraint clearly enough for self-correction.
zotero_read_pdf does not validate attachment_index or page_number ranges. Code sets default attachment_index=1 but doesn't check if the index exists or if page_number is within document bounds. An LLM passing page_number=9999 will silently return empty or error without guidance on valid ranges.
Error handling in make_zotero_request, make_crossref_request catches exceptions broadly and returns {'error': str(e)}. Stack traces and raw exception messages leak to the agent, which cannot act on them. No recovery guidance (e.g., 'Zotero server not running on localhost:23119, verify Zotero is open').
zotero_search_items response includes metadata like 'creatorSummary' but doesn't document which fields are always present, which are optional, and how to interpret them. A human-readable result is helpful but makes downstream parsing fragile, the agent cannot reliably extract item_key, doi, or publication for the next call.