Zoteus
Zoteus is an MCP server that gives AI assistants safe, local-first access to a Zotero library—search, cite, write, and ground answers in your own references.
Search your library: keyword/full-text search with filters (type/tag/collection/trashed), semantic/hybrid search, saved searches, and incremental sync deltas.
Retrieve and ground answers: get full item records, pull PDF full text/passages with page locators and character offsets, and export in BibTeX/RIS/CSL-JSON/HTML and more.
Cite accurately: format bibliographies and citations in ~2,800 CSL styles via citeproc-js or server-rendered Zotero styles; resolve style names.
Add and import: fetch metadata by DOI/arXiv/ISBN/PMID/URL, create/update items, attach files, and upload/download attachments.
Write safely: transactional create/update, reversible trash vs permanent delete (opt-in), optimistic concurrency/retry, and dry-run diffs.
Organize your library: manage collections, tags, saved-search definitions, and group libraries; audit tags against controlled vocabularies.
Annotate PDFs: add/delete highlights, underlines, and notes with exact passage anchoring.
Follow the scholarship: look up references, citations, and related works via OpenAlex/Crossref, flagging what is already in your library.
Operate flexibly: works with the desktop local API and/or cloud Web API, key-free local reads/writes, background index build/update with status polling, and a discoverable tool catalog.
Allows adding papers to Zotero using arXiv identifiers, fetching metadata automatically.
Allows adding papers by DOI, fetching metadata from DOI resolution.
Supports OpenAI embeddings for semantic search within your Zotero library.
Provides scholarly context graph integration via Semantic Scholar for following scholarship.
Provides complete access to your Zotero library – search papers, add by identifier, format bibliographies, semantic search over PDFs, and write back items.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ZoteusFind papers in my Zotero library about climate change"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Zoteus
Zoteus is an MCP server that gives Claude and other MCP clients access to a Zotero library: search, citations, adding items, safe writes, semantic search, and passages from PDFs.

npx -y @oscardvs/zoteusWhat it does
Zoteus connects an MCP client such as Claude Desktop, Claude Code, or Cursor to your Zotero library. It exposes 30 tools, namespaced zotero_*, that search the library by keyword or by meaning, return passages from your PDFs with page locators, format bibliographies with citeproc-js in any CSL style, add items by DOI or arXiv id, and create, edit, tag, and organize items with reversible writes. When the Zotero desktop app is running, reads and personal-library writes go to it directly and need no cloud API key; the Zotero Web API v3 is the fallback for sync, group libraries, and for when the app is closed. Zoteus is written in TypeScript, runs on your machine, and is MIT licensed.
Related MCP server: zotero-grounded-mcp
Install
For normal use there is nothing to download from GitHub: your MCP client fetches Zoteus with npx the first time it runs. If you are new to MCP servers, start with docs/getting-started.md.
Client | Command |
Claude Desktop (one-click) | download |
Claude Code |
|
Cursor / VS Code / Claude Desktop / Codex / Zed… |
|
claude.ai (web) | Add custom connector → your hosted URL (OAuth) |
Updating a desktop-extension install: manually installed extensions (
.mcpb, or the older.dxt) do not auto-update. Turn on Check for updates in the extension settings (or setZOTEUS_UPDATE_CHECK=true) and Zoteus asks GitHub once a day, then tells you in-chat viazotero_whoamiwhen a newer version exists; download the newzoteus.mcpband reinstall it to upgrade. The check is off by default.npxinstalls always run the latest published version.
A cloud API key is optional. Add one for sync, group libraries, and writes when the desktop app is not running; reads and personal-library writes work without a key against a running Zotero.
claude mcp add --transport stdio zoteus -e ZOTERO_API_KEY=xxxxx -- npx -y @oscardvs/zoteusGet a key at zotero.org/settings/keys. For key-free local reads and writes, enable Settings → Advanced → "Allow other applications on this computer to communicate with Zotero" in the desktop app.
Features
Search your own library. Hybrid keyword and semantic search over titles, abstracts, creators, and tags, plus full-text keyword search inside your PDFs and notes, with the matching passage returned together with its page number. Your own notes and PDF annotations are indexed under the item they belong to, so "where did I object to this?" is a question search can answer. Set
ZOTEUS_INDEX_FULLTEXT(or passfulltext:truetozotero_index) and semantic search also covers the body of every PDF, so a claim that never made it into an abstract is still findable.Format citations. Zoteus reads the citation data in your Zotero library and formats it with citeproc-js in any CSL style from the CSL styles repository.
Add a paper by identifier. Pass a DOI or arXiv id and Zoteus fetches the metadata and files the item. This works out of the box through built-in resolvers; a Zotero translation-server extends it to ISBN, PMID, and URLs (see
docs/resolver.md).Write back. Create items, edit, tag, and organize. Writes are versioned with optimistic-locking retries, trash is reversible by default, and permanent deletion is opt-in and confirmation-gated.
Write straight to the desktop app. Personal-library writes go to your running Zotero, with no cloud API key. On Zotero 10+ this uses the local API behind a key you grant once ("Always Allow"); on Zotero 9 and earlier, whose local API is read-only, it uses the connector protocol the browser extensions use. The cloud Web API is the fallback for group libraries and for when the app is not running.
Annotate PDFs and attach files.
zotero_annotateadds highlights, underlines, and notes, the same objects the Zotero PDF reader creates. Quote the passage and Zoteus locates it in the PDF and anchors the annotation to the lines it occupies, wrapping and hyphenation included, so no page coordinates are needed.zotero_attach_filestores a local file or a URL as an attachment under any item.Ground claims in the PDF.
zotero_get_fulltextreturns the relevant passage with character offsets, the nearest heading, and a page locator. When Zotero has not indexed the PDF or EPUB, it extracts the text on the fly, from the running desktop app or from Zotero's own storage folder, so a file added a minute ago is readable immediately. It also returns a PDF's table of contents (outline:true) and any page range on demand, so working through a 400-page book costs a few small calls rather than one that returns the whole book.Follow the literature.
zotero_scholarlooks up a paper's references, citing works, and related works through OpenAlex, with Crossref as a fallback, and can flag which of them are already in your library.Agent support. 30 tools with structured outputs, MCP Resources and Prompts, and a generated tool tree for the code-execution-with-MCP pattern.
How it works
Install with one
npxcommand, or the one-click.mcpb.Connect by running the desktop app for key-free local access, or by pasting your Zotero API key.
Ask. Your MCP client can now search, cite, add to, and organize your library.
Zoteus detects a running Zotero desktop app and talks to it directly: the key-free local API for reads (full PDFs, saved-search results, the semantic-search index build), and the app itself for personal-library writes (imports, annotations, attachments, trash). The cloud Web API v3 is the fallback, and it is still required for sync, group libraries, and writes when the app is not running. Details: docs/writing.md.
Semantic search setup. The first
zotero_semantic_searchbuilds the library index in the background. On very large libraries you can also runzotero_index(action:"build") yourself, then poll action:"status" until it is done. The build pages your library through the same local-first path as every other read, so it needs no cloud API key while the desktop app is running. That covers your personal library and, on Zotero 10+, any group library the app holds; a key is needed when the app is closed, and for a group the app does not hold.
Embedding through an API on a large library. A full-text build of a 10k-item library is tens of thousands of requests, and at the default pacing the rate rides at OpenAI's tokens-per-minute ceiling whatever your tier. A rate-limited request now backs off and retries rather than failing the build, and a build that still ends short keeps everything it indexed: run
zotero_index action:"build"again and it resumes, embedding only the passages that have no vector yet (action:"refresh"is the one that starts over). To pace it up front, setZOTEUS_EMBED_BATCH_SIZE=256andZOTEUS_EMBED_BATCH_DELAY_MS=8000. Seedocs/semantic-search.md.
Vector ranking is opt-in. Keyword (BM25) search works out of the box everywhere. On-device vectors need
@huggingface/transformers, which the desktop-extension bundle cannot ship (the resolved dependency tree, onnxruntime's native binaries included, is about 700 MB): install it into a directory of its own (mkdir -p ~/.zoteus-deps && cd ~/.zoteus-deps && npm init -y && npm i @huggingface/transformers) and setZOTEUS_TRANSFORMERS_PATHto~/.zoteus-deps/node_modules. Notnpm i -g: Claude Desktop runs the server on its own built-in Node, so a global install under a version manager sits next to a Node the extension never executes. When vectors are unavailable Zoteus says so inzotero_indexstatus,zotero_whoami, andzotero_semantic_searchrather than quietly returning nothing. Seedocs/semantic-search.md.
Configuration
Variable | Default | Purpose |
| none | Cloud auth (sync, groups, writes without the desktop app; optional otherwise) |
|
|
|
| none | Pre-provision the Zotero 10+ desktop write key (else granted once, in-app) |
|
|
|
| provider default | The model that provider embeds with, |
|
| Weight precision of the on-device model: |
|
| Passages per embedding call. Lower it if an API provider rejects a whole request (OpenAI answers |
|
| Pause between embedding calls. Raise it if an API provider rate-limits a large build: |
|
| Index your own child notes and PDF annotations as searchable passages |
|
| Index PDF body text for semantic search (opt-in; costly) |
|
|
|
| none | Where to find |
|
| Must be |
Full table in docs/configuration.md. To run a shared or remote instance, see docs/remote-oauth.md (self-host the OAuth remote on loopback or behind your own proxy).
Documentation
zoteus.com/docs · Getting started · Configuration · Import & resolver · Architecture · Safe writes · Citations · Semantic search · Scholarly context · Code execution · Deployment
Privacy
Zoteus runs locally, collects nothing, and has no telemetry. Your library data flows only between your machine and the services you configure (Zotero, and optionally scholarly-graph or embedding providers), directly and under your own keys. Full policy: PRIVACY.md.
Contributing
Contributions are welcome; see CONTRIBUTING.md. Zoteus is MIT licensed.
Acknowledgements
Built on the Model Context Protocol, the Zotero Web API, citeproc-js, and the Citation Style Language. Not affiliated with or endorsed by the Corporation for Digital Scholarship / Zotero.
Available Tools
30 toolssearch_toolsDiscover Zotero toolsARead-only
Discover the available Zotero tools by keyword — useful for progressive disclosure when you do not want to load every tool definition up front (the code-execution-with-MCP pattern). Pass an optional query (matched against tool names, titles, and descriptions) and detail ("names" or "descriptions", default "descriptions"). Returns the matching zotero_* tools so you can pick the right one for a task. With no query, returns the full catalog.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Keyword to match against tool names/titles/descriptions. | |
| detail | No | How much to return (default "descriptions"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true, so the description adds value by explaining the progressive disclosure pattern and behavior with no query (returns full catalog). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, no wasted words. Every sentence serves a clear function: purpose, use case, parameter explanation, and result description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains that it returns matching zotero_* tools. Could be slightly more explicit about the structure of returned data (e.g., tool definitions), but sufficient for an agent to understand usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning beyond schema: explains that query matches against 'tool names, titles, and descriptions', and clarifies detail default and output difference ('descriptions' vs 'names').
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it discovers Zotero tools by keyword, using specific verb 'Discover' and resource 'Zotero tools'. It distinguishes from siblings like zotero_schema or action tools by focusing on tool discovery itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit context: 'useful for progressive disclosure when you do not want to load every tool definition up front'. It does not explicitly say when not to use, but the use case is clear and well-motivated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_annotateAnnotate a PDF (highlights, notes)A
Add or delete Zotero PDF annotations (highlights, underlines, notes), the same objects you create in the Zotero PDF reader. action:"add" needs parent (a regular item key OR a PDF attachment key) and annotations: each with type (highlight|note|underline, default highlight), text (the exact passage to highlight), optional comment, color, page (0-based page index). You do not need page coordinates: give the passage in text and it is located in the PDF and anchored to the exact lines it occupies, so quoting a passage is enough to highlight it. Pass page to disambiguate a passage that repeats, or occurrence to pick among repeats; pass position ({"pageIndex":N,"rects":[[x1,y1,x2,y2],...]} in PDF points, bottom-left origin) only to place a highlight yourself. action:"delete" trashes the annotations in annotation_keys. Writes go to the running Zotero desktop app for your personal library (via its connector protocol, or its local-API writes where available), otherwise to the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | Default "add". | |
| parent | No | Item key or PDF attachment key to annotate. | |
| library_id | No | ||
| annotations | No | Annotations to add. | |
| library_type | No | ||
| annotation_keys | No | Annotation keys to trash (action:"delete"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses key behavioral traits: delete trashes annotations, text is located and anchored to exact lines without page coordinates, occurrence disambiguates repeated passages, and writes go to the running Zotero desktop app or fall back to the cloud Web API. No contradiction with the annotations is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense and well organized. It front-loads the core operation, then highlights the most valuable guidance (no coordinates needed, occurrence, custom position), then deletion behavior and write routing. Every sentence carries practical information for invoking the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers operation modes, required parent context, annotation types, ambiguity handling, and API routing. It does not describe the response shape or error behavior, and there is no output schema, but an agent still has enough information to construct a valid invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds significant meaning beyond the 67%-coverage schema: it explains the difference between item keys and PDF attachment keys, defines text as the exact passage, notes that page is 0-based, and gives the position object format. It does not cover every parameter such as library_id or sort_index refiners, but the schema covers those adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: add or delete Zotero PDF annotations such as highlights, underlines, and notes. It also ties them to the objects created in the Zotero PDF reader, making the tool's intent precise and distinguishable from the sibling item, collection, and tag tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: annotate a PDF via a parent item key and annotation definitions, or delete annotations via annotation keys. It does not explicitly name sibling tools or state when not to use it, but the add/delete modes and required inputs make the intended use obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_attach_fileAttach a file (PDF, snapshot) to an itemA
Add a stored file attachment (e.g. a PDF full text) under an existing item. Give parent (the item key) and either url (Zoteus downloads it, then stores it) or path (a file on the machine running Zoteus). filename and content_type are inferred when omitted. Saves through the Zotero desktop app when one is reachable (Zotero 10+ local API; you may be asked once to allow Zoteus write access, choose "Always Allow"), and otherwise through the cloud Web API, which needs ZOTERO_API_KEY with file access and uses your Zotero file-storage quota. url works on every setup including a remote/hosted Zoteus that cannot see your desktop, so prefer it over path unless the file really is on the server. Returns the new attachment key.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to download the file from; works on remote/hosted servers. | |
| path | No | Filesystem path to the file, on the machine running Zoteus. | |
| title | No | Attachment title, e.g. "Full Text PDF". | |
| parent | Yes | Key of the parent item to attach the file to. | |
| filename | No | File name to store; inferred from path/url if omitted. | |
| library_id | No | Group library to attach in; forces the cloud path. | |
| content_type | No | MIME type; inferred from the extension if omitted (pdf -> application/pdf). | |
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing that the write may route through the Zotero desktop app or cloud Web API, that the user may be prompted to allow write access, and that cloud usage requires ZOTERO_API_KEY and consumes file-storage quota. It also states the return value as the new attachment key. These are meaningful behavioral details beyond readOnlyHint/destructiveHint/openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: core purpose, required parameters, parameter alternatives, storage/auth behavior, and return value. It is front-loaded with the main action and then adds necessary operational detail without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers all essential operational aspects: how to identify the parent, how to supply the file, local vs cloud routing, authentication requirements, quota implications, and the returned key. The schema covers the remaining parameter details, and the absence of an output schema is mitigated by explicitly stating the return value.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high at 88%, and the description still adds value by explaining the semantic difference between `url` and `path`, including remote/hosted setups, and noting that `filename` and `content_type` are inferred. It also clarifies that `library_id` forces the cloud path. This is useful guidance beyond the schema's basic descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Add a stored file attachment (e.g. a PDF full text) under an existing item.' It clearly scopes the operation as attaching to an existing item, which distinguishes it from sibling creation tools like zotero_create_items. The title and description together leave no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong usage context by explaining when to use `url` versus `path` and explicitly recommends 'prefer it over `path` unless the file really is on the server.' It also explains the local-desktop versus cloud-Web API routing, which helps an agent choose the right setup. However, it does not explicitly name sibling tools or state when not to use this tool in favor of another, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_attachmentZotero attachments (files)ADestructive
Upload, download, or inspect attachment files. action: "upload" stores a file as a Zotero attachment using the full File Storage protocol (provide url to have Zoteus fetch it, or file_path for a file on the machine running Zoteus; optional parent_item to attach it under an item, title, content_type) and returns the new attachment key; "download" fetches an attachment's file to a local path (provide item_key; optional save_path, default under the Zoteus data dir) and returns the path and byte count; "info" returns an attachment item's metadata. File bytes are written to / read from disk, never streamed through the conversation. Upload/download use the cloud Web API and your file-storage quota. When Zoteus runs on a different machine than Zotero, file_path refers to the server's disk, so use url instead.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to download and upload instead of `file_path`; works on remote/hosted servers. | |
| title | No | ||
| action | Yes | ||
| item_key | No | Attachment item key (download/info). | |
| file_path | No | File to upload, on the machine running Zoteus. | |
| overwrite | No | Allow `save_path` to replace a file that already exists (default false). | |
| save_path | No | Where to write the downloaded file. | |
| library_id | No | ||
| parent_item | No | Parent item key to attach under (upload). | |
| content_type | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as non-read-only and destructive, and the description adds substantial context: file bytes are read/written to disk and never streamed through the conversation, upload/download consume cloud Web API and file-storage quota, and file_path refers to the server's disk. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition opens with a concise one-line summary and then uses a structured, dense second sentence to cover all three actions, parameters, defaults, and caveats. Every clause adds either behavioral or parameter knowledge without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-mode tool with no output schema, the description covers return values, disk behavior, quota usage, and the remote-host caveat well. It leaves minor gaps around library_id/library_type defaults and explicit overwrite behavior, but those are partially covered by the schema and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds real meaning beyond the schema for most action-relevant parameters: url vs file_path, parent_item, title, content_type, item_key, save_path default, and return forms. It does not clarify library_id/library_type selection, and schema coverage is only 55%, so it earns a 4 rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names the resource (attachment files) and three concrete verbs: upload, download, inspect. This makes the tool's purpose immediately clear, but it does not contrast it with the similarly named sibling zotero_attach_file, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives per-action guidance: upload with url/file_path, download with item_key and save_path, info for metadata. It also provides a clear conditional rule to use url instead of file_path on remote hosts. However, it does not explicitly state when to prefer alternatives among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_bibliographyServer-rendered bibliography (library items)ARead-only
Produce a formatted bibliography for items already in a Zotero library, rendered server-side by Zotero in a CSL style. Provide item_keys and optionally style (name or CSL id; Zotero default is chicago-note-bibliography), locale, and linkwrap. Returns XHTML. Note: this endpoint is item-only and capped at 150 items. For arbitrary CSL-JSON or items not in the library, use zotero_format_bibliography instead.
| Name | Required | Description | Default |
|---|---|---|---|
| style | No | Style name or CSL id. | |
| locale | No | Locale (e.g. en-US). | |
| linkwrap | No | Wrap URLs/DOIs in links. | |
| item_keys | Yes | Library item keys (max 150). | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true. The description adds beyond this: it specifies the tool is server-rendered, returns XHTML, is item-only, and capped at 150 items. No contradictions with annotations. The description provides valuable behavioral context not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the main purpose, then options, then a note about limits and an alternative. Every sentence adds value, no redundancy, and it is structured logically for quick parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, no output schema), the description covers purpose, usage limits, alternative tool, output format (XHTML), and parameter hints. It could mention error handling or behavior when items are missing, but it is reasonably complete for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 6 parameters with 67% description coverage. The description explains item_keys, style, locale, linkwrap with added context (e.g., 'style (name or CSL id; Zotero default is chicago-note-bibliography)'). It does not mention library_id and library_type, but these are common and likely inferred from the library context. The description adds meaning beyond the schema for most parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Produce a formatted bibliography for items already in a Zotero library, rendered server-side by Zotero in a CSL style.' This provides a specific verb and resource, and it distinguishes from the sibling tool zotero_format_bibliography by noting that this tool is for library items only, while the other handles arbitrary CSL-JSON.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: 'item-only and capped at 150 items.' It also provides an alternative: 'For arbitrary CSL-JSON or items not in the library, use zotero_format_bibliography instead.' This gives clear context on usage boundaries and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_create_itemsCreate or update Zotero itemsADestructive
Create new items or update existing ones in a single batch (the server auto-chunks into groups of 50). items is an ARRAY of item-data objects; each object has itemType as a plain string (e.g. "journalArticle", "book", "preprint", "report") plus its valid fields, creators (each {creatorType, firstName, lastName} or {creatorType, name}), tags ([{tag}]), and collections (array of 8-char collection keys). To UPDATE an existing item, also include its key and current version; to CREATE, omit both. Every item is validated against the Zotero schema before anything is sent — if any item is invalid, nothing is written and the problems are returned. Use zotero_schema to discover valid fields/creator types for an itemType. Writes go to the cloud Web API (requires ZOTERO_API_KEY).
Example:
{"items": [{"itemType": "journalArticle", "title": "The Role of Metadata in Machine Learning", "creators": [{"creatorType": "author", "firstName": "Ada", "lastName": "Lovelace"}], "date": "2024-01-15", "DOI": "10.1234/example.5678", "tags": [{"tag": "ml"}], "collections": ["ABCD1234"]}]}| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | Array of Zotero item-data objects (itemType + fields; include key+version to update). Example: {"items":[{"itemType":"journalArticle","title":"The Role of Metadata in Machine Learning","creators":[{"creatorType":"author","firstName":"Ada","lastName":"Lovelace"}],"date":"2024-01-15","DOI":"10.1234/example.5678","tags":[{"tag":"ml"}],"collections":["ABCD1234"]}]} | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the write-related annotations, the description discloses batching behavior, atomic validation (nothing is written if any item is invalid), API-key/auth requirements, and version-based update semantics. This is rich behavioral context that structured fields alone would not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded: core purpose first, then behavioral details, then schema guidance and auth requirements, with a concrete example at the end. Every sentence contributes actionable information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write tool with no output schema, it covers the essential invocation context: batch size, atomic failure behavior, auth, item structure, and how to distinguish create from update. The main gaps are the undocumented optional library parameters and the shape of a successful response, but the required payload is specified in sufficient detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The items parameter is thoroughly explained: itemType as a plain string, creator object shapes, tags, collections, and create-vs-update key/version rules. However, schema description coverage is only 33%, and library_id and library_type are left undescribed in both the schema and the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence identifies the exact operation (create or update Zotero items) and its batch scope, including server-side auto-chunking into groups of 50. The key/version distinction further separates creation from update, helping an agent distinguish this from single-item siblings like zotero_update_item.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit rules for when to create versus update: include key and version to update, omit them to create. It also directs the agent to zotero_schema for discovering valid fields and creator types. It does not explicitly name a single-item alternative or state when not to use this tool, but the batch framing makes the intended context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_delete_itemsPermanently delete Zotero itemsADestructive
PERMANENTLY and IRREVERSIBLY delete items by key (this purges them — it is NOT the trash). Prefer zotero_trash_items, which is reversible. This tool is disabled unless the server is started with ZOTEUS_ALLOW_DELETE=true, and additionally requires confirm: true on every call. For the personal library it goes through the running Zotero desktop app when that app supports local-API writes, otherwise the cloud Web API. The current library version is used as a precondition; the operation auto-chunks to 50 keys per request.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to proceed with permanent deletion. | |
| item_keys | Yes | Item keys to permanently delete. | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, but the description adds critical details: the operation is irreversible and purges (not trash), requires explicit confirmation, is disabled without a server flag, and routes via local app or cloud API. It also notes the library version precondition and auto-chunking, going well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense paragraph that front-loads the critical warning and then details requirements and behavior. Every sentence adds essential information with no redundancy, making it appropriately concise for a high-stakes operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with no output schema, the description fully covers safety (irreversible, requires confirm), operational prerequisites (server flag), behavioral specifics (chunk size, library version precondition), and routing (local app vs. cloud API). It gives an agent everything needed to decide and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers confirm and item_keys with descriptions (50% coverage), and the description reinforces their meaning: 'requires `confirm: true`' and 'delete items by key.' It also mentions auto-chunking to 50 keys, which adds operational context. However, it does not explain library_id/library_type beyond the schema, so it doesn't fully compensate for the 50% gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'PERMANENTLY and IRREVERSIBLY delete items by key' with a specific verb and resource, and explicitly distinguishes from the reversible 'zotero_trash_items'. This clearly defines the tool's unique function among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Prefer zotero_trash_items, which is reversible' and details the server flag requirement and the `confirm: true` prerequisite. This provides clear when-to-use and when-not-to-use guidance, plus operational constraints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_exportExport Zotero itemsARead-only
Export items in a bibliographic format and return the raw text. Choose format (bibtex, biblatex, better-biblatex, ris, csljson, csv, mods, tei, coins, rdf_*, refer, wikipedia, bookmarks). biblatex is Zotero's STOCK translator via the cloud Web API; BBT-specific options (citation-key generation, sentence-case, biblatexExtendedNameFormat, unicode→LaTeX) are NOT available there. better-biblatex uses the local desktop Better BibTeX plugin (your configured BBT export options apply) and is only available when desktop Zotero + BBT are running; it degrades to built-in biblatex otherwise. Narrow with item_keys, collection_key, q, or item_type. A limit (default 50) is always applied. For styled human bibliographies use the bibliography tools.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | ||
| limit | No | ||
| format | Yes | ||
| item_keys | No | ||
| item_type | No | ||
| library_id | No | ||
| library_type | No | ||
| collection_key | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that export is read-only (matches readOnlyHint) and returns raw text. Explains better-biblatex availability and degradation, and that a limit is always applied. No annotation contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with main purpose, then details format options, narrowing, and limit. Each sentence provides essential information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (8 params, multiple enums, no output schema), the description is complete: explains output, format behaviors, narrowing, limit, and points to alternative tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description adds meaning for all parameters: explains format options in detail, distinguishes better-biblatex, and explains how to use item_keys, collection_key, q, item_type, and limit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Export', the resource 'Zotero items', and the output 'raw text'. It distinguishes from sibling tools like bibliography tools, which are for styled bibliographies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use (for raw text) and when not to (for styled bibliographies, use bibliography tools). Provides guidance on choosing between better-biblatex and biblatex, and explains narrowing options.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_format_bibliographyFormat a bibliography (citeproc / any CSL style)ARead-only
Render a formatted bibliography in any CSL style using citeproc-js — no Zotero library write required. Provide either items (an array of CSL-JSON objects, e.g. from zotero_import or external metadata) or item_keys (library items, which are exported to CSL-JSON first). Choose style (a name like "APA 7th" or a CSL id; default "apa"), locale (default "en-US"), and format (html/text/rtf; default html). The formatted bibliography text is returned. Use this for arbitrary items or styles; for items already in the library you can also use zotero_bibliography (server-rendered).
| Name | Required | Description | Default |
|---|---|---|---|
| items | No | CSL-JSON items to format. | |
| style | No | Style name or CSL id (default "apa"). | |
| format | No | Output format (default html). | |
| locale | No | Locale (default "en-US"). | |
| item_keys | No | Library item keys (exported to CSL-JSON). | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint, and the description adds context by stating 'no Zotero library write required' and mentioning it uses citeproc-js, which is client-side rendering. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured paragraph of three sentences. It is front-loaded with the main purpose, covers all key aspects without redundancy, and is highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's seven parameters and no output schema, the description is quite complete. It explains input methods, main parameters, defaults, and comparison with a sibling. It could mention return format more explicitly, but it's sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 71%, and the description adds value by explaining the two input methods (items vs item_keys) with examples, and noting values like style='APA 7th' and default values. It goes beyond the schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Render a formatted bibliography in any CSL style' and explicitly distinguishes from the sibling tool zotero_bibliography by noting 'no Zotero library write required' and mentioning the alternative for library items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool vs the sibling: 'Use this for arbitrary items or styles; for items already in the library you can also use zotero_bibliography.' It also explains the two input methods (items vs item_keys).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_fulltextAttachment full-textADestructive
Not a search — to find which items contain a term, use zotero_search_items with qmode=everything. This reads, sets, or tracks one attachment's already-extracted full text by key. action: "get" returns the indexed text content plus indexing stats for an attachment item (only attachment items have full text; returns found:false if none); "set" stores extracted text for an attachment (provide content and the indexing counts); "since" returns the map of attachment keys whose full text changed after a given library version (useful for incremental indexing). Only attachment items support full text. "get" and "since" read through the running Zotero desktop app when there is one (no cloud key needed), otherwise the cloud Web API; "set" always writes via the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | Library version for "since" (default 0). | |
| action | Yes | ||
| content | No | Extracted text (set). | |
| item_key | No | Attachment item key (get/set). | |
| library_id | No | ||
| total_chars | No | ||
| total_pages | No | ||
| library_type | No | ||
| indexed_chars | No | ||
| indexed_pages | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the runtime access path: 'get'/'since' read through the running Zotero desktop app when present (no cloud key needed), otherwise the cloud Web API, while 'set' always writes via the cloud Web API. Also discloses the found:false fallback for attachments with no full text and the attachment-only domain constraint. This is consistent with readOnlyHint:false and destructiveHint:true since 'set' overwrites stored text — no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence front-loads the most decision-relevant fact (this is not a search), and the description is dense with no filler. It loses a point for repeating the attachment-only constraint twice ('only attachment items have full text' / 'Only attachment items support full text') and for sentence length that mildly taxes scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-action tool with 10 parameters and no output schema, the description covers a lot: per-action semantics, return shapes for 'get' and 'since', the attachment-only rule, and the desktop-vs-cloud access behavior. Gaps remain — what 'set' returns, and how library_id/library_type scope the 'since' map — so it is not fully complete for the most complex action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 30%, and the description partially compensates by explaining the action enum, mapping 'since' to a library version, and grouping content + 'indexing counts' for 'set'. However, library_id, library_type, and the individual count fields (total_chars, total_pages, indexed_chars, indexed_pages) are never individually clarified, leaving most parameters under-documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with an explicit exclusion that separates it from the search sibling ('Not a search — to find which items contain a term, use zotero_search_items'), then states a concrete verb+resource: 'reads, sets, or tracks one attachment's already-extracted full text by key.' Each action (get/set/since) is named with its distinct purpose, so the tool cannot be confused with any sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names an alternative and the exact condition for choosing it: use zotero_search_items with qmode=everything to find which items contain a term rather than this tool. Also gives scope guidance ('Only attachment items support full text') and when 'since' is useful ('useful for incremental indexing'). However, it never differentiates this tool from the sibling zotero_get_fulltext, leaving one real ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_get_fulltextGet attachment full text / passages / outline (read-only)ARead-only
Retrieve an item's PDF or EPUB text for grounding. Pass a parent item_key (its best PDF/EPUB attachment is resolved automatically) or an attachment key. With query, returns the top relevant passages with locators (char offsets, nearest section, and a page); with page_range (e.g. "3-7"), returns just those pages, re-extracted from the PDF so the span is exact; with outline:true, returns the PDF's table of contents with page numbers (the cheapest way to decide which pages to read next); with none of them, returns a truncated head. Text comes from Zotero's full-text index when available; when the attachment is NOT indexed yet, the file itself is read and parsed on the fly (fallback, on by default; set fallback:false to disable), so a PDF added minutes ago still returns text (marked fulltextSource:"pdf" or "epub", with fileSource saying where the bytes came from). The file is read from the running Zotero desktop app, else straight out of the local Zotero storage folder, else downloaded from Zotero cloud storage. Page numbers are exact whenever the PDF was parsed, and otherwise an estimate (pageApprox) unless precise_pages:true. Read-only; the indexed text is served by the running Zotero desktop app when there is one, otherwise by the cloud Web API. Use this to cite a claim with a page after finding an item via zotero_search_items / zotero_semantic_search.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Return top passages relevant to this query. | |
| outline | No | Return the PDF's table of contents (heading, page, nesting level) instead of text. | |
| fallback | No | When Zotero has no indexed full text for the attachment, read the file itself and extract it directly (default true). | |
| item_key | Yes | Parent item key or attachment key. | |
| max_chars | No | Best-effort cap on total returned text (default 12000); a single passage is never split, so one passage may slightly exceed it. | |
| library_id | No | ||
| page_range | No | Page span like "3-7" (1-based, inclusive). PDFs only. | |
| library_type | No | ||
| max_passages | No | Max passages (default 5). | |
| precise_pages | No | Re-extract the PDF for exact page numbers (already the default with `page_range`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses fallback behavior (indexed vs on-the-fly parsing), source resolution order (desktop app, local storage folder, cloud storage), page-number exactness (exact vs pageApprox), and return markers (fulltextSource/fileSource). This is rich behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but each clause earns its place given the tool's 10 parameters and multiple modes. It is front-loaded with the core action and then organized by behavior, fallback, sources, and precision; it could trim a little redundancy around read-only serving, but it remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description covers all modes, defaults, source fallbacks, precision behavior, and return metadata. The only structured coverage missing (no output schema) is compensated by naming returned fields like fulltextSource, fileSource, and pageApprox.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 80%, and the description still adds substantial semantics: item_key accepts parent attachments resolved automatically, page_range is exact and PDF-only, outline is a cheap TOC view, precise_pages is already defaulted with page_range, and fallback materializes text from an unindexed file. It explains how the parameters interact, not just what they are.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Retrieve an item's PDF or EPUB text for grounding.' It then enumerates the four retrieval modes (query, page_range, outline, head), which makes the tool's scope unmistakable and distinguishes it from the sibling search tools by tying it to citing a claim after item discovery.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: use it after zotero_search_items / zotero_semantic_search to ground citations with page numbers, and advises outline as the cheapest way to decide which pages to read next. It does not explicitly state when-not-to-use or name alternative full-text tools like zotero_fulltext, so it stops short of full five-level routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_get_itemGet a Zotero itemARead-only
Fetch one item by its key, returning the full item record (itemType, all bibliographic fields, creators, tags, collections, relations, version). Optionally set include_children to also return the item's child notes and attachments. Use include to additionally request rendered output: "bib" (formatted bibliography entry), "citation" (inline citation), or "csljson" (CSL-JSON for downstream formatting); combine with style (a CSL style id, default chicago-note-bibliography) and locale. The returned version is required if you later update or delete this item.
| Name | Required | Description | Default |
|---|---|---|---|
| style | No | CSL style id for bib/citation (default chicago-note-bibliography). | |
| locale | No | Locale for bib/citation, e.g. en-US. | |
| include | No | Extra rendered content: "bib", "citation", or "csljson". | |
| item_key | Yes | The 8-character Zotero item key. | |
| library_id | No | ||
| library_type | No | ||
| include_children | No | Also fetch child notes/attachments. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint and openWorldHint. The description adds valuable behavioral details: the returned fields, the importance of the 'version' field for later updates/deletes, and the effect of optional parameters. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph that front-loads the main action and then explains optional features. Every sentence serves a purpose without redundancy. It is concise yet comprehensive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, no output schema), the description covers the main action, return fields, optional children, and formatted output. It also explains the version field's role. No critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 71%; the description adds meaning by explaining how parameters like 'include', 'style', and 'locale' work together, and clarifies the optionality of 'include_children'. For undocumented parameters like 'library_id' and 'library_type', the description does not add value, but overall it enhances parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Fetch' and the resource 'one item by its key', listing the full record fields. It distinguishes this tool from search, update, and other sibling tools by its specific function of retrieving a single item.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on optional parameters like 'include_children' and 'include', and how to combine 'include' with 'style' and 'locale'. It does not explicitly contrast with sibling tools, but the context is clear for a retrieval tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_groupsList Zotero groupsARead-only
List the group libraries the current API key can access, with each group's id, name, type, item count, and edit permissions. Use a returned group id with the library_id/library_type:"group" parameters of other tools to operate on that group library. Requires a cloud API key.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond annotations (readOnlyHint, openWorldHint) by specifying that it lists what the API key can access, and it enumerates the fields returned. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff. Every sentence adds value: first explains what the tool does, second explains how to use the output. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list operation with no parameters and no output schema, the description is complete: it states what is returned and how to use the results. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters (schema coverage 100%), so the description is not required to explain parameters. Baseline for 0 parameters is 4, and the description meets that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists group libraries accessible by the current API key, with specific fields (id, name, type, item count, edit permissions). It distinguishes from sibling tools like zotero_whoami (user info) and zotero_search_items (search items) by focusing on groups and their usage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains how to use returned group ids with other tools via parameters, and mentions the requirement for a cloud API key. It provides clear context for use but does not explicitly state when not to use it or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_importImport items by identifier or URLA
Resolve bibliographic metadata to Zotero item-data and optionally save it to your library. action: "by_identifier" resolves a DOI, ISBN, PMID, arXiv id, or ADS bibcode (set identifier); action: "by_url" scrapes a web page (set url) and may return multiple choices to pick from. Set save_to_library:true (and optionally collection_key) to persist the resolved items — saved into the running Zotero desktop app when available, otherwise via the cloud Web API (requires ZOTERO_API_KEY); otherwise the resolved metadata is returned without saving. When a Zotero translation-server is reachable (ZOTEUS_TRANSLATION_SERVER_URL, default http://127.0.0.1:1969) it is the primary path; if none is running, DOI and arXiv ids fall back to built-in resolution (OpenAlex/Crossref and the arXiv API respectively) — the result then carries a source field ("scholar" or "arxiv"). ISBN/PMID/bibcode and web URLs require a translation-server.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Web page URL to scrape (needs a translation-server). | |
| action | Yes | ||
| attach_url | No | File URL (e.g. an arXiv PDF) to download and attach as a stored attachment to the (single) imported item. Works on every save path: the desktop app when one is reachable, otherwise the cloud Web API. | |
| identifier | No | DOI (10.…), arXiv id (YYMM.NNNNN), ISBN, PMID, or ADS bibcode. | |
| library_id | No | ||
| attach_title | No | Title for the attached file, e.g. "Full Text PDF". | |
| library_type | No | ||
| collection_key | No | Collection to add saved items to: an 8-char collection key or a Zotero treeViewID like "C20". | |
| save_to_library | No | Persist the resolved items — into the running Zotero desktop app when available, otherwise the cloud Web API (needs a cloud key). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only provide `readOnlyHint: false`, `destructiveHint: false`, and `openWorldHint: true`. The description adds essential behavioral context: optional persistence, desktop-vs-cloud path selection, API-key requirement, translation-server dependency, fallback behavior for DOI/arXiv, and the `source` field on results. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every clause earns its place: action modes, save behavior, server dependency, fallback logic, and auth requirements are all covered without redundancy. It is front-loaded with the core purpose and then layers conditional details naturally.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no output schema, this description covers the major decision paths: identifier vs URL, save vs no-save, local vs cloud, server vs fallback. It also hints at output shape with `source` and multiple-choice results. Some optional parameters are not elaborated and the full return format is only partially described, leaving minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description enriches key parameters: `action` is fully explained with routing behavior, `identifier` gets the list of accepted formats, and `save_to_library` is clarified with persistence semantics and cloud-key requirements. Schema coverage is 67%, and the description compensates for much of that gap, though `library_id`, `library_type`, and `attach_title` remain less explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: "Resolve bibliographic metadata to Zotero item-data and optionally save it to your library." It then distinguishes the two modes (`by_identifier` vs `by_url`) clearly. This separates it from sibling tools like `zotero_create_items` or `zotero_search_items` without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives excellent when-to-use guidance: when to use `by_identifier` vs `by_url`, when saving happens, when the desktop app vs cloud API is used, and when a translation-server is required versus built-in fallback. It does not explicitly name sibling tools as alternatives, so the exclusions are slightly less direct than ideal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_indexBuild the semantic search indexADestructive
Manage the local hybrid-search index used by zotero_semantic_search. Every job runs in the background on the server, so this tool returns immediately and never blocks on large libraries. THREE write actions, and picking the right one matters: action: "update" is the cheap one and should be the default for a library that is already indexed; action: "build" and action: "refresh" both rebuild the WHOLE index, which on a large library means many minutes and, with an API embedding provider, real spend (they differ in one thing: build resumes an interrupted build, refresh always starts over). action: "build"/"refresh" pages the library's top-level items (100-at-a-time, stopping at the server's item cap, ZOTEUS_INDEX_MAX_ITEMS, default 5000, or at a smaller limit if one is given), indexes their text (title, abstract, creators, tags) for BM25 keyword search and, if an embedding provider is configured, for vector search, persisting partial progress atomically as it goes; use it for the first build, after changing the embedding model, or to widen a previously capped build. It is ALSO the repair: if the index cannot be read at all, only action:"build" clears it, by deleting the unreadable file and opening a fresh one before rebuilding (nothing repairs it at startup or inside a query). action: "update" instead fetches only the items changed since the version the index recorded (Zotero's ?since=), re-chunks and re-embeds just those, and removes items the library no longer holds (diffed from a cheap keys-only ?format=versions census, since the deletion log is cloud-only); untouched items are never re-embedded, so adding a handful of items costs seconds instead of a full rebuild. Update falls back to a full rebuild by itself, and says so in updateNotice, when a delta would be wrong: no version stamp recorded yet, the library is now served by a different Zotero API (the desktop app and the cloud number their versions independently), or the embedding model changed. An update ALSO asks Zotero's full-text index what it has extracted since the build (that is a separate version sequence from item versions, so a PDF Zotero extracted when it was first opened changes no item version and appears in no delta) and indexes the new body text for items nothing else touched; on a library where nothing was extracted, that costs one request. A build or update interrupted by action:"stop", a crash or a restart leaves a checkpoint, and action: "build" RESUMES from it: the items already committed stay searchable and are never re-fetched or re-embedded, and only work since the last save is redone (resumedFrom on the status reports how many were inherited). action: "refresh" is the one that always starts over. A build also indexes the reader's OWN words by default: every child note, and every PDF annotation (its highlighted passage and its comment), as extra passages carrying the parent item's key — so zotero_annotate writes text that search can then find, an item with forty annotations still takes one result slot, and a hit whose snippet came from one is marked source:"note" or source:"annotation". That corpus is one paged crawl of hand-written text, orders of magnitude smaller than attachment bodies; turn it off with own_words:false or ZOTEUS_INDEX_OWN_WORDS=false. An action:"update" keeps it current for the cost of one request when nothing was written: notes and annotations are ordinary items carrying ordinary versions, so an edit, an addition and a deletion are all found by comparing the library's note/annotation keys against the ones the index holds — which is also how an index built before this existed fills its gap, once, on its first update. Set fulltext:true to ALSO index the body text Zotero extracted from each item's attachments, which is what makes semantic search match a claim buried in a PDF rather than only its title and abstract; it is off by default because it multiplies build time and index size (default cap: 40000 characters per item, tunable with fulltext_max_chars), and only attachments Zotero has already extracted are available. That pass used to be refused inside Claude Desktop, where a build that reached it killed the server process partway through with no error at all (#37); the cause was the on-device embedding model asking Electron's allocator for a block it will not serve, so the server now embeds fewer passages per call there and the build runs to completion. It is somewhat slower inside the app than in a terminal and produces exactly the same index, so a user who wants the fastest possible first build can still run one headlessly against the same ZOTEUS_DATA_DIR and let Desktop read the result. A build runs in TWO passes and reports which one it is on as phase: every item's metadata is indexed first, across the whole library, and only then are attachment bodies crawled (fulltextItemsScanned of fulltextItemsTotal). So the library is fully searchable on titles, abstracts, creators and tags long before a full-text crawl that can run for hours finishes — tell the user they can search already rather than asking them to wait for state:"done". Start a job, then POLL action: "status" every few seconds until state is "done" (or "error"); calling build or update again while one is running just returns current progress. action: "status" reports state (idle|building|done|error), operation (build|update), phase (metadata|fulltext), fetch/embed progress, itemsRemoved, index size, the active embedder, libraryVersion/libraryBackend (the version stamp an update diffs from), fulltextVersion (how far into Zotero's separate full-text sequence the index has read), resumedFrom (items inherited when a build resumed an interrupted one), itemsTotal/itemsAvailable (which differ, with a warning, when the cap stopped the crawl short of the library), ownWordsItems/ownWordsPassages (the notes and annotations indexed, with ownWordsReason if they could not be read), and (when full text was requested) fulltextItems/fulltextPassages plus fulltextReason if it produced nothing. It also reports localApiDegradedAt when the job saturated Zotero's local API and the whole session fell back to the Zotero Web API: that fallback works, so nothing errors, but the Web API is slower and rate-limited and the rest of the build takes far longer than its start suggested, so tell the user rather than letting them watch an unexplained slowdown (the crawl also backs off to one attachment at a time by itself, to let the app recover). It reports where the index is stored (storage: sqlite or memory, set by ZOTEUS_INDEX_BACKEND), storageNotice when opening that store imported or refused an older JSON index, persistError when the index could not be written to disk at all, and how the last semantic query ranked vectors (vectorScan: "codes" for the two-stage path, "exact" for a full scan of every vector, with vectorScanNotice when that needs explaining). When the embedding provider is an API (ZOTEUS_EMBEDDINGS=openai or gemini), status also reports embedRate: the batch size, the pause between requests, the estimated tokens per request and the tokens per minute the build is actually sustaining, plus passagesWithoutVectors when the index holds passages nothing has embedded yet. A build whose embedder was rate-limited to a standstill keeps every passage it indexed and stays RESUMABLE: tell the user to run action:"build" again, which embeds only the passages that have no vector and re-fetches nothing, and NOT action:"refresh", which starts the whole crawl over and pays for every vector a second time. A rate-limited request already backs off and retries by itself; if a build reports it is riding the provider's tokens-per-minute limit, the fix is ZOTEUS_EMBED_BATCH_DELAY_MS (with ZOTEUS_EMBED_BATCH_SIZE), not a smaller library. action: "stop" cancels a running job (partial data is kept and stays searchable; a stopped update leaves the version stamp untouched so the next one repeats the delta, and a stopped build leaves a checkpoint the next action:"build" resumes from). A partially built index is always usable for keyword search. Local embeddings are CPU-bound (see ZOTEUS_EMBEDDINGS), so large builds take a while: poll status rather than retrying build.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max items to index. Lowers the configured cap for this build only; it cannot raise it. The cap defaults to 5000 and is set by ZOTEUS_INDEX_MAX_ITEMS. | |
| action | Yes | ||
| fulltext | No | Also index the full text Zotero extracted from each item's attachments, so searches match the body of a PDF. Resource-intensive (slower build, much larger index); defaults to ZOTEUS_INDEX_FULLTEXT (off unless set). | |
| own_words | No | Also index the reader's OWN words — child notes and PDF annotations (highlight text and comments) — as passages carrying the parent item's key. On by default (ZOTEUS_INDEX_OWN_WORDS); the whole corpus is one paged crawl of hand-written text, so it costs a fraction of what fulltext does. | |
| library_id | No | ||
| library_type | No | ||
| fulltext_max_chars | No | Cap on indexed full-text characters per item; 0 means no cap (default 40000). Only used with fulltext. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint false, destructiveHint true), the description discloses background execution, immediate return, checkpoint/resume behavior, deletion of an unreadable index on build, update fallback conditions, rate-limit backoff, and degraded-API fallback. The destructive hints are consistent with the stated deletion and rebuild behavior, so there is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is front-loaded with the key action distinction and the logic flows from actions to status fields, but the description is a single enormous unbroken paragraph. It repeats resume and rate-limit caveats and includes historical context like bug #37; short sections or bullets would make the actionable guidance far more scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description documents the status fields, state values, progress indicators, error conditions, and environment variables needed to drive the tool correctly. It also covers failure modes such as rate limits, version mismatch, unreadable index, and degraded-API fallback, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 57%, but the description substantially compensates by explaining action semantics and adding defaults/caveats for limit, fulltext, fulltext_max_chars, and own_words. However, library_id and library_type have no schema descriptions and are never mentioned in the description, leaving a small but real gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific resource (the local hybrid-search index used by zotero_semantic_search) and a clear management role, then enumerates the distinct actions. It is easy to distinguish this from query/write siblings such as zotero_semantic_search and zotero_update_item.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says update is the cheap default for an already-indexed library, lists the conditions for build (first build, model change, widening a capped build, repairing an unreadable index), and distinguishes refresh as the always-start-over option. It even prescribes polling status rather than retrying build, so the agent knows not just what the tool does but how to use it correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_list_collectionsList Zotero collections (read-only)ARead-only
List collections in a Zotero library (key, name, parent collection key, item count). Read-only — available even in read-only mode (unlike zotero_manage_collections, which also writes). Use the keys to scope zotero_search_items (collectionKey) or zotero_tag_audit (scope.collection_keys).
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Only top-level collections. | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. Description adds that it's available in read-only mode and contrasts with the write sibling. No contradictions, but lacks mention of pagination or empty library behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with purpose, zero wasted words. Efficiently covers main points.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple list operation, description is nearly complete: purpose, usage, sibling differentiation, and returned fields. Lacks parameter details for library_id and library_type, but overall adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (33%, only 'top' described). Description does not add meaning for library_id or library_type, leaving them unexplained. With low coverage, description should compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs ('list') and resource ('collections'), lists returned fields, and distinguishes from sibling zotero_manage_collections by noting it's read-only.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (listing, read-only mode) and when not to (for writing, use zotero_manage_collections). Also provides downstream usage of keys for other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_list_tagsList Zotero tags (read-only)ARead-only
List tags in a Zotero library with their usage count and whether each was auto-applied by Zotero. Optional q substring filter and limit. Read-only — available even when the connector runs in read-only mode (unlike zotero_manage_tags, which also writes). For taxonomy hygiene use zotero_tag_audit.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Substring filter. | |
| limit | No | Max tags (default 100). | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true; the description adds details about returned data (usage count, auto-applied flag) and that it works in read-only mode, providing useful context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences with no redundancy: purpose, param mention, and sibling differentiation. Well-structured and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description explains return fields. However, missing param descriptions for library_id and library_type reduce completeness; overall adequate but with gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 2 of 4 parameters (q, limit) are mentioned in the description; library_id and library_type are undocumented. With 50% schema coverage, the description should compensate but does not, leaving key params unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists tags with usage count and auto-applied status, and distinguishes it from siblings like zotero_manage_tags (write) and zotero_tag_audit (hygiene).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes read-only availability, contrasts with zotero_manage_tags for writing, and suggests zotero_tag_audit for taxonomy hygiene, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_manage_collectionsManage Zotero collectionsADestructive
List, create, rename, reparent, or delete collections, and move items into or out of a collection. Set action to one of: "list" (all collections with key/name/parent), "create" (needs name, optional parent_collection key — omit for top-level), "rename" (needs collection_key + name), "reparent" (needs collection_key; parent_collection key, or omit to move to top level), "delete" (needs collection_key), "add_items" / "remove_items" (need collection_key + item_keys; collection membership lives on each item). All actions except "list" write to the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Collection name (create/rename). | |
| action | Yes | ||
| item_keys | No | Item keys (add_items/remove_items). | |
| library_id | No | ||
| library_type | No | ||
| collection_key | No | Target collection key (all actions except list/create). | |
| parent_collection | No | Parent collection key; omit for top-level. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly warns that all actions except 'list' write to the cloud Web API, which aligns with and supplements the destructiveHint annotation. It also clarifies that collection membership lives on each item, adding useful behavioral context beyond the annotations, though deletion effects are not detailed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense single paragraph organized by action, with the main verb phrase front-loaded and each action clause carrying concrete requirements. It is somewhat monolithic but efficient given seven actions to describe.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full operation set, required parameters, and the list output shape, which is valuable given there is no output schema. It omits details like pagination, write-action return values, and the meaning of library_id/library_type, but overall it gives an agent enough to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description maps actions to parameters, such as 'create needs name' and 'reparent can omit parent_collection to move to top level,' adding meaning beyond the raw schema. However, library_id and library_type are left unexplained by both the schema and description, preventing full parameter coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb-and-resource summary: list, create, rename, reparent, or delete collections, plus moving items in/out. The explicit action list and relation to collection management make it easy to distinguish from sibling tools like zotero_list_collections or tag management.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each action is paired with its required and optional parameters, effectively telling the agent exactly how to invoke every route. It does not explicitly name alternatives or state when not to use this tool versus siblings, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_manage_tagsManage Zotero tagsADestructiveIdempotent
List tags, or add/remove tags on items. Set action to "list" (returns library tags; supports q substring filter), "add" (add tags to each of item_keys), or "remove" (remove tags from each of item_keys). Tags are stored on the parent item's tag array, so add/remove edits the items (cloud Web API). Tag names are case-sensitive.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Substring filter for list. | |
| tags | No | Tag names to add or remove. | |
| limit | No | ||
| action | Yes | ||
| item_keys | No | Items to modify (add/remove). | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description adds valuable behavioral details: tags live on the parent item's tag array, add/remove edits live items through the cloud Web API, and tag names are case-sensitive. This supplements the destructiveHint and idempotentHint annotations with concrete implications of calling the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and efficient. The first sentence states the core purpose, the second maps action values to behavior, and the final sentences add necessary caveats. No sentence is wasted, and the most important information appears early.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, the description covers the action semantics and mutation behavior well, but with no output schema it does not describe the response shape for add/remove, and it omits library selection details. These gaps prevent it from being fully self-sufficient for an agent that must invoke and interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description clarifies the most important parameters: action values are fully explained, q is described as a substring filter for list, and tags/item_keys are tied to add/remove semantics. However, with only 43% schema description coverage, the description still leaves library_id, library_type, and limit unexplained, so it only partially compensates for the schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource combination: 'List tags, or add/remove tags on items.' It then enumerates the three action modes clearly, making it obvious that this tool both reads and mutates tags on Zotero items, and distinguishing it from more narrowly scoped siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear, actionable context for each action value: 'list' returns library tags with a q filter, 'add' and 'remove' modify item_keys. It does not explicitly name alternatives or state when not to use this tool instead of zotero_list_tags, but the action breakdown makes the usage context fairly obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_saved_searchesManage Zotero saved searchesADestructive
List, create, or delete saved-search DEFINITIONS. NOTE: the Zotero cloud Web API stores saved searches but does NOT execute them — to get the items a saved search matches, run an equivalent zotero_search_items query (or use the desktop local API when available). Set action to "list" (all saved searches with their conditions), "create" (needs name and conditions, each {condition, operator, value}), or "delete" (needs search_key). Writes go to the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Saved-search name (create). | |
| action | Yes | ||
| conditions | No | Search conditions (create). | |
| library_id | No | ||
| search_key | No | Saved-search key (delete). | |
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-write and destructive, and the description adds important context: the cloud Web API stores saved-search definitions but does not execute them, and writes go to the cloud Web API. It could disclose prerequisites such as authentication or library context more explicitly, but the key behavioral caveat is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and the key caveat, then gives a compact breakdown of the three actions. Every sentence carries information and none is wasted or redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the operational caveat, the action semantics, and the relationship to zotero_search_items, which is the core knowledge needed. It falls slightly short because library_id and library_type are not mentioned, and there is no output-schema guidance for what list/delete return, but as a whole it is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 50% schema description coverage, the description compensates by explaining the action enum values' meanings and the data shape required for conditions ({condition, operator, value}). However, library_id and library_type are left without any explanation in either the schema or the description, which is a notable gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names specific verbs (list, create, delete) and a specific resource (saved-search definitions), and immediately distinguishes itself from zotero_search_items by stating the cloud API does not execute saved searches. This lets an agent understand what the tool does and what it does not do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use this tool versus zotero_search_items: use this to manage definitions, and use an equivalent zotero_search_items query to get matched items. It also gives action-specific usage requirements (list vs create with name and conditions vs delete with search_key), so an agent can select the right path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_schemaZotero data model (types & fields)ARead-only
Return the Zotero data model so you never hardcode item shapes. With no arguments, returns the schema version and the list of all item type names. With item_type, returns the valid fields and creator types for that type (the "primary" creator type is listed first). Use this to validate an item before creating or updating it: notes, attachments, and annotations are item types too but bypass the normal field/creator model.
| Name | Required | Description | Default |
|---|---|---|---|
| item_type | No | If set, return the fields & creator types for this item type. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and openWorldHint=true. The description adds behavioral context by specifying return values (schema version, item type list, fields, creator types) and that the primary creator type is listed first. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all front-loaded with the main purpose. Each sentence adds value without redundancy. Very efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only schema tool with one optional parameter and no output schema, the description is complete. It explains both modes of operation and provides usage advice, leaving no gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear description for the only parameter item_type. The description adds meaning: 'the primary creator type is listed first' and clarifies that certain item types bypass the normal model, which is not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Return the Zotero data model so you never hardcode item shapes.' It explains behavior with and without arguments, and distinguishes itself from sibling tools by being the only schema-related tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It advises to use this to 'validate an item before creating or updating it' and notes that notes, attachments, and annotations are item types but 'bypass the normal field/creator model.' This provides clear context for when to use the tool, though it doesn't explicitly exclude alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_scholarScholarly context (references, citations, related)ARead-only
Explore the EXTERNAL scholarly graph around a paper (OpenAlex, Crossref fallback). This does NOT search, list, or read your Zotero library — it queries the open web, and results are works from the scholarly web, not your items. To search or inspect YOUR library use zotero_search_items, zotero_semantic_search, zotero_get_item, or zotero_list_tags instead. Provide a doi and an action: "lookup" (metadata + citation count), "references" (works this paper cites), "citations" (works that cite this paper, most-cited first), or "related" (similar works). Set include_in_library: true to additionally flag which results your library already holds (off by default because it scans the library); otherwise every result is just a web record. limit caps results (default 20). Read-only; calls external scholarly APIs.
| Name | Required | Description | Default |
|---|---|---|---|
| doi | Yes | The DOI of the paper (with or without the https://doi.org/ prefix). | |
| limit | No | Max results (default 20). | |
| action | Yes | ||
| include_in_library | No | Also scan the library and flag results already saved (default false; scanning is expensive). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint and openWorldHint, and the description adds substantial context: it queries external scholarly APIs, uses Crossref as a fallback, never touches the user's library unless include_in_library is set, and describes the expensive scanning behavior. This goes well beyond the structured annotation data and is consistent with it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: scope, exclusions, action values, optional flag behavior, and safety. It front-loads the core purpose and then logically expands into usage details without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives strong context for selecting and invoking the tool, including action semantics and external data source behavior. It does not describe the result shape beyond 'works' and citation counts, but given the complexity of four action modes and no output schema, this is a minor gap rather than a critical omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers parameter names and types, but the description adds crucial meaning for each parameter: the doi prefix tolerance, the exact meaning of each action enum value, the default and role of limit, and the behavioral tradeoff of include_in_library. This significantly enriches the schema, especially for the action parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as exploring the external scholarly graph around a paper via OpenAlex and Crossref, with explicit action modes (lookup, references, citations, related). It distinguishes itself from sibling library tools by stating it does NOT search, list, or read the Zotero library.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states what the tool does not do and names alternative tools (zotero_search_items, zotero_semantic_search, zotero_get_item, zotero_list_tags) for library operations. It also clarifies when to enable include_in_library and how the default avoids expensive library scanning.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_search_itemsSearch Zotero itemsARead-only
Search or list items in a Zotero library or collection. Quick search via q (qmode: titleCreatorYear=default, matches title/creator/year only; everything=also searches notes & attachment full text). For presence checks ("is X in my library?"): a default-mode q that matches nothing auto-retries once in everything mode, so terms appearing only inside PDF text don't false-negative — pin qmode explicitly to disable. An empty everything result is reported as strong-but-not-conclusive, since un-indexed/scanned/un-synced PDFs aren't full-text searchable. Also supports boolean itemType filters (use || for OR, repeat or && for AND, leading - to negate, e.g. "journalArticle || book", "-attachment"), boolean tag filters (same syntax; escape a literal leading hyphen as "-"), since (version) for incremental queries, sort/direction, and limit/start paging. Set response_format to "detailed" to also return technical fields (version, tags, collections, DOI, url) needed before chaining a write; the default "concise" returns high-signal projections (key, itemType, title, creators, date). Reads are served from the fast desktop local API when available, otherwise the cloud Web API. Returns totalResults so you can tell when to page rather than assuming you saw everything. For conceptual/"papers about X" queries by meaning rather than exact fields, use zotero_semantic_search instead.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Quick/full-text search string. | |
| tag | No | Boolean tag filter, e.g. "to-read && 2024". | |
| top | No | Only top-level items (exclude child notes/attachments). | |
| sort | No | ||
| limit | No | Max items (default 25, max 100). | |
| qmode | No | ||
| since | No | Return items modified after this library version. | |
| start | No | ||
| itemType | No | Boolean itemType filter, e.g. "journalArticle || book". | |
| direction | No | ||
| library_id | No | ||
| library_type | No | ||
| collectionKey | No | Restrict to a collection by key. | |
| includeTrashed | No | ||
| response_format | No | Detail level of returned items. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses retry logic, behavior with un-indexed PDFs, API routing (local vs cloud), and response format options. Complements annotations (readOnlyHint, openWorldHint) without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with front-loaded purpose and logical detail. Slightly long but necessary given complexity; each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Thoroughly covers search modes, filter syntax, pagination, response formats, and API routing. Addresses edge cases (presence checks, un-indexed PDFs). Lacks explicit error handling but is very complete overall.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning to q, qmode, tag, itemType, and response_format beyond schema. Explains retry logic for q. With 53% schema coverage, description compensates well but could explicitly cover remaining parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search or list items in a Zotero library or collection' with specific verb and resource. It distinguishes from siblings like zotero_semantic_search (conceptual) and zotero_get_item (single item).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use default vs everything qmode, presence check behavior, and mentions alternative tool for conceptual queries. Could be more exhaustive about when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_semantic_searchSemantic / hybrid library searchARead-only
Search the library by meaning, not just keywords. Combines BM25 keyword scoring with vector similarity (when an embedding provider is configured) via reciprocal-rank fusion, and returns the best-matching items with a snippet and score. By default it searches item metadata and abstracts; if the index was built with fulltext on (zotero_index fulltext:true, or ZOTEUS_INDEX_FULLTEXT=true) it also searches the body text of attachments, and a hit whose snippet came from a PDF body is marked source:"fulltext". It ALSO searches the words the reader wrote — child notes and PDF annotations (highlight text and comments) — unless that was turned off (ZOTEUS_INDEX_OWN_WORDS=false); a hit from one is marked source:"note" or source:"annotation" and is attributed to the item it hangs off, so an item with forty annotations is one result rather than forty. mode: "auto" (hybrid, default), "keyword" (BM25 only), or "semantic" (vector only). "semantic" needs vectors in the index: when the configured embedder is not running (e.g. the on-device model runtime is not installed) it returns an error naming the cause instead of an empty result set, and "auto" keeps working as keyword search while saying so. The index must be built once before first use: when it is empty this tool starts a background build automatically (auto_build, on by default) and tells you to poll zotero_index action:"status" and retry — pass auto_build:false to opt out. For exact field/tag/itemType filtering use zotero_search_items instead; use this for conceptual/"papers about X" queries. To read the actual passages of a found item (with page locators) use zotero_get_fulltext.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Natural-language query. | |
| mode | No | ||
| limit | No | Max results (default 10). | |
| auto_build | No | Start building the index automatically in the background when it is empty (default true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint:true and openWorldHint:true; the description carries the real behavioral burden and does so richly: config-dependent search scope (metadata/abstracts vs fulltext vs notes/annotations), source markers ("fulltext", "note", "annotation"), result aggregation (forty annotations collapse to one item), mode-specific failure behavior (semantic errors naming the cause, auto silently degrading to keyword while saying so), and the transparent disclosure of the background auto-build side effect during a read-only search. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long (~8 dense sentences) but front-loaded with the core purpose and every clause carries distinct behavioral information — search scope, source markers, mode semantics, index prerequisites, sibling routing. A few parentheticals (e.g., 'e.g. the on-device model runtime is not installed') are slightly expandable, keeping it a notch below perfect conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and covers it: best-matching items with snippet and score, plus source markers and one-result-per-item aggregation. It also covers prerequisites (index must be built), config-dependence (fulltext/own-words flags), and failure modes. For a read-only search tool of this complexity, nothing an agent needs to invoke it correctly or interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75% (mode lacks a description), so the description must compensate for the enum parameter — and it does, explaining each mode value and its failure/fallback behavior. It also enriches auto_build by explaining the consequence (background build triggers, poll and retry) beyond the schema's one-liner. The q parameter gains context ('papers about X' conceptual queries). Genuine added value beyond the structured schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+approach ('Search the library by meaning, not just keywords') and details the mechanism (BM25 + vector similarity via reciprocal-rank fusion). It explicitly differentiates from siblings: 'For exact field/tag/itemType filtering use zotero_search_items instead; use this for conceptual/""papers about X" queries.' An agent can distinguish this from every sibling without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names alternatives and the conditions that select them: zotero_search_items for exact field/tag/itemType filtering, zotero_get_fulltext for reading actual passages with page locators. It also gives the operational workflow for the empty-index case (poll zotero_index action:"status" and retry, or pass auto_build:false to opt out). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_stylesResolve CSL citation stylesARead-only
Resolve a human citation-style name to a valid CSL style id and confirm it is available, or list common style aliases. action: "resolve" maps names like "APA 7th", "IEEE", "Vancouver", "Chicago", "MLA", "Nature" to the correct CSL id (e.g. apa, ieee, modern-language-association) and verifies the style can be fetched; pass the returned styleId as the style argument to zotero_format_bibliography or zotero_bibliography. action: "list" returns the built-in common aliases (any id from the CSL styles repository also works). Dependent styles are resolved to their independent parent automatically when formatting.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Style name to resolve (e.g. "APA 7th"). | |
| action | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly and openWorld. Description adds that the tool verifies fetchability, resolves dependent styles to independent parent, and accepts any CSL repository id. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with main purpose. Second sentence is somewhat dense but still readable. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers both actions, input examples, output usage, and automatic resolution of dependent styles. Lacks mention of error handling for unresolvable names, but overall adequate given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds examples of style names (APA 7th, IEEE, etc.) and explains the output usage (pass styleId to other tools). The schema had 50% coverage; description compensates well by giving context beyond property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool resolves human citation-style names to CSL ids or lists aliases, with specific actions. It distinguishes from siblings by mentioning its output is used by other formatting tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes when to use each action (resolve vs. list), and tells the agent to pass the returned styleId to other tools. Does not explicitly state when not to use, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_syncIncremental sync deltaARead-only
Return what changed in a library since a given version, for efficient incremental sync. Provide since (a library version; 0 = everything). Returns, per object type (items/collections/searches/tags), the map of keys→version that changed after since, plus the deletion log (keys removed since since). This is the version-based delta the Zotero sync algorithm uses — fetch the changed keys, then pull only those with zotero_get_item/zotero_search_items. Reads via the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | Library version to diff from (default 0). | |
| types | No | Which object types to check (default all). | |
| library_id | No | ||
| library_type | No | ||
| include_deleted | No | Include the deletion log (default true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral details beyond the annotations: it states this is a read operation via the cloud Web API, consistent with readOnlyHint=true. It describes the return structure (map of keys→version per object type, deletion log) and that it follows the Zotero sync algorithm. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise at four sentences, each earning its place. It is front-loaded with the purpose, then explains the key parameter, return structure, and usage guidance. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters and no output schema, the description adequately covers purpose, usage, return structure, and complementary tools. It lacks error handling details but provides enough context for an AI agent to use it effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 60%, baseline is 3. The description adds meaning for 'since' (0 = everything) and implies types. However, it does not explain 'library_id', 'library_type', or 'include_deleted' beyond what the schema provides. Some value added, but incomplete for undocumented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns what changed in a library since a given version for efficient incremental sync. It uses specific verbs ('Return what changed') and distinguishes itself from sibling tools like zotero_get_item and zotero_search_items by positioning as the delta mechanism.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: for efficient incremental sync. It explains the key parameter 'since' and what to do with the results (fetch changed keys, then pull only those with other tools). It does not explicitly state when not to use or list alternatives, but the usage context is well-defined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_tag_auditAudit tags against a controlled vocabularyARead-only
Audit a library against a controlled tag vocabulary with priority tiers. Provide the vocabulary inline as vocabulary (or a JSON file via vocabulary_path): { tags:[{name,tier?}], tiers?:[{name,required?}] }. Reports (1) off-taxonomy tags (library tags not in the vocabulary; Zotero auto-applied tags are bucketed separately unless include_auto), (2) items missing a tag from each required tier, and (3) optional per-collection coverage when scope.collection_keys is given. Read-only. Tag/auto-tag enumeration uses the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max items listed per report (default 50). | |
| scope | No | ||
| library_id | No | ||
| vocabulary | No | ||
| include_auto | No | Treat Zotero auto-applied tags as off-taxonomy too. | |
| library_type | No | ||
| vocabulary_path | No | Path to a JSON file with the vocabulary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true and openWorldHint=true. The description adds that it enumerates via the cloud Web API, reports off-taxonomy tags, and handles required tiers. No contradictions found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph of five sentences, covering purpose, input format, output, and read-only nature. It is mostly concise and front-loaded, though slightly verbose in explaining reports.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, nested objects, no output schema), the description adequately explains what the tool does and what reports it produces. Annotations support completeness. Minor gaps remain in output structure details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (43%), but the description adds meaning for key parameters like `vocabulary` (inline example) and `include_auto`. However, parameters like `limit`, `library_id`, `library_type`, and `vocabulary_path` are not explained in the description, limiting full compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool audits tags against a controlled vocabulary with priority tiers, distinguishing it from tag listing or management tools. It specifies three types of reports, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool (for auditing tags), including the types of reports generated. It does not explicitly mention when not to use it or provide alternatives, but the context is clear enough for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_trash_itemsTrash or restore Zotero itemsA
Move items to the trash (the safe, REVERSIBLE default) or restore them. This sets the deleted flag (1=trash, 0=restore) — it is NOT a permanent delete, so trashed items can be recovered here or in the Zotero app. Use this instead of zotero_delete_items unless you truly need irreversible removal. Provide item_keys and optional action (default "trash"). Writes go to the running Zotero desktop app for your personal library (via its local-API writes where available), otherwise to the cloud Web API.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | Default "trash". | |
| item_keys | Yes | Item keys to trash or restore. | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant context beyond annotations: it reveals the underlying flag mechanism (`deleted` 1/0), confirms reversibility, and specifies the API path (local vs web). Annotations already indicate a write operation (readOnlyHint=false) and non-destructive intent (destructiveHint=false), and the description aligns without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured, fitting in three sentences. It front-loads the core action, then explains the flag behavior, usage guidance, and parameter details without any redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write operation with no output schema, the description covers the essential behavioral aspects: reversibility, default action, API routing, and alternative tools. It lacks explicit mention of response formats or error handling, but these are less critical for a straightforward toggle operation. The omission of `library_id`/`library_type` is a minor gap, but the overall description is sufficiently complete for likely use cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%, with only `action` and `item_keys` having descriptions. The description explains these two parameters (default action, required keys) but completely omits `library_id` and `library_type`. While it mentions 'your personal library' implying group libraries aren't covered, it doesn't clarify these parameters, leaving ambiguity for group use cases.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Move items to the trash' or 'restore them'. It uses a specific verb and resource, and explicitly differentiates from zotero_delete_items by emphasizing reversibility and the `deleted` flag mechanism.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool: 'Use this instead of zotero_delete_items unless you truly need irreversible removal.' It also explains the default action and the optional `action` parameter, covering both use cases and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_update_itemUpdate a Zotero itemADestructiveIdempotent
Partially update one item (HTTP PATCH — only the fields you supply change; omitted fields are preserved). Provide item_key and a patch object of the fields to change (e.g. {"title":"New","extra":"note"} or {"tags":[{"tag":"reviewed"}]}). All field values are plain JSON strings/numbers/booleans/arrays — never wrapped in nested objects (e.g. "title": "New", NOT "title": {"title": "New"}). Optimistic concurrency is handled for you: if you pass the item's version it is used; otherwise the current version is fetched first. If the item changed on the server in the meantime (412), the update is automatically re-fetched and retried once. Writes go to the cloud Web API. Set dry_run:true to preview the field-level before→after diff without writing (arrays like tags/collections are replaced wholesale by PATCH, not merged; a dry_run call performs no write).
| Name | Required | Description | Default |
|---|---|---|---|
| patch | Yes | Object of fields to change (PATCH semantics), e.g. {"title": "New title", "date": "2024-02-01", "tags": [{"tag": "reviewed"}], "collections": ["ABCD1234"]}. Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings. Values are plain, never wrapped in nested objects. | |
| dry_run | No | Preview the field-level before→after diff without writing. | |
| version | No | Known current version; fetched automatically if omitted. | |
| item_key | Yes | The 8-character item key. | |
| library_id | No | ||
| library_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses PATCH merge semantics, plain-value formatting, optimistic concurrency with automatic retry, cloud Web API writes, dry_run behavior, and wholesale replacement of arrays. These are exactly the behavioral surprises an agent would otherwise discover at runtime.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is long but information-dense and front-loaded with the central PATCH semantics. Each sentence adds operational value, though a bit of restructuring (separating dry_run and concurrency) could improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and a complex patch object, the description covers invocation, concurrency, and dry_run well. It leaves return-value shape and optional library parameters (library_id/library_type) implicit, but these are not required to make a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds crucial meaning beyond the schema: patch values must not be wrapped in nested objects, tags/collections are replaced rather than merged, and version/dry_run behavior is explained. It does not clarify library_id/library_type, but the core required parameters are thoroughly documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Partially update one item (HTTP PATCH — only the fields you supply change; omitted fields are preserved)', which names a precise verb, a specific resource, and the operation's scope. This clearly distinguishes it from sibling create/delete/trash tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly implies use for modifying an existing item and explains when dry_run is appropriate, and the PATCH semantics tell the agent not to send full objects. It does not explicitly name alternatives like zotero_create_items or zotero_delete_items, so no explicit exclusion is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zotero_whoamiZotero identity & accessARead-only
Resolve the current Zotero identity (userID, username, display name) and per-library access scopes from the configured API key, and report which library backends are available (cloud Web API and/or the desktop local API). Call this first to discover the userID — never ask the user to type a numeric ID. If no API key is configured, the server runs in local-only read mode against the desktop library (users/0).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint, but description adds depth: behavior depends on API key presence, reports specific identity fields and backend availability. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences covering purpose, usage, and edge case. No filler, front-loaded with most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all essential aspects: identity fields, scopes, backends, and local-only fallback. Lacks explicit output format but lists fields sufficiently for a simple read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters, so schema coverage is 100%. Description does not need to elaborate on parameters. Baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool resolves identity (userID, username, display name) and access scopes, and reports available backends. It also explicitly instructs to call this first, distinguishing it from other tools that perform searches or manage items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance to call this first and never ask user for numeric ID. Mentions local-only mode when no API key. No explicit alternatives needed as no sibling tool provides identity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v1.14.0- Changed
zotero_attachment1 field changed- added
Input schema / properties / overwriteAdded value: +{ + "description": "Allow `save_path` to replace a file that already exists (default false).", + "type": "boolean" +}
2 tool updates
v1.13.0- Changed
zotero_get_fulltext4 fields changed- changed
Input schema / properties / fallback / descriptionPrevious value: -"When Zotero has no indexed full text for the attachment, download the PDF and extract it directly (default true)."New value: +"When Zotero has no indexed full text for the attachment, read the file itself and extract it directly (default true)." - added
Input schema / properties / outlineAdded value: +{ + "description": "Return the PDF's table of contents (heading, page, nesting level) instead of text.", + "type": "boolean" +} - changed
Input schema / properties / page_range / descriptionPrevious value: -"Page span like \"3-7\" (1-based, inclusive)."New value: +"Page span like \"3-7\" (1-based, inclusive). PDFs only." - changed
Input schema / properties / precise_pages / descriptionPrevious value: -"Re-extract the PDF for exact page numbers."New value: +"Re-extract the PDF for exact page numbers (already the default with `page_range`)."
- Changed
zotero_index1 field changed- added
Input schema / properties / own_wordsAdded value: +{ + "description": "Also index the reader's OWN words — child notes and PDF annotations (highlight text and comments) — as passages carrying the parent item's key. On by default (ZOTEUS_INDEX_OWN_WORDS); the whole corpus is one paged crawl of hand-written text, so it costs a fraction of what fulltext does.", + "type": "boolean" +}
1 tool update
v1.9.0- Changed
zotero_annotate2 fields changed- added
Input schema / properties / annotations / items / properties / occurrenceAdded value: +{ + "description": "Which occurrence of `text` to anchor when the passage appears more than once (1-based, in reading order). Only needed when a first attempt reports an ambiguous passage.", + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / annotations / items / properties / position / descriptionPrevious value: -"Zotero position: {\"pageIndex\": N, \"rects\": [[x1,y1,x2,y2],...]} (points, bottom-left origin), its JSON string, or shorthand [N, [x1,y1,x2,y2]]. Required for highlights/underlines to render in place."New value: +"Zotero position: {\"pageIndex\": N, \"rects\": [[x1,y1,x2,y2],...]} (points, bottom-left origin), its JSON string, or shorthand [N, [x1,y1,x2,y2]]. Optional: when omitted, the passage in `text` is located in the PDF and its coordinates are computed for you."
1 tool update
v1.7.1- Changed
zotero_index3 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "build", - "refresh", - "status", - "stop" -]New value: +[ + "build", + "refresh", + "update", + "status", + "stop" +] - changed
Input schema / properties / limit / descriptionPrevious value: -"Max items to index (default 5000, which is also the hard cap)."New value: +"Max items to index. Lowers the configured cap for this build only; it cannot raise it. The cap defaults to 5000 and is set by ZOTEUS_INDEX_MAX_ITEMS." - removed
Input schema / properties / limit / maximumRemoved value: -5000
4 tool updates
v1.6.0- Changed
zotero_attach_file4 fields changed- added
Input schema / properties / library_idAdded value: +{ + "description": "Group library to attach in; forces the cloud path.", + "type": "integer" +} - added
Input schema / properties / library_typeAdded value: +{ + "enum": [ + "user", + "group" + ], + "type": "string" +} - changed
Input schema / properties / path / descriptionPrevious value: -"Local filesystem path to the file."New value: +"Filesystem path to the file, on the machine running Zoteus." - changed
Input schema / properties / url / descriptionPrevious value: -"URL to download the file from."New value: +"URL to download the file from; works on remote/hosted servers."
- Changed
zotero_attachment2 fields changed- changed
Input schema / properties / file_path / descriptionPrevious value: -"Local file to upload."New value: +"File to upload, on the machine running Zoteus." - added
Input schema / properties / urlAdded value: +{ + "description": "URL to download and upload instead of `file_path`; works on remote/hosted servers.", + "format": "uri", + "type": "string" +}
- Changed
zotero_import1 field changed- changed
Input schema / properties / attach_url / descriptionPrevious value: -"File URL (e.g. an arXiv PDF) to download and attach as a stored attachment to the (single) imported item when saving to the desktop app."New value: +"File URL (e.g. an arXiv PDF) to download and attach as a stored attachment to the (single) imported item. Works on every save path: the desktop app when one is reachable, otherwise the cloud Web API."
- Changed
zotero_index2 fields changed- added
Input schema / properties / fulltextAdded value: +{ + "description": "Also index the full text Zotero extracted from each item's attachments, so searches match the body of a PDF. Resource-intensive (slower build, much larger index); defaults to ZOTEUS_INDEX_FULLTEXT (off unless set).", + "type": "boolean" +} - added
Input schema / properties / fulltext_max_charsAdded value: +{ + "description": "Cap on indexed full-text characters per item; 0 means no cap (default 40000). Only used with fulltext.", + "maximum": 1000000, + "minimum": 0, + "type": "integer" +}
9 tool updates
v1.3.1- Added
zotero_annotate - Added
zotero_attach_file - Changed
zotero_create_items2 fields changed- changed
Input schema / properties / items / descriptionPrevious value: -"Array of Zotero item-data objects (itemType + fields; include key+version to update)."New value: +"Array of Zotero item-data objects (itemType + fields; include key+version to update). Example: {\"items\":[{\"itemType\":\"journalArticle\",\"title\":\"The Role of Metadata in Machine Learning\",\"creators\":[{\"creatorType\":\"author\",\"firstName\":\"Ada\",\"lastName\":\"Lovelace\"}],\"date\":\"2024-01-15\",\"DOI\":\"10.1234/example.5678\",\"tags\":[{\"tag\":\"ml\"}],\"collections\":[\"ABCD1234\"]}]}" - added
Input schema / properties / items / items / properties / itemTypeAdded value: +{ + "description": "The Zotero item type as a plain string, e.g. \"journalArticle\", \"book\", \"preprint\", \"report\", \"thesis\".", + "type": "string" +}
- Changed
zotero_get_fulltext1 field changed- added
Input schema / properties / fallbackAdded value: +{ + "description": "When Zotero has no indexed full text for the attachment, download the PDF and extract it directly (default true).", + "type": "boolean" +}
- Changed
zotero_import6 fields changed- added
Input schema / properties / attach_titleAdded value: +{ + "description": "Title for the attached file, e.g. \"Full Text PDF\".", + "type": "string" +} - added
Input schema / properties / attach_urlAdded value: +{ + "description": "File URL (e.g. an arXiv PDF) to download and attach as a stored attachment to the (single) imported item when saving to the desktop app.", + "format": "uri", + "type": "string" +} - changed
Input schema / properties / collection_key / descriptionPrevious value: -"Collection to add saved items to."New value: +"Collection to add saved items to: an 8-char collection key or a Zotero treeViewID like \"C20\"." - changed
Input schema / properties / identifier / descriptionPrevious value: -"DOI / ISBN / PMID / arXiv id / ADS bibcode."New value: +"DOI (10.…), arXiv id (YYMM.NNNNN), ISBN, PMID, or ADS bibcode." - changed
Input schema / properties / save_to_library / descriptionPrevious value: -"Persist the resolved items (needs a cloud key)."New value: +"Persist the resolved items — into the running Zotero desktop app when available, otherwise the cloud Web API (needs a cloud key)." - changed
Input schema / properties / url / descriptionPrevious value: -"Web page URL to scrape."New value: +"Web page URL to scrape (needs a translation-server)."
- Changed
zotero_index2 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "build", - "refresh", - "status" -]New value: +[ + "build", + "refresh", + "status", + "stop" +] - added
Input schema / properties / limitAdded value: +{ + "description": "Max items to index (default 5000, which is also the hard cap).", + "maximum": 5000, + "minimum": 1, + "type": "integer" +}
- Changed
zotero_scholar1 field changed- changed
Input schema / properties / include_in_library / descriptionPrevious value: -"Flag results already in your library (default true)."New value: +"Also scan the library and flag results already saved (default false; scanning is expensive)."
- Changed
zotero_semantic_search1 field changed- added
Input schema / properties / auto_buildAdded value: +{ + "description": "Start building the index automatically in the background when it is empty (default true).", + "type": "boolean" +}
- Changed
zotero_update_item2 fields changed- changed
Input schema / properties / patch / descriptionPrevious value: -"Object of fields to change (PATCH semantics). Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings."New value: +"Object of fields to change (PATCH semantics), e.g. {\"title\": \"New title\", \"date\": \"2024-02-01\", \"tags\": [{\"tag\": \"reviewed\"}], \"collections\": [\"ABCD1234\"]}. Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings. Values are plain, never wrapped in nested objects." - added
Input schema / properties / patch / properties / itemTypeAdded value: +{ + "description": "The Zotero item type as a plain string, e.g. \"journalArticle\", \"book\", \"preprint\", \"report\", \"thesis\".", + "type": "string" +}
28 tool updates
v1.0.4- First observed
search_tools - First observed
zotero_attachment - First observed
zotero_bibliography - First observed
zotero_create_items - First observed
zotero_delete_items - First observed
zotero_export - First observed
zotero_format_bibliography - First observed
zotero_fulltext - First observed
zotero_get_fulltext - First observed
zotero_get_item - First observed
zotero_groups - First observed
zotero_import - First observed
zotero_index - First observed
zotero_list_collections - First observed
zotero_list_tags - First observed
zotero_manage_collections - First observed
zotero_manage_tags - First observed
zotero_saved_searches - First observed
zotero_schema - First observed
zotero_scholar - First observed
zotero_search_items - First observed
zotero_semantic_search - First observed
zotero_styles - First observed
zotero_sync - First observed
zotero_tag_audit - First observed
zotero_trash_items - First observed
zotero_update_item - First observed
zotero_whoami
TDQS
Most tools map cleanly to a distinct resource/action, but several pairs are easy to mix up: zotero_fulltext vs zotero_get_fulltext, zotero_attachment vs zotero_attach_file, and zotero_create_items vs zotero_update_item overlap in name or function. The very detailed descriptions help an agent disambiguate, but the set still has more than a couple of boundary cases.
The zotero_ prefix and lowercase snake_case are consistent, and most names follow verb_noun (search_items, get_item, create_items, manage_collections). Deviations like zotero_schema, zotero_groups, zotero_sync, zotero_index, and unprefixed search_tools break the pattern, and zotero_fulltext/zotero_get_fulltext is a confusingly close pair.
30 tools is above the 'too many' threshold for a single tool surface, even though Zotero is a broad domain. Several tools could be consolidated (list_tags/manage_tags, list_collections/manage_collections, attachment/attach_file, bibliography/format_bibliography), and search_tools is effectively a workaround for the large count.
The set covers the full Zotero lifecycle: identity, item CRUD, collections, tags, saved searches, attachments, annotations, import/export, bibliographies, and sync. What's missing are minor conveniences like tag rename, duplicate detection, or direct saved-search execution, and those gaps have usable workarounds.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Remote MCP server for full read/write access to a Zotero library
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Read-only MCP server exposing a user ORANO library to their own AI agent.
1
Related MCP Servers
- AlicenseBqualityAmaintenanceAn MCP server that lets AI assistants add papers and books to your Zotero library by DOI, arXiv ID, or ISBN, and manage your collections, tags, and items.492MIT
- AlicenseAqualityDmaintenanceAn MCP server that gives any MCP-compatible assistant access to your Zotero reference library, enabling search, citation, bibliography generation, and .docx processing while keeping Zotero as the ground truth for references.91MIT
- AlicenseAqualityAmaintenanceMCP server that lets AI assistants search, create, organize, and cite from a Zotero library.393MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that connects AI assistants to your Zotero library, enabling full-text PDF extraction and metadata search.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/oscardvs/zoteus'
If you have feedback or need assistance with the MCP directory API, please join our Discord server