Skip to main content
Glama

zotero-library-mcp

An MCP server that lets Claude, Codex, and ChatGPT add papers and books to your Zotero library by DOI, arXiv ID, or ISBN — and manage your collections, tags, and items.

The server supports both MCP transports used by these clients:

  • stdio (default) for Claude Code, Claude Desktop, Codex CLI/IDE, and the ChatGPT desktop app

  • Streamable HTTP for a hosted ChatGPT app or any remote MCP client

Tools

Adding papers

  • add_paper_by_doi — Resolve a DOI via CrossRef and add the paper to Zotero (with duplicate detection)

  • add_papers_by_dois — Batch-add up to 50 papers at once

  • add_paper_by_arxiv_id — Add a preprint by arXiv ID (uses DOI when available, falls back to arXiv metadata)

  • add_item_from_metadata — Create any supported Zotero item type from validated manual metadata

Adding books

  • add_book_by_isbn — Resolve an ISBN via Open Library and add the book to Zotero (with duplicate detection)

Searching & browsing

  • list_libraries — Discover the API key owner's personal library and shared group libraries, with IDs and key permissions

  • search_library — Search your Zotero library by title, author, tag, etc., paginated via start/limit (falls back to fuzzy matching when the exact search returns no results)

  • get_item_details — View full metadata for any item

  • get_recent_items — List recently added items

  • get_unfiled_items — Get items not in any collection

  • search_fulltext — Search Zotero metadata and indexed full text

  • find_duplicates — Find duplicate items by DOI, ISBN, or normalized title

  • list_attachments — List every attachment and choose a specific PDF key

  • health_check — Verify library credentials, access, and storage configuration

Reading & annotating

  • get_item_fulltext — Return bounded plain text from Zotero's index or a PDF, without leaking temporary paths

  • get_bibtex — Read-only BibTeX/BibLaTeX export for items, a collection, or the full library

  • save_bibtex — Save an export to an authorized local path

  • get_annotations — List all highlights and annotations on a paper's PDF

  • create_annotation — Highlight a text passage in a PDF (searches for the exact text, creates a visible highlight in Zotero's reader, and returns a preview image for verification). Smart overlap handling: exact duplicates update the existing comment; sub-passages get a contrasting highlight color automatically.

  • add_note — Add a note to an item

  • list_notes, update_note, delete_note — Manage existing notes

  • update_annotation, delete_annotation — Edit or remove annotations

File attachments

  • attach_file — Attach a local file over stdio or a ChatGPT file input over HTTP

  • download_pdf — Return a remote-safe MCP file resource

  • save_pdf — Save a PDF to an authorized local path

Collections

  • list_collections — List all collections (with nesting)

  • create_collection — Create a new collection (optionally nested under a parent)

  • get_collection_items — Browse items in a collection, paginated via start/limit

  • add_to_collection — Add an existing item to a collection

  • remove_from_collection — Remove an item from a collection (keeps it in your library)

  • rename_collection, move_collection — Reorganize collections

Tags

  • list_tags — List all tags in your library

  • add_tags — Add one or more tags to an item (with optional color)

  • remove_tags — Remove tags from an item

  • delete_tags — Delete tags from the entire library

  • set_tag_color — Assign a color to a tag (appears in Zotero's tag selector)

  • rename_tag — Rename a tag across all items in your library

  • unset_tag_color — Remove a tag color without deleting the tag

Verification

  • verify_items — Re-check recent items against CrossRef to catch bad DOIs or title mismatches

Deleting

  • delete_item — Permanently delete an item from your library

  • delete_collection — Permanently delete a collection

  • trash_item, restore_item — Prefer reversible trash operations for ordinary cleanup

The server also exposes the standard read-only search and fetch tool shapes used by ChatGPT company knowledge and deep research.

Related MCP server: zotero-mcp-lite

Prerequisites

  1. A Zotero account

  2. A Zotero API key with write permissions: https://www.zotero.org/settings/keys

  3. Your Zotero library ID (shown on the same page, or in your profile URL)

  4. uv installed

Quick Start

Codex and the ChatGPT desktop app

Codex and the ChatGPT desktop app share MCP configuration on the same Codex host. Add the server once:

codex mcp add zotero \
  --env ZOTERO_LIBRARY_ID=your_library_id \
  --env ZOTERO_API_KEY=your_api_key \
  -- uvx --from git+https://github.com/RaulSimpetru/zotero-library-mcp zotero-mcp

Then restart Codex or the ChatGPT desktop app. In Codex, use /mcp to confirm that zotero is connected. In ChatGPT desktop, open Settings → MCP servers to view the same server.

For WebDAV storage, add the three ZOTERO_WEBDAV_* values shown in the WebDAV example. If the desktop app cannot find uvx, replace it with the full path returned by which uvx.

You can also configure the server directly in ~/.codex/config.toml:

[mcp_servers.zotero]
command = "/full/path/to/uvx"
args = ["--from", "git+https://github.com/RaulSimpetru/zotero-library-mcp", "zotero-mcp"]
env_vars = ["ZOTERO_LIBRARY_ID", "ZOTERO_API_KEY", "ZOTERO_LIBRARY_TYPE", "CROSSREF_MAILTO", "ZOTERO_WEBDAV_URL", "ZOTERO_WEBDAV_USER", "ZOTERO_WEBDAV_PASSWORD"]
startup_timeout_sec = 30
tool_timeout_sec = 120

With env_vars, start Codex/ChatGPT from an environment that contains those variables. Use [mcp_servers.zotero.env] instead if you intentionally want to store their values in the config file.

Claude Code

Install it as a plugin (recommended):

/plugin install zotero --marketplace RaulSimpetru/zotero-library-mcp

On older Claude Code versions, run /plugin marketplace add RaulSimpetru/zotero-library-mcp first, then /plugin install zotero@zotero-library-mcp. Claude Code asks for your library ID and API key (plus optional WebDAV and Unpaywall settings) when you enable the plugin, and keeps the API key and WebDAV password in your system keychain. To get a new release, run /plugin marketplace update zotero-library-mcp, or turn on auto-update for the marketplace in /plugin.

Plugin tools are named mcp__plugin_zotero_zotero__<tool> rather than mcp__zotero__<tool>; update any permission rules that name the old tools. If you previously added the server with claude mcp add, remove that entry (claude mcp remove zotero -s user) so the two copies don't both run.

Or add it as a plain MCP server:

claude mcp add zotero \
  -e ZOTERO_LIBRARY_ID=your_library_id \
  -e ZOTERO_API_KEY=your_api_key \
  -- uvx --from git+https://github.com/RaulSimpetru/zotero-library-mcp zotero-mcp

WebDAV setup

To use WebDAV file storage (e.g. Synology, Nextcloud), include the WebDAV variables:

claude mcp add zotero \
  -e ZOTERO_LIBRARY_ID=your_library_id \
  -e ZOTERO_API_KEY=your_api_key \
  -e ZOTERO_WEBDAV_URL=https://your-webdav-server.com \
  -e ZOTERO_WEBDAV_USER=your_username \
  -e ZOTERO_WEBDAV_PASSWORD=your_password \
  -- uvx --from git+https://github.com/RaulSimpetru/zotero-library-mcp zotero-mcp

Claude Desktop

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "zotero": {
      "command": "/full/path/to/uvx",
      "args": ["--from", "git+https://github.com/RaulSimpetru/zotero-library-mcp", "zotero-mcp"],
      "env": {
        "ZOTERO_LIBRARY_ID": "your_library_id",
        "ZOTERO_API_KEY": "your_api_key",
        "ZOTERO_WEBDAV_URL": "https://your-webdav-server.com",
        "ZOTERO_WEBDAV_USER": "your_username",
        "ZOTERO_WEBDAV_PASSWORD": "your_password"
      }
    }
  }
}

Note: Claude Desktop doesn't inherit your shell's PATH, so you need the full path to uvx. Find it with which uvx in your terminal.

ChatGPT on the web (Apps SDK / developer mode)

ChatGPT web connects to an HTTPS Streamable HTTP endpoint. Start the server locally with the HTTP transport, then make it reachable through Secure MCP Tunnel or another authenticated HTTPS deployment:

ZOTERO_LIBRARY_ID=your_id ZOTERO_API_KEY=your_key \
  uvx --from git+https://github.com/RaulSimpetru/zotero-library-mcp zotero-mcp \
  --transport streamable-http \
  --host 127.0.0.1 \
  --port 8000 \
  --allowed-host your-tunnel.example.com

The MCP endpoint is https://your-tunnel.example.com/mcp. Enable developer mode in ChatGPT, create a developer-mode app, and enter that URL as the MCP server URL. See OpenAI's Connect from ChatGPT guide for the current UI flow.

Security: The safest personal setup is OpenAI Secure MCP Tunnel with the MCP server bound to loopback. HTTP mode disables all server-path reads and writes by default. attach_file accepts ChatGPT's authorized file object, while download_pdf returns an opaque MCP resource link. Safety annotations are approval hints, not an authorization boundary.

For a public deployment, configure an external OAuth 2.1 identity provider. The server validates JWT access tokens against its JWKS endpoint:

export ZOTERO_MCP_OAUTH_ISSUER=https://auth.example.com
export ZOTERO_MCP_OAUTH_RESOURCE=https://zotero.example.com
export ZOTERO_MCP_OAUTH_JWKS_URL=https://auth.example.com/.well-known/jwks.json
export ZOTERO_MCP_OAUTH_SCOPES=zotero:read,zotero:write

The authorization server must publish OAuth/OIDC discovery metadata, support the MCP OAuth 2.1 flow with PKCE, issue tokens for ZOTERO_MCP_OAUTH_RESOURCE, and include the configured scopes. See OpenAI's authentication guide. For testing behind an already authenticated gateway only, --allow-unauthenticated-http explicitly acknowledges an unauthenticated non-loopback listener.

This process still uses one server-side Zotero API key. Every authenticated MCP client can target libraries available to that key, including shared groups. Use a key scoped to the libraries intended for those clients. A true multi-user service must map the verified OAuth identity to separate Zotero credentials and enforce per-user authorization; that deployment architecture is intentionally outside this personal-server package.

If an HTTP deployment genuinely needs server paths, enable them only inside confined roots:

zotero-mcp --transport streamable-http \
  --allow-server-files \
  --file-root /srv/zotero-mcp/exports

HTTP launch settings can also be supplied as environment variables:

CLI option

Environment variable

Default

--transport

ZOTERO_MCP_TRANSPORT

stdio

--host

ZOTERO_MCP_HOST

127.0.0.1

--port

ZOTERO_MCP_PORT or PORT

8000

--http-path

ZOTERO_MCP_HTTP_PATH

/mcp

--allowed-host

ZOTERO_MCP_ALLOWED_HOSTS (comma-separated)

local hosts

--allowed-origin

ZOTERO_MCP_ALLOWED_ORIGINS (comma-separated)

local origins

--stateless-http

ZOTERO_MCP_STATELESS_HTTP

false

--allow-unauthenticated-http

ZOTERO_MCP_ALLOW_UNAUTHENTICATED_HTTP

false

--allow-server-files

ZOTERO_MCP_ALLOW_SERVER_FILES

false in HTTP mode

--file-root

ZOTERO_MCP_FILE_ROOTS (comma-separated)

none

Run standalone

ZOTERO_LIBRARY_ID=your_id ZOTERO_API_KEY=your_key \
  uvx --from git+https://github.com/RaulSimpetru/zotero-library-mcp zotero-mcp

Personal and shared group libraries

The environment variables select the default library. Existing calls that omit library arguments continue to use that default.

Call list_libraries() to discover the key owner's personal library and shared groups. Results include name, library_id, library_type, is_default, and key_permissions. Group results are paginated with limit and start; follow next_start until it is null. Discovery also works when the default is a group.

Every other tool accepts optional library_id and library_type arguments:

list_libraries()
list_collections(library_id="123456", library_type="group")
search_library(query="ultrasound", library_id="123456", library_type="group")
get_item_details(item_key="<key from that group>", library_id="123456", library_type="group")
search_library(query="ultrasound")  # Uses the configured default again

Pass both arguments to select a library, or omit both. Use IDs returned by list_libraries, rather than group names. Selection applies to one call and never changes the environment or another client's target, including concurrent calls. Item and collection keys must come from the selected library. Zotero enforces the API key's permissions and the user's group rights; a denied group request fails without falling back to the personal library. health_check accepts the same arguments to verify a specific library without writing to it.

Group attachments use Zotero's built-in storage. WebDAV is used only for the configured personal library, even when the same server accesses shared groups.

Environment Variables

Variable

Required

Description

ZOTERO_LIBRARY_ID

Yes

Default Zotero user or group library ID

ZOTERO_API_KEY

Yes

API key with read/write permissions

ZOTERO_LIBRARY_TYPE

No

Default library type: user (default) or group

CROSSREF_MAILTO

No

Your email for CrossRef polite pool (faster API access)

UNPAYWALL_EMAIL

No

Contact email for open-access PDF lookup (defaults to CROSSREF_MAILTO)

ZOTERO_WEBDAV_URL

No

WebDAV URL for file storage (e.g. https://dav.example.com)

ZOTERO_WEBDAV_USER

No

WebDAV username

ZOTERO_WEBDAV_PASSWORD

No

WebDAV password

ZOTERO_MCP_OAUTH_ISSUER

No

External OAuth/OIDC issuer URL for protected HTTP deployments

ZOTERO_MCP_OAUTH_RESOURCE

No

Canonical HTTPS MCP resource/audience URL

ZOTERO_MCP_OAUTH_JWKS_URL

No

JWKS URL used to verify JWT access tokens

ZOTERO_MCP_OAUTH_SCOPES

No

Comma-separated required scopes (defaults to read and write)

ZOTERO_MCP_FILE_ROOTS

No

Comma-separated allowed roots when HTTP server paths are enabled

Note: If all three ZOTERO_WEBDAV_* variables are set, attachments in the configured personal library use WebDAV instead of Zotero's built-in storage. Group attachments always use Zotero storage. The server automatically appends /zotero to the WebDAV base URL, matching Zotero Desktop's behavior.

Version 0.10.2

  • Install as a Claude Code plugin: /plugin install zotero --marketplace RaulSimpetru/zotero-library-mcp.

  • An empty ZOTERO_LIBRARY_TYPE now means the default (user), as plugin installs pass unset optional settings as empty strings.

Version 0.10.1

  • Attaching files to Zotero storage works again (group libraries and setups without WebDAV): Zotero rejects the full local path Pyzotero sent as the filename. Uploads are now confirmed, and a rate-limited or failed upload is reported instead of leaving an empty attachment.

  • list_tags returns every tag; Zotero's tag paging metadata is wrong past 200 tags, which made the old listing drop the rest.

  • Leftover query parameters no longer leak between calls (e.g. a duplicate check after fetching an item template only searched items of that type).

  • Searches and tag renames containing the word "tags" no longer crash.

  • Tagging, filing, and editing notes or annotations works on trashed items.

  • Highlights land correctly on rotated pages with offset crop boxes, match whole words, check for duplicates at the same location only, and report a missing occurrence instead of highlighting a different passage.

  • arXiv imports detect existing copies of any version of the paper.

  • CrossRef imports keep organization authors and editors and map books, edited books, chapters, and dissertations to the right item types; Open Library books get their authors from the work record.

  • verify_items handles DataCite DOIs (arXiv, Zenodo), HTML in CrossRef titles, and subtitles; health_check reports read-only keys as write_access: false.

  • BibTeX exports keep Zotero's order and unique citekeys across pages.

  • Lists of child items (attachments, notes, annotations) are no longer capped at 100; linked PDFs are skipped, and standalone PDFs can be read.

  • Removing the last tag color works; deleting tags containing || is refused.

  • Hardening for hosted HTTP deployments: downloads connect to the validated IP (DNS rebinding), JWKS refetches are rate-limited, and file saves use exclusive temporary files.

  • DOI imports no longer create duplicates. Zotero's search does not index DOIs, so the old check never matched; imports now search the resolved title and compare DOIs (including DOI: lines in Extra).

  • ISBN imports no longer create duplicates of books stored with hyphenated ISBNs; ISBN-10 and ISBN-13 forms now match each other.

  • search_library returns papers instead of matching attachments and notes.

  • Rate-limited writes are never retried (a retry could duplicate the item) and now fail instead of reporting success.

  • add_papers_by_dois(attach_pdfs=True) downloads PDFs in parallel.

  • search_fulltext and search query top-level items (about 20x faster).

  • Fuzzy search and find_duplicates reuse a library cache that is kept current with Zotero's incremental sync (since=), so repeat calls take well under a second.

  • CrossRef requests use UNPAYWALL_EMAIL as the polite-pool contact when CROSSREF_MAILTO is unset, and retry rate-limited requests.

  • create_annotation highlights quotes that wrap across lines in full, counts occurrence across pages, and uses the PDF's own page labels.

  • PDFs attached during DOI/arXiv import are named after the item title, and the result now says why a PDF was not attached.

  • List output shows the correct year for dates like 12/1/1993.

  • health_check returns library_type as user/group and reports whether open-access PDF lookup (UNPAYWALL_EMAIL) is configured.

  • New list_trash tool for finding keys to pass to restore_item.

  • Faster get_bibtex for item keys, rename_tag, get_recent_items, fuzzy searches, and find_duplicates; Zotero API connections are reused across calls.

  • Full-library and collection get_bibtex exports stop downloading once max_chars is exceeded.

  • get_item_fulltext prefers a PDF's index over a web snapshot's.

  • find_duplicates reports items_scanned and scan_capped.

  • search falls back to the item's zotero.org link when it has no URL.

  • Shorter tool descriptions; library targeting is explained once in the server instructions.

Version 0.10.0

  • Discover personal and shared libraries with list_libraries.

  • Target a library on each tool call using library_id and library_type; existing calls keep the configured default.

  • Keep concurrent calls and nested exports scoped to the selected library.

  • Use Zotero storage for shared-library attachments and personal WebDAV only for the configured personal library.

  • Keep current dependency imports and HTTP logging compatible with MCP stdio.

Restart the MCP connection after upgrading to load the new tool schemas.

Upgrading to 0.8

Two path-writing operations were split from their read-only counterparts so remote clients can apply correct safety approvals:

  • get_bibtex(save_path=...) is now save_bibtex(save_path=...); get_bibtex only returns data.

  • download_pdf(save_path=...) is now save_pdf(save_path=...); download_pdf returns an opaque MCP resource link.

Existing read-only calls to get_bibtex and download_pdf continue to work.

0.8.1

  • PDF and annotation-preview resources now keep their precise MIME type when read by clients.

  • PDF downloads report progress and return a clear WebDAV timeout error.

  • health_check reports API-key write permission without modifying the library.

  • Server instructions are shorter, reducing repeated client context usage.

How it works

  1. You provide a DOI, arXiv ID, or ISBN

  2. The server queries the appropriate API to get full metadata:

  3. Metadata is mapped to Zotero's item format (title, authors, journal/publisher, date, etc.)

  4. The item is created in your Zotero library via the Zotero Web API

License

MIT

mcp-name: io.github.RaulSimpetru/zotero-library-mcp

Available Tools

51 tools
add_book_by_isbnAdd Book By IsbnB

Add a book to your Zotero library by its ISBN.

Resolves metadata automatically via Open Library and creates the item in Zotero. Optionally add it to a specific collection.

Args: isbn: The ISBN of the book (e.g. "9780262046824") collection_id: Optional Zotero collection key to add the book to

ParametersJSON Schema
NameRequiredDescriptionDefault
isbnYes
library_idNo
library_typeNo
collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, so the write and external-network nature is known without the description. The description adds the specific source (Open Library metadata resolution) and that a new item is created, which is useful context. It says nothing about duplicate-ISBN handling, permissions, or failure behavior, so with annotations carrying the safety burden a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by mechanism and optional behavior, then a compact Args block. No wasted sentences. The Args section only covers 2 of 4 parameters, which is a completeness issue rather than a verbosity one.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and annotations cover the safety profile. But with 4 parameters at 0% schema coverage, the omission of library_id and library_type leaves an agent unable to tell how to target a group library vs a user library. Minimum viable but noticeably incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it documents only isbn (with a format example) and collection_id. The library_id and library_type parameters appear nowhere, leaving half the parameters with no semantics at all. It partially compensates but falls well short of what 0% coverage requires.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+identifier scheme (add a book by ISBN to Zotero), which naturally distinguishes it from the sibling family (add_paper_by_doi, add_paper_by_arxiv_id, add_item_from_metadata). It also specifies metadata resolution via Open Library and optional collection placement. However, it never explicitly contrasts itself with those siblings, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the ISBN-based identifier and the 'optionally add it to a specific collection' clause, but there is no explicit when-to-use guidance, no statement of when to prefer add_item_from_metadata or add_paper_by_doi instead, and no prerequisites declared. Adequate but with clear gaps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_item_from_metadataAdd Item From MetadataB

Add an item from manual, CSL-like, or previously parsed metadata.

The Zotero item template determines which fields are accepted for the requested item type, preventing invalid cross-type metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
fieldsNo
creatorsNo
item_typeYes
library_idNo
library_typeNo
collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds a genuine behavioral detail beyond that: the Zotero item template gates which fields are accepted and blocks invalid cross-type metadata. However, it says nothing about where the item lands or permission requirements, so it adds only moderate value on top of 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the purpose front-loaded and no filler. The second sentence on template validation is the only part that could be tightened, but overall it is well-sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. But for a 7-parameter creation tool with 0% schema coverage, the description omits how items are targeted to a library or collection and gives no guidance on the creators/fields shapes, leaving real gaps for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and there are 7 parameters, so the description must carry the burden and largely does not. It loosely relates the item template to item_type and fields, but says nothing about creators, library_id, library_type, or collection_id, whose formats and roles are undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

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 an item from ... metadata') and identifies the input sources (manual, CSL-like, or previously parsed metadata). This distinguishes it from identifier-based siblings such as add_paper_by_doi and add_book_by_isbn, though it never names them directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: describing the input as 'manual, CSL-like, or previously parsed metadata' hints at when to prefer this over the DOI/ISBN/arXiv siblings, but there is no explicit when-to-use or when-not statement, and no routing to alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_noteAdd NoteB

Add a note to a Zotero item.

The note is created as a child of the specified item. Supports HTML formatting (e.g. bold, italic, lists).

Args: item_key: The parent Zotero item key to attach the note to note: The note content (plain text or HTML)

ParametersJSON Schema
NameRequiredDescriptionDefault
noteYes
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds useful behavioral detail (child-of-item attachment, HTML support), but omits auth/permission needs and how library_id/library_type defaulting behaves. Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose sentence, then two short clarifying sentences and a compact args list. The args block partly duplicates schema content, but with 0% schema coverage that repetition is doing real work rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and annotations cover the safety profile. Still, for a 4-parameter mutation tool, the description leaves the library scoping parameters and any permission requirements unaddressed, which is a meaningful gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it documents the two required parameters (item_key as parent key, note as plain text or HTML). The optional library_id and library_type parameters are left completely unexplained in both schema and description, so compensation is only partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add a note to a Zotero item') and clarifies that the note becomes a child of the target item, which implicitly separates it from update_note/delete_note/list_notes. However, it never names an alternative sibling or explicitly scopes itself against them, so it falls short of the top tier.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says what the tool does but gives no when-to-use or when-not-to-use guidance, and never mentions update_note or list_notes as alternatives. An agent must infer usage purely from the name and verb.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_paper_by_arxiv_idAdd Paper By Arxiv IdA

Add a paper to your Zotero library by its arXiv ID.

Fetches metadata from the arXiv API. If the paper has a DOI, resolves it via CrossRef for richer metadata; otherwise creates a preprint entry directly. Optionally add it to a specific collection.

Args: arxiv_id: The arXiv ID of the paper (e.g. "2301.07041") collection_id: Optional Zotero collection key to add the paper to

ParametersJSON Schema
NameRequiredDescriptionDefault
arxiv_idYes
library_idNo
library_typeNo
collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations by disclosing the external service chain: it fetches from the arXiv API and conditionally resolves via CrossRef, which explains the openWorldHint and the branching behavior (DOI present → richer metadata; absent → preprint entry). It does not mention auth requirements or failure modes, and the output schema covers the return, so a 4 is fair.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then the behavior, then the optional collection. The Args block largely restates schema fields, which is slightly redundant, but the overall text is tight and earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The mutation behavior and external-fetch chain are covered, and the output schema handles return values. However, for a 4-parameter write tool with 0% schema coverage, the untouched library_id/library_type fields and the absence of scoping context leave meaningful gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it documents only arxiv_id (with an example) and collection_id. The library_id and library_type parameters are never mentioned, leaving half the inputs undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add a paper to your Zotero library by its arXiv ID') and the identifier type immediately distinguishes it from the sibling add_paper_by_doi. An agent can select this over the DOI/ISBN/metadata variants without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the arxiv_id requirement and the optional collection note, but the description never explicitly states when to prefer this over add_paper_by_doi or add_item_from_metadata, nor any exclusions. Implied rather than stated guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_paper_by_doiAdd Paper By DoiA

Add a paper to your Zotero library by its DOI.

Resolves metadata automatically via CrossRef and creates the item in Zotero. Optionally add it to a specific collection.

Args: doi: The DOI of the paper (e.g. "10.1038/nature12373") collection_id: Optional Zotero collection key to add the paper to

ParametersJSON Schema
NameRequiredDescriptionDefault
doiYes
library_idNo
library_typeNo
collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true), so the bar is lower. The description usefully explains that metadata is resolved automatically via CrossRef, which accounts for the open-world network behavior, and that the item is created in Zotero. It omits failure/duplicate handling and auth requirements, but adds real context 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose followed by behavioral detail and an Args block; every line is meaningful and no sentence is wasted. Slight overlap between 'Add a paper to your Zotero library' and 'creates the item in Zotero' keeps it from a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, and the CrossRef resolution is described. However, for a mutating, open-world tool the two undocumented library-targeting parameters leave a real gap an agent must fill from the schema alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the whole burden, but it only documents two of the four parameters. The 'doi' entry adds an example format and 'collection_id' is explained, yet 'library_id' and 'library_type' (including the user/group enum) are unexplained anywhere.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+key ('Add a paper to your Zotero library by its DOI') and explains the mechanism (metadata resolved via CrossRef and item created in Zotero). An agent can immediately tell it apart from add_paper_by_arxiv_id, add_book_by_isbn, and the bulk add_papers_by_dois.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The DOI-scoped phrasing implies the appropriate context ('when you have a DOI'), and the sibling names make alternatives inferable, but the description never explicitly states when to prefer this over add_paper_by_arxiv_id or add_item_from_metadata, nor any exclusions. Usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_papers_by_doisAdd Papers By DoisB

Add multiple papers to Zotero by their DOIs (batch, up to 50).

Args: dois: List of DOIs to add collection_id: Optional Zotero collection key to add all papers to

ParametersJSON Schema
NameRequiredDescriptionDefault
doisYes
library_idNo
attach_pdfsNo
library_typeNo
collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations establish the safety profile (readOnlyHint=false, openWorldHint=true, destructiveHint=false), so the bar is lower. The description usefully adds the batch-size ceiling, but says nothing about PDF attachment behavior, library resolution, duplicates, or partial failures. Adequate with clear gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the essential fact (batch DOI add, max 50) before the Args block. The Args section restates the schema fields but is short and wastes no prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema covers return values and the annotations cover safety, but three of five input parameters and the fallback library/collection resolution behavior are undocumented. For a mutating batch tool this leaves meaningful gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 5 parameters, so the description must compensate. It documents only dois and collection_id, leaving library_id, library_type, and attach_pdfs completely unexplained in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (add papers by DOI) and pins the batch scope with 'multiple' and 'up to 50', which tells an agent this handles bulk input. It stops short of explicitly naming its singular sibling add_paper_by_doi, but the word 'multiple' still separates them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to prefer this over add_paper_by_doi or add_item_from_metadata. The 'batch, up to 50' note is a constraint, not a usage rule, and nothing states prerequisites or failure conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_tagsAdd TagsB

Add one or more tags to a Zotero item. Optionally assign a color to all added tags.

Args: item_key: The Zotero item key tags: List of tags to add color: Optional hex color code (e.g. '#FF0000') to assign to the added tags

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsYes
colorNo
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the mutation/safety profile is covered structurally. The description adds one useful nuance — that the color applies to ALL added tags — but is silent on idempotency (what happens when a tag already exists), whether tag names are created implicitly, and whether this needs write permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the action and optional behavior before the Args block, and there is no filler. The Args block largely restates the schema titles, which is mildly redundant but keeps the description self-contained.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover the safety profile. The remaining gaps are the two undocumented library parameters and the absence of any guidance on duplicate/conflicting tag handling, which leaves the description only minimally complete for this tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the load; it documents item_key, tags and color, and adds the hex format example ('#FF0000'), which is genuine added meaning. However, library_id and library_type are entirely undocumented in both schema and description, leaving a real gap for a 5-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add one or more tags to a Zotero item') and mentions the optional color side effect, so the operation is unambiguous. It does not, however, distinguish itself from close siblings like set_tag_color or remove_tags, so an agent must infer the boundary itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance and no named alternative, even though the sibling list contains several overlapping tag tools (set_tag_color, remove_tags, delete_tags, rename_tag). The only usage-adjacent statement is that color is optional, which is a behavior note rather than routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_to_collectionAdd To CollectionB

Add an existing Zotero item to a collection.

Args: item_key: The Zotero item key (from search results) collection_id: The collection key to add it to

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo
collection_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=false), so the bar is lower. The description adds the useful constraint that the item must already exist, but does not disclose idempotency, duplicate handling, or error behavior for invalid keys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in a single clear sentence, and the Args block is compact. Slightly redundant formatting for a short definition, but no wasted prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. But for a 4-parameter mutation tool, the description omits the two library-scoping params and any mention of failure modes, leaving material gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It documents the two required params with helpful context ("from search results", "collection key") but leaves the optional library_id and library_type entirely undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Add an existing Zotero item to a collection"), which is clearly distinguishable from the sibling remove_from_collection. However, it does not explicitly name or differentiate itself from siblings beyond the obvious add/remove polarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit when-to-use guidance, no prerequisites, and no alternatives, aside from the parenthetical "(from search results)" on item_key. It never says what to do if the item is already in the collection, nor points to remove_from_collection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

attach_fileAttach FileB

Attach a ChatGPT file input or an authorized local file to an item.

Args: item_key: The Zotero item key to attach the file to file: File object supplied by ChatGPT through openai/fileParams file_path: Local server path; stdio only unless HTTP roots are explicitly enabled

ParametersJSON Schema
NameRequiredDescriptionDefault
fileNo
item_keyYes
file_pathNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, so safety profile is partly covered. The description adds a genuinely useful constraint (file_path is stdio only unless HTTP roots are enabled), but says nothing about what happens on collision, overwrite, or failure. Baseline 3 with partial added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in one sentence, and the Args block is compact. Slight redundancy since the arg list restates schema field names, but each line adds semantic detail rather than pure repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Has an output schema, so return values need not be explained. For a mutation tool with 5 params, however, the omission of library_id/library_type semantics and the file/file_path selection rule leaves meaningful gaps an agent must guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for top-level params, so the description carries the burden. It documents item_key, file, and file_path but leaves library_id and library_type completely unexplained, and gives no rule for mutual exclusivity of file vs file_path. Partial compensation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource+target: 'Attach a ChatGPT file input or an authorized local file to an item.' An agent can distinguish this from list_attachments/download_pdf/save_pdf without opening schemas, though it never names a sibling explicitly for routing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance. It says the tool attaches a file, but doesn't explain when to choose it over save_pdf, download_pdf, or how it relates to list_attachments. It also doesn't resolve the file-vs-file_path choice beyond a constraint note.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_annotationCreate AnnotationA

Highlight a text passage in a PDF attached to a Zotero item.

Searches the PDF for the quoted text and creates a visible highlight annotation in Zotero's PDF reader. Tries a normalized word match first, then fuzzy matching (for OCR errors, hyphenation differences, or minor transcription mismatches).

Smart overlap handling:

  • If the same text is already highlighted, appends the new comment to the existing annotation instead of creating a duplicate.

  • If the new text is a sub-passage of an existing highlight (or vice versa), the new highlight is created in a contrasting color so both are visually distinct.

Args: item_key: The Zotero item key (the parent item, not the attachment) quoted_text: The text passage to highlight in the PDF (fuzzy matching handles minor differences from the actual PDF text) comment: Optional comment to attach to the highlight color: Highlight color as hex (default "#ffd400" yellow) max_l_dist: Maximum Levenshtein distance for fuzzy matching. Default is ~20% of the search text length. Increase if the PDF has many OCR errors; decrease for stricter matching. attachment_key: Optional PDF attachment key when the item has multiple PDFs page_number: Optional one-based page number to search occurrence: One-based occurrence to highlight when text repeats

ParametersJSON Schema
NameRequiredDescriptionDefault
colorNo#ffd400
commentNo
item_keyYes
library_idNo
max_l_distNo
occurrenceNo
page_numberNo
quoted_textYes
library_typeNo
attachment_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=false), while the description adds rich behavior: normalized-then-fuzzy matching, the Levenshtein fallback for OCR/hyphenation issues, appending comments to existing overlapping annotations instead of duplicating, and contrasting colors for sub-passages. This is substantial disclosure beyond what structured fields provide, and it is consistent with destructiveHint=false since operations are additive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the behavior/matching details are organized under clear headings, with an Args block that adds meaning rather than restating schema titles. The Args list is somewhat long, but given 0% schema coverage each entry earns its place; only the two undocumented library parameters are omissions rather than bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description covers the tricky parts of this operation (fuzzy matching, overlap/duplicate behavior). It is incomplete on failure modes (what happens when no match is found) and on library scoping via the undocumented library_id/library_type params.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it mostly delivers: it clarifies that item_key is the parent item rather than the attachment, gives the color default, and explains max_l_dist tuning tradeoffs (increase for OCR errors, decrease for strictness) plus one-based semantics for page_number and occurrence. It leaves library_id and library_type entirely undocumented, so it does not fully compensate for the 10-parameter surface.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb, resource, and scope ('highlight a text passage in a PDF attached to a Zotero item'), which cleanly separates it from siblings like update_annotation, delete_annotation, and get_annotations. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is clear: it's for creating visible PDF highlights with support for fuzzy text matching, and the 'Smart overlap handling' section explains what happens when text is already highlighted or is a sub-passage. However, it never explicitly names alternatives (e.g., update_annotation for modifying an existing highlight, or get_annotations to check first) or states when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_collectionCreate CollectionC

Create a new collection in your Zotero library.

Args: name: Name for the new collection parent_collection_id: Optional parent collection key to nest under

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
library_idNo
library_typeNo
parent_collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the agent knows this is a non-destructive local write. The description adds no behavioral context beyond that – nothing about duplicate-name handling, whether parent_collection_id must reference an existing key, or permission requirements – but the annotation coverage keeps this at a baseline 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence stating the action, followed by a compact Args block. It is appropriately sized with no filler, though the Args block partly restates schema titles rather than adding new meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, but with 4 parameters at 0% schema coverage and two parameters undocumented anywhere, plus no guidance on nesting validity or duplicate names, the definition is not complete enough for confident invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it documents only 2 of 4 parameters (name, parent_collection_id) and silently omits library_id and library_type. Since library_type accepts 'user'/'group' and library_id selects the target library, the omission is a real gap for a multi-library tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a new collection in your Zotero library'), which cleanly distinguishes it from siblings like add_to_collection, rename_collection, and delete_collection. However, it does not explicitly name or contrast with any sibling, leaving the routing inference to the agent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is given. It doesn't clarify how this differs from add_to_collection (adding items to an existing collection) or whether a collection must be created before items can be added, which is exactly the ambiguity an agent faces here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_annotationDelete AnnotationC
Destructive

Permanently delete a Zotero annotation.

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idNo
library_typeNo
annotation_keyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false. The description adds 'Permanently,' which clarifies that the deletion is irreversible rather than a recoverable trash operation. However, it says nothing about required permissions, cascading effects, or confirmation behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short front-loaded sentence with no filler. It is concise and direct, though arguably too terse for a destructive operation with three parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description only covers the basic action and permanence. It omits parameter semantics for a 3-parameter tool with 0% schema coverage, provides no usage guidance, and does not clarify library scoping. Output schema existence means return values need not be explained, but the remaining gaps are substantial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for all three parameters. The description does not mention annotation_key, library_id, or library_type, nor does it explain that annotation_key is required or how library context is determined. It fails to compensate for the undocumented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'delete a Zotero annotation.' This clearly distinguishes it from create_annotation, update_annotation, and get_annotations by action, though it does not explicitly name any sibling tool or compare itself to alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides no when-to-use guidance, prerequisites, or alternative routing. The word 'Permanently' hints at caution, but there is no instruction about when this should be used instead of update_annotation, trash_item, or other sibling operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_collectionDelete CollectionA
Destructive

Permanently delete a collection from your Zotero library.

Items in the collection are NOT deleted — they remain in your library.

Args: collection_id: The collection key to delete

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idNo
library_typeNo
collection_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely non-obvious context beyond that: deletion is permanent and, crucially, does not cascade to contained items, which the destructive hint alone cannot convey. It stops short of permissions or confirmation/irreversibility details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short lines, front-loaded with the action and its most important consequence. The 'Args:' block adds little value but costs little space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the key cascade behavior is disclosed. However, for a destructive, irreversible operation with two entirely undocumented optional scoping parameters, the definition is thinner than it should be.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the burden, but it only restates collection_id ('The collection key to delete'). library_id and library_type — which determine which library the collection is deleted from — are undocumented in both the schema and the description, leaving a meaningful scoping gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Permanently delete a collection from your Zotero library'), which cleanly separates it from delete_item, delete_tags, and delete_note in the sibling set. The adverb 'Permanently' also distinguishes it from soft-delete siblings like trash_item.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No statement of when to use this versus alternatives such as remove_from_collection (which removes items but keeps the collection) or trash_item. The only guidance is a consequence note, which informs behavior rather than tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_itemDelete ItemB
Destructive

Permanently delete an item from your Zotero library.

Args: item_key: The Zotero item key to delete

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=false, so the safety profile is covered. The description adds useful context by emphasizing 'permanently' (non-recoverable, unlike trash), but says nothing about permission requirements, cascading effects on attachments/notes, or irreversibility beyond the adverb.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Short and front-loaded, with the destructive nature stated first. The Args block is slightly redundant with the schema but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations carry the safety profile. However, for a destructive mutation tool with 0% schema description coverage, the two undocumented optional parameters and the absent trash_item comparison leave real gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description only restates item_key, which the schema already names. The optional library_id and library_type parameters are documented in neither place, so the description fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('permanently delete') and resource ('item from your Zotero library'), and the adverb 'permanently' implicitly differentiates it from the sibling trash_item. However, it never names trash_item explicitly, so an agent must infer the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'permanently' hints at when this tool is appropriate versus a recoverable soft-delete like trash_item, but there is no explicit when-to-use, when-not-to-use, or named alternative. Usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_noteDelete NoteC
Destructive

Permanently delete a Zotero note.

ParametersJSON Schema
NameRequiredDescriptionDefault
note_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds the irreversibility nuance via 'permanently', which is real value, but it omits permission requirements, library-scoping behavior, and any recovery caveat.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single clean, front-loaded sentence with no wasted words. Its brevity is efficient, though it borders on under-specification rather than deliberate conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive three-parameter delete tool with 0% schema coverage, the description is too thin. Even with an output schema present (relieving the need to explain returns), the total absence of parameter and scoping context leaves the agent under-informed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the three parameters, so the description carries the full burden and does not compensate. It never explains note_key, or the meaning/behavior of the optional library_id and library_type scoping parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Permanently delete a Zotero note'), and 'note' distinguishes it from delete_item and delete_annotation, while 'permanently' distinguishes it from trash_item. Clear, though it names no sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance and no named alternative. 'Permanently' hints at irreversibility but the description never tells the agent to reach for trash_item for recoverable deletion or explains when this tool is appropriate over other delete tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_tagsDelete TagsB
Destructive

Delete tags from the entire Zotero library. This removes the tags from all items.

Args: tags: List of tag names to delete from the library

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description reinforces the blast radius ('removes the tags from all items'), which is useful, but adds nothing about reversibility, permission requirements, or effect on items sharing the tag.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and efficient overall. The 'Args:' block is slightly redundant, re-stating that tags are deleted 'from the library' after the opening sentence already said 'entire Zotero library,' but the total length is reasonable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be documented. However, for a destructive library-wide operation with two undocumented parameters and no sibling/usage routing, the description leaves meaningful gaps an agent would need to resolve before calling it safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it only documents the 'tags' argument. The library_id and library_type parameters are completely unaddressed in either the schema or the description, leaving no guidance on how the target library is selected.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete tags') and adds a scope qualifier ('from the entire Zotero library... from all items') that implicitly distinguishes it from the sibling remove_tags, which would operate on specific items. It does not name that sibling explicitly, so an agent must infer the contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is given. The closest sibling, remove_tags, is never mentioned, leaving the agent to guess which tool handles item-scoped tag removal versus library-wide tag deletion. The scope phrase is the only implicit signal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

download_pdfDownload PdfA
Read-onlyIdempotent

Return a PDF as a remote-safe MCP resource link.

Useful when Zotero's fulltext index is incomplete (e.g. for books) and you need to read the PDF directly with other tools.

Args: item_key: The Zotero item key (the parent item, not the attachment) attachment_key: Optional PDF attachment key when the item has multiple PDFs

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo
attachment_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, so the safety profile is covered. The description adds meaningful behavior beyond that: the return value is a resource link rather than raw bytes, which matters for how the agent consumes the result. It does not cover permissions or failure modes (e.g. missing attachment).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key behavior and usage rationale are front-loaded in two short sentences, followed by an Args block. It is efficient, though the Args block restates parameter names already visible in the schema and could be trimmed to only the non-obvious semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is not required, and the description captures the resource-link behavior well. The gaps are the two library scoping parameters, which are unexplained despite 0% schema coverage, and the absence of any differentiation from the closely related save_pdf sibling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden, and it partially does: it clarifies that item_key is the parent item (not the attachment) and explains attachment_key is for disambiguating multiple PDFs. However, library_id and library_type are undocumented in both schema and description, leaving half the parameters opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: returning a PDF as a remote-safe MCP resource link, which is more precise than a generic 'download file'. It implicitly distinguishes itself from the fulltext-oriented siblings by framing itself as the fallback when the fulltext index is incomplete, though it never names a sibling such as get_item_fulltext or save_pdf directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear triggering condition: use it when Zotero's fulltext index is incomplete (e.g. books) and the PDF must be read directly with other tools. That is genuine when-to-use guidance that routes the agent away from the search/get_fulltext siblings, but no explicit when-not-to-use or named alternative is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetchFetchC
Read-onlyIdempotent

Company-knowledge compatible fetch for one Zotero item key.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds no behavioral context beyond that - no auth requirements, rate limits, or error behavior for a missing/invalid item key.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is short and front-loaded, which is good, but 'Company-knowledge compatible' is filler that occupies the most prominent position without earning its place. The one substantive clause is otherwise efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, but with 3 params at 0% schema coverage and no usage routing against a nearly identical sibling, the description is too thin for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for all three parameters. It only gestures at the required 'id' ('one Zotero item key'); library_id and library_type (with its user/group enum) are entirely unexplained in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase 'fetch for one Zotero item key' names a verb and resource, which is useful, but 'Company-knowledge compatible' is meaningless jargon that conveys nothing to an agent. It also fails to differentiate from the close sibling get_item_details, leaving it ambiguous which one to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus get_item_details, search_library, or any other retrieval sibling, and no stated preconditions. The agent is left to infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_duplicatesFind DuplicatesB
Read-onlyIdempotent

Find duplicate top-level items by DOI, ISBN, or normalized title.

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldNoDOI
limitNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safety profile (read-only, idempotent, non-destructive, closed-world). The description adds scope by saying 'top-level items' and matching criteria, but it does not describe return grouping, pagination behavior, or how limits affect results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is a single front-loaded sentence with no wasted text. It communicates the core operation efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema and annotations reduce the burden, but the description omits usage context and most parameter semantics. For a tool with library scoping and a limit parameter, it is not complete enough to guide correct invocation beyond the basic purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It mentions possible matching values for the field parameter (DOI, ISBN, normalized title), but says nothing about limit, library_id, or library_type, leaving three of four parameters unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: find duplicate top-level items. It also names the matching criteria (DOI, ISBN, normalized title), so an agent can understand the operation without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for duplicate detection but gives no explicit guidance on when to use it versus search_library or other sibling tools. It also does not explain field selection, library scoping, or limits.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_annotationsGet AnnotationsB
Read-onlyIdempotent

List all highlights and annotations on a paper's PDF.

Args: item_key: The Zotero item key (the parent item, not the attachment) limit: Maximum number of annotations to return (default 100)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and a closed-world scope, so the safety profile is fully covered. The description adds one genuinely useful behavioral note — item_key must be the parent item, not the attachment — which prevents a common misuse. Beyond that it says nothing about pagination or how the 100-item limit interacts with 'all'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded single-sentence purpose, followed by a compact Args block. The Args restate schema fields but add the parent-item clarification, so the structure earns its space. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, and annotations cover the safety profile. However, the two library-scoping parameters are undocumented, and the description doesn't say how the result is scoped or paginated when limit is hit — a gap an agent invoking across user vs group libraries would care about.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It usefully clarifies the required item_key (parent item, not attachment) and documents limit with its default, but leaves library_id and library_type entirely unexplained in both schema and prose. Two of four parameters are undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'List all highlights and annotations on a paper's PDF.' This is clearly a read operation and implicitly distinguishes itself from the mutation siblings create_annotation, update_annotation, and delete_annotation. It doesn't explicitly name an alternative to route between (e.g. list_notes), but the purpose itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use guidance, prerequisites, or named alternatives. The agent must infer from context that this is the read path for annotations, versus list_notes or list_attachments for adjacent resources, but nothing steers that choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_bibtexGet BibtexA
Read-onlyIdempotent

Export BibTeX entries from your Zotero library.

Can export specific items, an entire collection, or your whole library. Use save_bibtex when the export should be written to a local file.

Args: item_keys: Optional list of item keys to export. If omitted, exports collection or full library. collection_id: Optional collection key to export all items from. include_abstract: Include abstracts in BibTeX output (default False to save tokens). biblatex: Convert output to BibLaTeX format (default False). Remaps fields like journal→journaltitle, address→location, and merges year+month into date. max_chars: Maximum response size; use save_bibtex for larger full-library exports

ParametersJSON Schema
NameRequiredDescriptionDefault
biblatexNo
item_keysNo
max_charsNo
library_idNo
library_typeNo
collection_idNo
include_abstractNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a safe, idempotent, non-destructive read. The description adds behavior beyond that: include_abstract defaults to False specifically to save tokens, max_chars caps response size, and large exports should go to save_bibtex. It does not discuss pagination or auth, but for a read-only export the added context is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and the save_bibtex routing before the argument list. The Args block is efficient and each line earns its place, though the two unexplained library parameters slightly bloat the surface without adding meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value details are unnecessary, and the description covers scope, mode selection, and token/size tradeoffs well. The gap is the undocumented library_id/library_type parameters, which an agent cannot reason about from the description alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it explains five of seven parameters with real semantics, including the non-obvious biblatex field remapping (journal→journaltitle, address→location, year+month→date). However, library_id and library_type are left undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Export BibTeX entries from your Zotero library') and immediately scopes the three export modes (specific items, a collection, whole library). It clearly distinguishes itself from save_bibtex, which writes to a file instead of returning the export.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative tool explicitly and the condition selecting it: 'Use save_bibtex when the export should be written to a local file.' The max_chars note reinforces this by routing large full-library exports to save_bibtex. Both when-to-use and when-not-to-use are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_collection_itemsGet Collection ItemsB
Read-onlyIdempotent

Get items in a specific collection, one page at a time.

Args: collection_id: The collection key to browse limit: Maximum number of items to return per page (default 25, max 100) start: Offset of the first item; pass the value suggested by the previous call's footer to fetch the next page (default 0)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
startNo
library_idNo
library_typeNo
collection_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world semantics, so the safety profile is covered. The description adds non-obvious behavioral context beyond that: results come one page at a time, and the next page is driven by a value surfaced in the previous call's footer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded summary sentence followed by a compact Args block; no filler. The footer-pagination hint is a bit wordy but earns its place by describing a non-obvious workflow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the pagination mechanics are covered. However, the two undocumented library-scoping parameters leave a gap an agent may need to fill to correctly target a collection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must carry the full burden, and it documents only 3 of 5 params. It gives useful detail on collection_id, limit (default 25, max 100), and start (offset, default 0), but library_id and library_type are left entirely unexplained with no enum or type hints from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get items in a specific collection') plus the pagination scope, so the core action is unambiguous. It does not name or contrast against siblings like get_unfiled_items, get_recent_items, or search_library, so an agent must infer which listing tool fits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the pagination loop but gives no when-to-use vs alternatives guidance. Nothing tells the agent why to pick this over get_unfiled_items or search_library when browsing items.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_item_detailsGet Item DetailsC
Read-onlyIdempotent

Get full details of a Zotero item by its key.

Args: item_key: The Zotero item key

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false, and destructiveHint=false, so the safety profile is fully covered elsewhere. The description adds only 'full details' and the key requirement, with no note on what happens if the key is missing or belongs to another library.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence plus a one-line arg note; nothing is padded. The docstring-style 'Args:' block is a bit formal for a one-param restatement, but it costs little.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be described. But with 0% schema coverage and two optional library-scoping parameters unexplained, the description leaves an agent uncertain how to target group versus user libraries.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 3 parameters. The description documents only the required item_key (restating the schema) and says nothing about library_id or library_type, which control which library is queried — a meaningful semantic gap given the user/group enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'Get full details of a Zotero item by its key' — which is clearer than the bare title. It does not, however, distinguish itself from close siblings like get_item_fulltext or search_library, leaving the boundary implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this versus alternatives; get_item_fulltext, get_bibtex, and search_library all plausibly overlap. No prerequisites or exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_item_fulltextGet Item FulltextA
Read-onlyIdempotent

Get bounded plain text from a paper's PDF or Zotero full-text index.

Unlike download_pdf, this returns readable text directly and never exposes a server-local temporary path.

Args: item_key: The Zotero item key (the parent item, not the attachment) attachment_key: Optional PDF attachment key when an item has several PDFs max_chars: Maximum number of characters to return (1,000-200,000)

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
max_charsNo
library_idNo
library_typeNo
attachment_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description still adds real behavioral context: output is bounded by max_chars and no server-local temp path is exposed. It omits behavior when no PDF/full-text exists, but that is minor.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose, then a differentiating sentence, then an Args block. Efficient and readable, though the Args listing partially duplicates what the schema already structures.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return-value explanation is unnecessary, and annotations cover the safety profile. The description is complete enough to call the tool correctly, with the only gaps being the two undocumented library parameters and the no-PDF case.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden. It documents item_key (parent not attachment), attachment_key (for multiple PDFs), and max_chars (1,000-200,000), which is meaningful added value, but library_id and library_type are left entirely undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (get) and resource (bounded plain text from a paper's PDF or Zotero full-text index), and explicitly differentiates itself from the sibling download_pdf. An agent can identify what this returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The contrast with download_pdf ('returns readable text directly and never exposes a server-local temporary path') gives clear guidance on when to prefer this tool. It does not, however, address when to use this vs. search_fulltext, which also touches full-text content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recent_itemsGet Recent ItemsC
Read-onlyIdempotent

Get recently added items from your Zotero library.

Args: limit: Maximum number of items to return (default 10)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is fully covered. The description adds the 'recently added' ordering trait, which is genuine behavioral context, but says nothing about sort order specifics, what library scope defaults to, or result shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose in the first sentence and short overall. The 'Args' block slightly duplicates schema information (the default of 10) but does not bloat the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. But with two of three parameters (library_id, library_type) undocumented and zero usage guidance, the definition is incomplete for a tool an agent must decide how to scope correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description only restates the 'limit' parameter, whose default of 10 is already in the schema — so it adds no new meaning. The library_id and library_type parameters are completely undocumented in both schema and description, leaving an agent unable to know how to scope the query.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get recently added items from your Zotero library'), which is more precise than a generic fetch. However, it does not distinguish itself from adjacent siblings like get_unfiled_items, get_collection_items, or search_library, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'recently added' hints at the use case, but there is no explicit when-to-use guidance, no mention of when NOT to use it, and no named alternative (e.g. search_library for filtered queries). Nothing tells the agent how to choose between this and its many siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_unfiled_itemsGet Unfiled ItemsB
Read-onlyIdempotent

Get items that are not in any collection (unfiled items).

Args: limit: Maximum number of items to return (default 25)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds nothing behavioral beyond that — no ordering, pagination, or library-scoping behavior — so this is the baseline-plus level appropriate when annotations do the heavy lifting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose sentence is front-loaded and wastes no words, and the Args note is efficient. Structure is sound, though the Args block only covers one of three parameters, making it feel truncated rather than complete.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. However, with three optional parameters and 0% schema coverage, the description leaves the library_id/library_type scoping unexplained, which is a real gap for an agent deciding how to scope the query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 3 parameters, so the description must compensate. It only restates the limit parameter (which the schema already documents via a default) and is silent on library_id and library_type, leaving two of three params — including the library scoping that determines what 'unfiled' means — unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'Get items that are not in any collection' — and parenthetically defines 'unfiled' as 'not in any collection,' which meaningfully distinguishes it from get_collection_items and list_collections. It does not explicitly name a sibling, so it lands just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no exclusions, and no alternatives named. An agent must infer from the definition of 'unfiled' that this is the tool for items outside collections, with no comparison to sibling listers like get_recent_items or get_collection_items.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

health_checkHealth CheckA
Read-onlyIdempotent

Check Zotero credentials, library access, and optional file storage setup.

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed-world scope, so the safety profile is covered. The description usefully enumerates what is actually probed (credentials, library access, storage) but says nothing about failure reporting or what a partial failure means.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the enumerated targets read cleanly and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and annotations carry the safety profile for this read-only, idempotent diagnostic. The remaining shortfall is that the two optional scoping parameters are unexplained anywhere.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for both parameters and the description never mentions library_id or library_type, so it adds no meaning about scoping the check to a specific user or group library. With 0% coverage the description is required to compensate and does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

'Check Zotero credentials, library access, and optional file storage setup' names a specific verb plus three concrete resources, and no sibling tool does diagnosis, so it is unambiguous within this tool set.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the setup/verification step to run before other Zotero operations, but the description states no when-to-use condition, no prerequisites, and no alternatives. Adequate but with a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_attachmentsList AttachmentsC
Read-onlyIdempotent

List attachment keys, filenames, MIME types, links, and sizes for an item.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile needs no restating. The description adds only the set of returned fields, which the output schema also covers, and says nothing about pagination via limit or how library scoping affects results. With annotations lowering the bar, this is adequate but thin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler and the verb first. Its brevity is appropriate to the tool's simplicity, though the trailing whitespace suggests an unpolished string rather than a deliberate omission.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be re-explained, but four inputs at zero schema coverage go undocumented in both places, and no scoping or pagination behavior is given. For a tool taking library_type/library_id filters, this leaves real ambiguity about how results are constrained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 4 parameters, and the description adds no meaning for any of them — item_key, limit, library_id, and library_type are entirely unexplained. The listed fields describe output, not inputs, so the description fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('attachments') and names the fields returned (keys, filenames, MIME types, links, sizes). It is recognizable as the read-side counterpart to attach_file, though it never explicitly contrasts itself with sibling tools like get_item_details or download_pdf.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus alternatives such as get_item_details or download_pdf, and no prerequisites noted (e.g., which library context is needed). The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_collectionsList CollectionsC
Read-onlyIdempotent

List all collections in your Zotero library.

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered elsewhere. The description adds nothing beyond that – no note on pagination, ordering, or whether nested subcollections are flattened.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler. It is efficiently sized, though the brevity comes at the cost of the missing parameter and usage detail noted above.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists so return values need not be described, but the tool takes two completely undocumented scoping parameters and offers no usage context. For a listing tool whose behavior varies by library scope, this leaves a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for two parameters (library_id, library_type), and the description never mentions either. Since both are optional with null defaults, an agent gets no hint that they scope the listing to a user or group library, or how to supply a group ID.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all collections') plus the containing scope ('in your Zotero library'), which separates it from list_tags, list_notes and list_libraries. It does not, however, distinguish itself from get_collection_items or explain the collection hierarchy it returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance, no prerequisites, and names no alternative. An agent cannot tell from the text whether to call this or get_collection_items / create_collection when exploring collections.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_librariesList LibrariesA
Read-onlyIdempotent

List the key owner's personal library and a page of shared group libraries.

Use the returned library_id and library_type on subsequent tool calls. This does not change the default library. Pagination applies to groups; the personal library is included on each page. Key permissions are not a guarantee of group membership rights; Zotero enforces access on each call.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
startNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive hints. The description adds genuine behavioral value beyond annotations: it does not change the default library, pagination applies only to groups, the personal library is included on every page, and key permissions do not guarantee group access since Zotero enforces permissions per call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences cover purpose, downstream use, side effects, and access caveats. The most important information is front-loaded, and every sentence adds distinct value with no filler or redundant restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The definition is complete enough for a read-only listing tool with an output schema available. It explains pagination, side effects, and permission caveats, which are the main uncertainties an agent could face. Minor details like the exact meaning of 'key owner' are not spelled out, but they are not essential for invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the two parameters. It explains the pagination model conceptually and that the personal library repeats on each page, which clarifies how limit/start behave. However, it does not explicitly describe limit as page size or start as an offset, leaving some meaning to be inferred from the schema's defaults and parameter names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it lists the key owner's personal library and a page of shared group libraries. This clearly distinguishes it from sibling tools like list_collections or list_tags, so an agent knows exactly what resource is being enumerated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete downstream usage guidance: use the returned library_id and library_type on subsequent calls. It also clarifies pagination behavior and access semantics. It does not explicitly name alternative tools for when not to use it, but the intended context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_notesList NotesC
Read-onlyIdempotent

List child notes for an item with bounded note content.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a safe, idempotent, read-only, closed-world operation, so the safety profile is covered. The description adds one genuinely useful behavioral fact – note content is 'bounded' – but says nothing about truncation thresholds, pagination behavior, or the limit default.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. It is arguably too terse rather than verbose, but nothing in it is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, but for a four-parameter listing tool with zero schema coverage the description leaves library scoping, limit semantics, and pagination behavior unaddressed. An agent cannot tell how to constrain or page results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across four parameters, so the schema contributes no meaning. The description only hints at item_key ('for an item') and limit ('bounded note content'); library_id and library_type, which control the library scope, are entirely undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List child notes') and scopes it to 'an item', which separates it from the mutation siblings add_note, update_note, and delete_note. It does not, however, distinguish itself from list_attachments or explain what 'child' means relative to the item hierarchy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance and no alternative is named. The only contextual cue is the phrase 'for an item', which implies you need an item in hand but never says so explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tagsList TagsC
Read-onlyIdempotent

List all tags in your Zotero library.

Args: limit: Maximum number of tags to return (default 100)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. Beyond that the description adds essentially nothing: it does not say whether the limit truncates silently, whether results are paginated, alphabetized, or whether the count reflects distinct tags across all items. 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.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The prose is a single front-loaded sentence, which is good, but the trailing 'Args:' block is a raw restatement of the schema field, adding no information and slightly padding the definition. Efficient overall, just not well-targeted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, but the definition still omits how tags are scoped per library and what happens when the limit is hit. For a tool with 3 parameters, 0% schema coverage, and two undocumented parameters, this leaves the agent guessing on the main operational question.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it documents only `limit` (already described in the schema via default=100). The `library_id` and `library_type` parameters are completely unexplained in both places, even though `library_type` has a user/group enum that materially changes what is listed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'List all tags in your Zotero library.' An agent can distinguish this from delete_tags, add_tags, rename_tag, and set_tag_color, which are the mutation siblings. It stops short of naming the read-side alternatives it competes with (e.g., list_collections, search_library), so no explicit sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus the many sibling list/search tools, nor any prerequisites about scoping to a user vs group library. The agent must infer usage entirely from the name and the parameter names in the schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_trashList TrashA
Read-onlyIdempotent

List items in Zotero's trash, e.g. to find a key for restore_item.

Args: limit: Maximum number of items per page (default 25, max 100) start: Offset of the first item; use the footer's suggestion for the next page

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
startNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so safety is covered structurally. The description adds genuinely useful behavior beyond that: page-size bounds (max 100) and the pagination idiom of following the footer's suggested next offset.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose sentence is front-loaded and the Args block is compact and scannable. Slightly loose phrasing ('use the footer's suggestion') but no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, and pagination is hinted at. However, two of four parameters (library_id, library_type) are never explained anywhere, and the description references a 'footer' that is only meaningful via the output schema, leaving the scoping behavior underspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it documents only limit and start (with defaults and the max-100 cap anguage). The two library-scoping parameters, library_id and library_type, are undocumented in both schema and description, leaving a real gap for a tool that spans user and group libraries.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List items in Zotero's trash') and ties it to a concrete downstream consumer, 'restore_item', which helps separate it from siblings like delete_item or trash_item. It is clear but the differentiation is a use-case hint rather than an explicit contrast with alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'e.g. to find a key for restore_item' gives a clear when-to-use scenario and links this tool into the restore workflow. There is no explicit when-not guidance, but the context for invoking it is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_collectionMove CollectionC

Move a collection under another collection, or to the library root.

ParametersJSON Schema
NameRequiredDescriptionDefault
library_idNo
library_typeNo
collection_idYes
parent_collection_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the agent knows this mutates state without destroying data. The description adds only the root-move option; it does not disclose what happens if the target parent is a descendant of the moved collection, whether the move is reversible, or required permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with zero filler. It is appropriately sized, though it is arguably too terse given the undocumented parameters rather than padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, but for a 4-parameter mutation with 0% schema coverage and no annotation detail about side effects, the description omits parameter mapping and edge-case behavior. It is not sufficient on its own for an agent to call this tool confidently in non-trivial cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 4 parameters, so the description carries the full burden. It implicitly signals that the destination is controlled (move "under another collection, or to the library root"), but never mentions collection_id, parent_collection_id, library_id, or library_type by name, leaving half the parameters entirely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource ("Move a collection") and states both destination modes: under another collection or to the library root. It does not compare itself to siblings like rename_collection, add_to_collection, or delete_collection, but the action is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit statement of when to use this tool versus alternatives such as add_to_collection or create_collection, and no prerequisites or permission notes. The only implicit guidance is that a root-level move is a valid target, derived from "or to the library root".

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_from_collectionRemove From CollectionA

Remove an item from a collection without deleting it from the library.

Args: item_key: The Zotero item key collection_id: The collection key to remove it from

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo
collection_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare write (readOnlyHint=false), non-destructive (destructiveHint=false), and closed-world. The description adds real behavioral value beyond that: it explains exactly what 'remove' means — detachment from the collection only, not deletion from the library — which resolves the ambiguity the annotation alone leaves open. It stops short of error/idempotency behavior, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The behavioral scoping sentence is front-loaded and the argument block is tight. The 'Args:' list is slightly awkward formatting, but there is no wasted prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, and annotations cover the safety profile. But for a 4-parameter mutation tool, two parameters (library_id, library_type) are entirely undocumented, leaving a real gap an agent would need to resolve.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries full burden, yet it documents only item_key and collection_id (the two required params). The optional library_id and library_type parameters are undocumented in both schema and description, leaving the library-resolution semantics — critical for a tool that must locate an item — unspecified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (remove) and resource (item from a collection) and immediately scopes it: 'without deleting it from the library.' This distinguishes it from delete_item, delete_collection, and trash_item in the sibling list, so an agent can pick the right tool without comparing schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the clarification that the item stays in the library, which implicitly frames when this is preferable to delete_item. However, it never names add_to_collection as the inverse or states prerequisites (e.g., does the item need to be in the collection first?). Guidance is inferable but not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_tagsRemove TagsC

Remove one or more tags from a Zotero item.

Args: item_key: The Zotero item key tags: List of tags to remove

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsYes
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, openWorldHint=false, so the safety profile is known. The description adds nothing beyond that: it does not say whether tags are deleted library-wide or just detached from the item, whether the operation is idempotent, or what happens on a missing tag — the most important ambiguity given the nearby 'delete_tags' sibling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One-line purpose followed by a short Args block — front-loaded and free of padding. However, the Args block adds almost no information, so part of its length is not earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with four parameters (two undocumented anywhere) and a sibling that performs a similar-sounding operation, the description is too thin. The output schema covers return values, so that is not a gap, but the library-scoping parameters and the item-vs-global semantics are.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it only restates the two required parameters ('item_key', 'tags') in near-identical wording to their titles. The optional 'library_id' and 'library_type' parameters are undocumented in both schema and description, leaving half the parameters unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Remove one or more tags from a Zotero item.' An agent can tell it is a tag-detachment operation, but the description does not distinguish it from the sibling tools 'delete_tags' or 'add_tags' (e.g., whether this deletes tags globally or only detaches them from one item).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this instead of 'delete_tags' (global tag deletion) or 'add_tags'. There are no prerequisites, no mention of what happens if a tag is not present on the item, and no exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_collectionRename CollectionB

Rename a Zotero collection without changing its parent.

ParametersJSON Schema
NameRequiredDescriptionDefault
new_nameYes
library_idNo
library_typeNo
collection_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description usefully adds that the parent relationship is preserved, but says nothing about auth requirements, reversibility, or name-uniqueness constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler, though trailing whitespace and the total absence of supporting detail make it leaner than ideal for a mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover the safety profile. However, with 0% schema coverage on 4 parameters, the description leaves the library_id/library_type scoping behavior entirely unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 4 parameters, so the description must compensate and does not. It says nothing about collection_id, new_name, or the optional library_id/library_type scoping parameters, leaving half the signature undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (rename) and resource (Zotero collection), plus a scope constraint ('without changing its parent') that implicitly distinguishes it from move_collection. It stops short of naming the sibling, but the operation is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'without changing its parent' clause implies the rename-vs-move boundary, but the description never states when to prefer this over move_collection or names any prerequisite. Usage must be inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_tagRename TagB

Rename a tag across all items in the Zotero library.

Args: old_name: The current tag name new_name: The new tag name to replace it with

ParametersJSON Schema
NameRequiredDescriptionDefault
new_nameYes
old_nameYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false. The description usefully adds that the rename is applied library-wide (a mass mutation), but it discloses nothing about permissions, reversibility, or what happens to items carrying the old tag. There is also mild tension between a library-wide rename and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line summary is front-loaded and short, but the 'Args:' block is boilerplate that merely echoes the schema property titles rather than adding meaning, so part of the text does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter bulk-mutation tool with 0% schema coverage and no annotation guidance on side effects, the description is thin: it omits the library-targeting parameters and any consequences of a library-wide rename. An output schema exists, so return values correctly need not be explained, but the input-side gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, yet it only restates the schema titles for old_name and new_name ('The current tag name' / 'The new tag name'). The library_id and library_type parameters are undocumented in both the schema and the description, leaving ambiguity about which library is targeted despite the phrase 'the Zotero library'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Rename') and resource ('tag') plus scope ('across all items in the Zotero library'), which distinguishes it from rename_collection and the add/remove/delete tag siblings. It stops short of explicitly naming any sibling it should be preferred over.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'across all items in the Zotero library' hints at bulk scope, but there is no statement of when to use this versus delete_tags/add_tags or any prerequisite such as needing the tag to already exist. An agent must infer the context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

restore_itemRestore ItemC

Restore an item from Zotero's trash.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a non-read-only (readOnlyHint false), non-destructive (destructiveHint false), closed-world write, so the safety profile is covered. The description adds the useful precondition that the item comes from the trash, but says nothing about where the item is restored to (original collection vs. unfiled), whether it needs library scoping, or what triggers failure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. It is efficient, though the brevity reflects under-specification rather than tight editing of richer content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter mutation tool with 0% schema coverage, the description leaves the library-scoping parameters entirely unexplained and never states restore behavior. The existing output schema and annotations relieve it of explaining return values and safety, but the operational gap is still significant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across three parameters, so the description carries full responsibility and mentions none of them. It says nothing about what item_key is, or how the optional library_id/library_type should be supplied to target a user vs. group library.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (restore) and a specific resource (an item from Zotero's trash), which is enough to distinguish it from siblings like trash_item, delete_item, or list_trash. It is clear but never explicitly names or contrasts with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance, no mention of the complementary trash_item operation, and no conditions or prerequisites for invocation beyond the implicit 'item must be trashed'. Usage must be inferred entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_bibtexSave BibtexB
Destructive

Export BibTeX or BibLaTeX and atomically write it to a local file.

Path writes are available by default over local stdio. HTTP deployments must explicitly allow a confined file root.

ParametersJSON Schema
NameRequiredDescriptionDefault
biblatexNo
item_keysNo
save_pathYes
library_idNo
library_typeNo
collection_idNo
include_abstractNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely new context — the write is atomic, and path writes are gated by deployment mode (stdio default, HTTP requires a confined file root). It does not detail overwrite behavior or path permissions further, so it is a solid but not complete addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and followed by the deployment constraint. No filler, and the most important information comes first. It could be marginally tighter but wastes nothing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The presence of an output schema relieves the description of explaining return values, and it covers purpose and runtime gating well. However, given 7 parameters at 0% schema coverage — including library/collection/item scoping — the definition is not complete enough to call it correctly without inspecting the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 7 parameters, so the description carries the full explanatory burden. It only loosely implies save_path ('a local file') and the biblatex flag ('BibTeX or BibLaTeX'), while item_keys, library_id, library_type, collection_id, and include_abstract are never mentioned. With zero structured coverage, this leaves most parameters undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource+destination: 'Export BibTeX or BibLaTeX and atomically write it to a local file.' An agent can distinguish this write-to-disk operation from a content-returning sibling like get_bibtex. It stops short of explicitly naming that sibling or its alternatives, which keeps it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It supplies environment-level guidance ('available by default over local stdio'; HTTP deployments 'must explicitly allow a confined file root'), which tells the agent when the tool will actually function. It never addresses when to choose this over get_bibtex or other siblings, so the core when-vs-alternatives question is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_pdfSave PdfC
Destructive

Save a Zotero PDF to an authorized local server path.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
save_pathYes
library_idNo
library_typeNo
attachment_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, and the description adds the useful scoping detail that the target is an 'authorized' server path. However it never explains the destructive aspect (e.g. whether an existing file is overwritten) nor the authorization requirement, so it adds only modest context 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.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence with no padding, but it is thin rather than economical — the trailing whitespace and missing detail suggest under-specification, not deliberate brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be described, but for a 5-parameter destructive write tool with 0% schema coverage, no usage guidance, and no explanation of library/attachment selection, the description is not complete enough to invoke confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It only loosely implies that item_key is the PDF item and that save_path is the local target, while library_id, library_type, and attachment_key are left entirely undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (save) and resource (a Zotero PDF) plus the destination (an authorized local server path). It is clear what the tool does, but it does not distinguish itself from the sibling download_pdf, leaving real ambiguity about which tool an agent should pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no named alternative despite download_pdf and attach_file being obvious contenders. The phrase 'authorized local server path' hints at a precondition but never states it as a rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_fulltextSearch FulltextC
Read-onlyIdempotent

Search Zotero metadata and indexed full text using qmode=everything.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, covering the safety profile. The description adds that it searches indexed full text (implying a full-text index distinct from metadata search), which is real behavioral context, but it says nothing about matching semantics or scoping by library.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The sentence is short and front-loaded with the core purpose, so it is not bloated. But the trailing 'using qmode=everything' phrase is dead weight that references a non-existent parameter and consumes the only slot where real parameter or usage guidance could have gone.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, but for a 4-parameter search tool the description is incomplete: no parameter documentation and no guidance on scoping by library or paging via limit. An agent would have to guess how library_id/library_type interact with the query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description documents none of the four parameters (query, limit, library_id, library_type). Worse, it references 'qmode=everything', which is not a parameter in the schema, potentially prompting the agent to pass a phantom argument while library_id/library_type filtering goes unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it searches Zotero metadata and indexed full text, which is more precise than a generic 'search'. However, it does not distinguish itself from the sibling tools search_library and search, and the 'qmode=everything' clause is opaque to an agent without prior knowledge of the backend.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus search_library, search, or get_item_fulltext, all of which appear to be search/retrieval siblings. The only hint is 'indexed full text', which the agent must infer means full-text search rather than metadata search.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_librarySearch LibraryA
Read-onlyIdempotent

Search your Zotero library. Falls back to fuzzy matching if the exact search returns no results.

Args: query: Search query matched against titles, creators, and year (use search_fulltext for abstracts, notes, and PDF text) limit: Maximum number of results per page (default 10, max 100) start: Offset of the first result; pass the value suggested by the previous call's footer to fetch the next page (default 0)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
startNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds real behavior beyond that: an automatic fuzzy-match fallback when exact search yields nothing, plus the pagination contract (footer-supplied start value) and a hard cap of 100 results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose in one sentence, then the fallback behavior, then a compact args block where each entry earns its place. No filler or redundant restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and annotations cover safety. The remaining gap is the two undocumented library-scoping parameters, which matters given siblings like list_libraries and the group/user distinction an agent must resolve before searching.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it does well for three of five: query matching scope, limit default/max, and start pagination semantics. However, library_id and library_type are never mentioned, leaving the agent without guidance on how to scope a search to a group library.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search your Zotero library') and narrows scope by naming the fields matched: titles, creators, and year. It also distinguishes itself from search_fulltext with an explicit hand-off, though it does not clarify its relationship to the bare 'search' sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear routing rule: use search_fulltext for abstracts, notes, and PDF text, implying this tool is for title/creator/year lookup. It also explains the pagination workflow via the previous call's footer. No explicit 'when not to use' statement beyond the search_fulltext split.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_tag_colorSet Tag ColorB

Assign a color to a tag in the Zotero library. Colored tags appear in the tag selector and item lists.

Args: tag: The tag name to colorize color: Hex color code (e.g. '#FF0000' for red, '#3366CC' for blue) position: Sort position for the colored tag (0-8, lower = higher priority)

ParametersJSON Schema
NameRequiredDescriptionDefault
tagYes
colorYes
positionNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the mutation/safety profile is covered. The description adds only that colored tags surface in the tag selector and item lists; it does not say whether an existing color is overwritten, whether the tag must already exist, or what happens on invalid input.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by a tight Args block with no filler. The UI context sentence is mildly expendable but does not bloat the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. However, for a 5-parameter mutation tool, the absence of any guidance on library_id/library_type scoping and on overwrite/error behavior leaves meaningful gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description is the only source of parameter meaning. It documents tag, color (with hex examples), and position (with range 0-8 and direction), but leaves library_id and library_type completely unexplained 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.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Assign a color to a tag in the Zotero library,' which is unambiguous and distinguishable from generic tag tools. It does not, however, name its obvious counterpart unset_tag_color, so sibling differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what colored tags look like in the UI but never states when to use this tool versus unset_tag_color, rename_tag, or add_tags. No prerequisites or conditions are given, leaving usage entirely implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

trash_itemTrash ItemB

Move an item to Zotero's trash so it can be restored later.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, and the description's 'can be restored later' essentially restates that non-destructive guarantee in prose rather than adding new information. It says nothing about permissions, where trashed items surface, or what happens to the item's collection memberships.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, front-loaded sentence with no filler; the recoverability constraint is stated immediately after the action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the core action plus recoverability is conveyed. However, for a 3-parameter mutation tool with no annotation-independent guidance on library scoping or sibling routing, the description is only minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 3 parameters, and the description mentions no parameters at all. It implies a single item is targeted, but the optional library_id/library_type scoping — which matters for Zotero user vs group libraries — is left entirely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Move an item to Zotero's trash'), which is clearly distinguishable from delete_item by the recoverability framing. It does not explicitly name the sibling it differs from (delete_item) or its lifecycle partners (restore_item, list_trash), so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'So it can be restored later' implies the use case (soft removal vs permanent deletion) but never states when to prefer this over delete_item or how it relates to restore_item/list_trash. Usage is inferable rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unset_tag_colorUnset Tag ColorA

Remove a tag's assigned library color without deleting the tag.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this is a non-read-only but non-destructive mutation, and the description usefully adds that the tag itself is not deleted. It still omits permission requirements, idempotency, and what happens if the tag has no color, so behavioral context remains moderate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single front-loaded sentence with no wasted wording. The core action and the key distinction from deletion are stated immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and annotations cover the safety profile. However, with zero schema descriptions, the description is not complete enough to clarify how `library_id` and `library_type` should be used when unsetting a tag color.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain the required `tag` parameter or the optional `library_id` and `library_type` parameters. It implies a tag and a library color but leaves the library-scoping parameters undocumented for invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: remove a tag's assigned library color. It also explicitly distinguishes the operation from tag deletion, so an agent can separate it from delete_tags and infer the counterpart to set_tag_color.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase "without deleting the tag" implies when to use it rather than a broader tag deletion operation. However, it does not explicitly compare it with set_tag_color or state prerequisites, so usage guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_annotationUpdate AnnotationC

Update the comment and/or highlight color of an annotation.

ParametersJSON Schema
NameRequiredDescriptionDefault
colorNo
commentNo
library_idNo
library_typeNo
annotation_keyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the mutation/safety profile is covered by structured data. The description adds that only comment and color are modifiable (implying the annotation text/anchor is immutable), but says nothing about failure when the key is missing or whether an empty/null value clears a field.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the intent is immediately clear. It is arguably too terse given the undocumented parameters, but there is no wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 5 parameters, 0% schema coverage, and only 1 required parameter, the description documents just 2 of the 5 inputs. An output schema exists so return values need no explanation, but the caller still lacks enough information to know how to uniquely target an annotation (annotation_key plus which library fields).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 5 parameters, so the description must compensate and does not. It names only comment and color, leaving the required annotation_key unexplained and giving no insight into library_id/library_type, which appear to scope the lookup.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Update ... an annotation') plus the exact mutable fields (comment and highlight color), which distinguishes it from create_annotation, delete_annotation, and get_annotations. It never names those siblings, so differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of prerequisites or permissions, and no reference to alternative tools such as create_annotation (to add) or delete_annotation (to remove). The agent must infer the use case entirely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_item_metadataUpdate Item MetadataB

Update selected bibliographic fields and optionally replace creators.

Immutable/internal fields such as item type, key, version, parent item, collections, tags, and deletion state cannot be changed through this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
updatesYes
creatorsNo
item_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=false), so the bar is lower. The description adds meaningful context beyond that: it enumerates exactly which immutable/internal fields (item type, key, version, parent item, collections, tags, deletion state) cannot be touched, and notes creators are optionally replaced. This is genuinely useful boundary disclosure for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, purpose front-loaded, no filler. The second sentence's exclusion list is dense but each item earns its place by preventing invalid calls. Minor room to trim, but efficient overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and annotations cover safety. But for a 5-parameter mutation tool with 0% schema description coverage, the missing parameter guidance leaves the definition only partially complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 0% and 5 parameters including nested objects (updates, creators), the description compensates poorly. It only alludes to 'creators' being optional and to 'fields', but never explains the item_key/updates structure, the library_id/library_type scoping params, or the expected creator shape. The schema does not fill this gap on its own.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Update selected bibliographic fields and optionally replace creators.' It also draws a clear boundary by listing immutable fields. However, it never names or distinguishes itself from sibling mutation tools like update_note, update_annotation, or add_item_from_metadata, so the agent must infer which update tool applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance or reference to alternatives; the agent is told what cannot be changed but not when this tool is the right choice versus add_item_from_metadata or update_note. The immutable-field list is scope information rather than usage routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_noteUpdate NoteC

Replace the content of an existing Zotero note.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteYes
note_keyYes
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the safety profile is largely covered. The description adds one genuinely useful behavioral fact — that the operation wholesale replaces content rather than appending or patching — but says nothing about note format (HTML vs plain text), library scoping, or what happens to prior content.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the key verb first and no filler; the trailing whitespace is the only noise. It is efficient, though its brevity is achieved more by omission than by editorial discipline.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be described, but for a mutation tool with 4 undocumented parameters the description omits too much: no note format expectations, no library disambiguation, no confirmation of whether the original content is recoverable. The agent cannot safely call this without guessing at the library scoping parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 4 parameters, so the description carries the full burden and fails to meet it. 'Content' loosely maps to the 'note' param and 'existing note' gestures at 'note_key', but library_id and library_type — which determine which library the note lives in — receive no explanation anywhere.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Replace') and resource ('content of an existing Zotero note'), making the operation unambiguous. It implicitly contrasts with add_note/delete_note/list_notes via 'existing' and 'replace', but never names a sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this versus add_note (for new notes), delete_note, or update_annotation. The only implied guidance is that the note must already exist, and even that is not framed as a precondition or paired with an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_itemsVerify ItemsA
Read-onlyIdempotent

Verify that recently added items have valid DOIs that match CrossRef metadata.

Re-resolves each item's DOI via CrossRef and compares the title. Reports items that have no DOI, DOIs that don't resolve, or title mismatches.

Args: limit: Number of recent items to check (default 10)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
library_idNo
library_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and openWorld, so safety is covered. The description adds real behavioral detail beyond that: it discloses an external CrossRef resolution step and enumerates the three reported failure classes (missing DOI, unresolved DOI, title mismatch). It stops short of stating rate-limit or network-failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, followed by a compact explanation of what gets reported. The Args block repeats the schema's default rather than adding information, a minor inefficiency, but overall tight and well-ordered.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return shape need not be explained, and the description does describe the report categories well. However, for a 3-parameter tool with 0% schema coverage, the absence of any library scoping explanation leaves a real gap for an agent deciding how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 3 parameters. The description only restates the limit parameter (which the schema already types with a default of 10) and says nothing about library_id or library_type, which would otherwise be undocumented and unclear in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (verify) and resource (recently added items) with the precise mechanism: re-resolving each item's DOI via CrossRef and comparing titles. This is clearly distinct from sibling tools such as find_duplicates or get_recent_items.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (checking recently added items for DOI validity) and documents the default limit, but gives no explicit when-to-use/when-not guidance or alternatives (e.g., vs find_duplicates or health_check). The scope 'recently added' is the only selector hint.

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.

  1. 1 tool updatev0.10.2
    • Addedlist_trash
  2. 50 tool updatesv0.10.0
    • Changedadd_book_by_isbn2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_item_from_metadata2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_note2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_paper_by_arxiv_id2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_paper_by_doi2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_papers_by_dois2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_tags2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedadd_to_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedattach_file2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedcreate_annotation2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedcreate_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddelete_annotation2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddelete_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddelete_item2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddelete_note2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddelete_tags2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changeddownload_pdf2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedfetch2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedfind_duplicates2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_annotations2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_bibtex2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_collection_items2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_item_details2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_item_fulltext2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_recent_items2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedget_unfiled_items2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedhealth_check2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedlist_attachments2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedlist_collections2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Addedlist_libraries
    • Changedlist_notes2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedlist_tags2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedmove_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedremove_from_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedremove_tags2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedrename_collection2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedrename_tag2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedrestore_item2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedsave_bibtex2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedsave_pdf2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedsearch2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedsearch_fulltext2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedsearch_library2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedset_tag_color2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedtrash_item2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedunset_tag_color2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedupdate_annotation2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedupdate_item_metadata2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedupdate_note2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
    • Changedverify_items2 fields changed
      • addedInput schema / properties / library_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Id"
        +}
      • addedInput schema / properties / library_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "user",
        +        "group"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Library Type"
        +}
  3. 49 tool updatesv0.9.0
    • First observedadd_book_by_isbn
    • First observedadd_item_from_metadata
    • First observedadd_note
    • First observedadd_paper_by_arxiv_id
    • First observedadd_paper_by_doi
    • First observedadd_papers_by_dois
    • First observedadd_tags
    • First observedadd_to_collection
    • First observedattach_file
    • First observedcreate_annotation
    • First observedcreate_collection
    • First observeddelete_annotation
    • First observeddelete_collection
    • First observeddelete_item
    • First observeddelete_note
    • First observeddelete_tags
    • First observeddownload_pdf
    • First observedfetch
    • First observedfind_duplicates
    • First observedget_annotations
    • First observedget_bibtex
    • First observedget_collection_items
    • First observedget_item_details
    • First observedget_item_fulltext
    • First observedget_recent_items
    • First observedget_unfiled_items
    • First observedhealth_check
    • First observedlist_attachments
    • First observedlist_collections
    • First observedlist_notes
    • First observedlist_tags
    • First observedmove_collection
    • First observedremove_from_collection
    • First observedremove_tags
    • First observedrename_collection
    • First observedrename_tag
    • First observedrestore_item
    • First observedsave_bibtex
    • First observedsave_pdf
    • First observedsearch
    • First observedsearch_fulltext
    • First observedsearch_library
    • First observedset_tag_color
    • First observedtrash_item
    • First observedunset_tag_color
    • First observedupdate_annotation
    • First observedupdate_item_metadata
    • First observedupdate_note
    • First observedverify_items

TDQS

C2.9/5.0

Scored across 51 tools

Disambiguation3/5

Most tools target distinct Zotero resources and actions, but search_library, search_fulltext, and search overlap heavily, and fetch duplicates get_item_details. An agent could struggle to choose the right search or retrieval tool without trial and error.

Naming Consistency4/5

Predominantly snake_case verb_noun (add_paper_by_doi, list_collections, delete_item). Minor deviations like health_check and bare verbs search/fetch are readable but slightly inconsistent.

Tool Count1/5

51 tools is far beyond the 25+ threshold and qualifies as an extreme mismatch for a single MCP server. While the domain is broad, many tools could be consolidated, such as search variants, batch/single adds, and attachment operations.

Completeness4/5

The surface covers items, collections, tags, notes, annotations, imports/exports, trash, search, and libraries very thoroughly. Minor gaps remain, such as explicit attachment deletion/update and batch item operations.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A lightweight MCP server that connects AI agents to a local Zotero library for paper management and metadata retrieval. It enables users to search titles and abstracts, browse collections, and automatically ingest papers via arXiv ID or DOI with PDF attachments.
    8
    25 PyPI
    17
    MIT