Skip to main content
Glama

Trash or restore Zotero items

zotero_trash_items

Move Zotero items to trash or restore them without permanent deletion. Recover trashed items anytime in the Zotero app. Use reversible trash instead of irreversible delete.

Instructions

Move items to the trash (the safe, REVERSIBLE default) or restore them. This sets the deleted flag (1=trash, 0=restore) — it is NOT a permanent delete, so trashed items can be recovered here or in the Zotero app. Use this instead of zotero_delete_items unless you truly need irreversible removal. Provide item_keys and optional action (default "trash"). Writes go to the running Zotero desktop app for your personal library (via its local-API writes where available), otherwise to the cloud Web API. When the server sets a bulk-write threshold (ZOTEUS_CONFIRM_BULK_WRITES, off by default), trashing more items than that in one call also needs confirm: true.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionNoDefault "trash".
confirmNoRequired to trash more items in one call than the server's bulk-write threshold.
item_keysYesItem keys to trash or restore.
library_idNoNumeric id of the library to address, e.g. 5234875 for a group (zotero_groups lists the ids you can reach). Omit to use the configured default library; an id given without library_type is read as a group id.
library_typeNoWhich library to address: "user" (a personal library) or "group" (a shared group library). Omit to use the library this server is configured for. "group" on its own is refused: pass library_id with it.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
failedNoOne entry per object the write could not land; absent or empty when all of them did.
targetNoWhere the write went: "local" (Zotero desktop local API), "desktop" (connector protocol) or "cloud" (Zotero Web API).
updatedYesKeys of the items trashed or restored.
libraryVersionNoThe library's Last-Modified-Version after this write.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.21.0
    • addedInput schema / properties / library_id / exclusiveMinimum
      Added value: +0
  2. Changed2 schema fields changedv1.20.2
    • removedInput schema / $schema
      Removed value: -"http://json-schema.org/draft-07/schema#"
    • removedOutput schema / $schema
      Removed value: -"http://json-schema.org/draft-07/schema#"
  3. Changed3 schema fields changedv1.20.0
    • addedInput schema / properties / library_id / description
      Added value: +"Numeric id of the library to address, e.g. 5234875 for a group (zotero_groups lists the ids you can reach). Omit to use the configured default library; an id given without library_type is read as a group id."
    • addedInput schema / properties / library_type / description
      Added value: +"Which library to address: \"user\" (a personal library) or \"group\" (a shared group library). Omit to use the library this server is configured for. \"group\" on its own is refused: pass library_id with it."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": true,
      +  "properties": {
      +    "failed": {
      +      "description": "One entry per object the write could not land; absent or empty when all of them did.",
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "code": {
      +            "description": "Zotero status for this object, e.g. 400 or 412.",
      +            "type": "number"
      +          },
      +          "index": {
      +            "description": "Position of the failed object in the request.",
      +            "type": "number"
      +          },
      +          "key": {
      +            "description": "Item key, when the failed object named one.",
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "Why Zotero refused it.",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "libraryVersion": {
      +      "description": "The library's Last-Modified-Version after this write.",
      +      "type": "number"
      +    },
      +    "target": {
      +      "description": "Where the write went: \"local\" (Zotero desktop local API), \"desktop\" (connector protocol) or \"cloud\" (Zotero Web API).",
      +      "type": "string"
      +    },
      +    "updated": {
      +      "description": "Keys of the items trashed or restored.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "updated"
      +  ],
      +  "type": "object"
      +}
  4. Changed1 schema field changedv1.17.0
    • addedInput schema / properties / confirm
      Added value: +{
      +  "description": "Required to trash more items in one call than the server's bulk-write threshold.",
      +  "type": "boolean"
      +}
  5. First observedv1.0.4

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false and destructiveHint=false, so the description's job is to add nuance. It does: it clarifies that trashing is reversible, that it sets a `deleted` flag rather than permanently deleting, and that writes go to the running Zotero desktop app or the cloud Web API. It also discloses the bulk-write threshold behavior. The only minor gap is that it doesn't describe the response shape, but the output schema exists and covers that.

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 dense but well-organized: it front-loads the core behavior and reversibility, then the sibling distinction, then parameters, then write-path details. Every sentence adds information. It is slightly long, but given the complexity of the tool (dual action, two write paths, bulk-write threshold), the length is justified.

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?

For a tool with 5 parameters, an output schema, and annotations, the description covers the essential decision points: what the tool does, when to use it vs the delete sibling, how the action parameter works, when confirm is needed, and which library is addressed. The only thing an agent might want is a note about the response format, but the output schema handles that. This is a complete, well-rounded definition.

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 100%, so the baseline is 3. The description adds value by explaining the default action ('trash'), the meaning of the `deleted` flag, and the condition under which `confirm` is needed. It also clarifies the library_id/library_type relationship ('an id given without library_type is read as a group id'), which is not fully explicit in the schema. This pushes it above baseline.

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 ('Move items to the trash' / 'restore them'), the resource (Zotero items), and the mechanism (sets the `deleted` flag). It explicitly distinguishes itself from zotero_delete_items, which is the key sibling it could be confused with. The title also reinforces the dual action.

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?

The description explicitly says 'Use this instead of zotero_delete_items unless you truly need irreversible removal,' naming the alternative and the condition for choosing it. It also explains the default action, the optional confirm flag, and the write path (local-API vs cloud Web API), giving clear context for when to call this tool.

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