Skip to main content
Glama

Update a Zotero item

zotero_update_item
DestructiveIdempotent

Partially update a Zotero item by supplying only the fields to change (PATCH), preserving others. Handles concurrency automatically; use dry_run to preview the before-after diff.

Instructions

Partially update one item (HTTP PATCH — only the fields you supply change; omitted fields are preserved). Provide item_key and a patch object of the fields to change (e.g. {"title":"New","extra":"note"} or {"tags":[{"tag":"reviewed"}]}). All field values are plain JSON strings/numbers/booleans/arrays — never wrapped in nested objects (e.g. "title": "New", NOT "title": {"title": "New"}). Optimistic concurrency is handled for you: if you pass the item's version it is used; otherwise the current version is fetched first. If the item changed on the server in the meantime (412), the update is automatically re-fetched and retried once. Writes go to the cloud Web API. Set dry_run:true to preview the field-level before→after diff without writing (arrays like tags/collections are replaced wholesale by PATCH, not merged; a dry_run call performs no write).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patchYesObject of fields to change (PATCH semantics), e.g. {"title": "New title", "date": "2024-02-01", "tags": [{"tag": "reviewed"}], "collections": ["ABCD1234"]}. Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings. Values are plain, never wrapped in nested objects.
dry_runNoPreview the field-level before→after diff without writing.
versionNoKnown current version; fetched automatically if omitted.
item_keyYesThe 8-character item key.
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
diffNoField-level before/after for a dry run; only fields the patch would actually change.
dryRunNoTrue when nothing was written.
retriedNoTrue when a version conflict (412) was re-fetched and retried once.
versionNoCurrent version on the server (dry run only).
item_keyYesThe item this call addressed.
newVersionNoVersion after the PATCH; absent on a dry run.
arrayReplacementsNoFields in that diff that PATCH replaces wholesale rather than merging, e.g. ["tags"].

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": {
      +    "arrayReplacements": {
      +      "description": "Fields in that diff that PATCH replaces wholesale rather than merging, e.g. [\"tags\"].",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "diff": {
      +      "additionalProperties": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "after": {
      +            "description": "Value the patch would set."
      +          },
      +          "before": {
      +            "description": "Value the item carries now."
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "description": "Field-level before/after for a dry run; only fields the patch would actually change.",
      +      "type": "object"
      +    },
      +    "dryRun": {
      +      "description": "True when nothing was written.",
      +      "type": "boolean"
      +    },
      +    "item_key": {
      +      "description": "The item this call addressed.",
      +      "type": "string"
      +    },
      +    "newVersion": {
      +      "description": "Version after the PATCH; absent on a dry run.",
      +      "type": "number"
      +    },
      +    "retried": {
      +      "description": "True when a version conflict (412) was re-fetched and retried once.",
      +      "type": "boolean"
      +    },
      +    "version": {
      +      "description": "Current version on the server (dry run only).",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "item_key"
      +  ],
      +  "type": "object"
      +}
  4. Changed2 schema fields changedv1.3.1
    • changedInput schema / properties / patch / description
      Previous value: -"Object of fields to change (PATCH semantics). Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings."New value: +"Object of fields to change (PATCH semantics), e.g. {\"title\": \"New title\", \"date\": \"2024-02-01\", \"tags\": [{\"tag\": \"reviewed\"}], \"collections\": [\"ABCD1234\"]}. Structured fields (creators, tags, collections, relations) must be real JSON arrays/objects, not JSON-encoded strings. Values are plain, never wrapped in nested objects."
    • addedInput schema / properties / patch / properties / itemType
      Added value: +{
      +  "description": "The Zotero item type as a plain string, e.g. \"journalArticle\", \"book\", \"preprint\", \"report\", \"thesis\".",
      +  "type": "string"
      +}
  5. First observedv1.0.4

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and readOnlyHint=false, and the description adds substantial behavior beyond that: optimistic concurrency handling with automatic version fetch and retry on 412, dry_run mode for no-write preview, wholesale array replacement via PATCH, and that writes go to the cloud Web API. This is rich behavioral disclosure.

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 long but every sentence carries weight. It front-loads the core PATCH semantics and then layers concurrency, dry_run, and array-replacement details. It is appropriately dense for a complex mutation tool, though a slight trim of redundant phrasing (e.g., the dry_run explanation) could make it tighter.

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

Completeness5/5

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

Given the tool's complexity (nested objects, concurrency, dry_run, library addressing) and the presence of an output schema, the description covers all operational aspects an agent needs: patch semantics, concurrency handling, retry logic, array replacement behavior, dry_run behavior, and library type/id rules. Nothing critical is missing.

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 coverage is 100% with descriptions for every parameter, giving a baseline of 3. The description adds real value: concrete patch examples, a warning against wrapping values in nested objects, clarification that structured fields must be real JSON (not encoded strings), and the version-handling behavior. This exceeds the 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 clearly states a specific verb ('update') and resource ('one item'), and immediately clarifies the PATCH semantics (partial update, omitted fields preserved). This distinguishes it from create/delete operations and leaves no ambiguity about what the tool does.

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

Usage Guidelines4/5

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

It clearly implies when to use (updating an existing item with partial field changes) but does not explicitly name alternatives like zotero_create_items or zotero_delete_items. The PATCH semantics and examples make usage context clear, though explicit exclusion of alternatives would push it to 5.

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