Skip to main content
Glama

Create or update Zotero items

zotero_create_items
Destructive

Create new items or update existing ones in a single batch (the server auto-chunks into groups of 50). items is an ARRAY of item-data objects; each object has itemType as a plain string (e.g.

Instructions

Create new items or update existing ones in a single batch (the server auto-chunks into groups of 50). items is an ARRAY of item-data objects; each object has itemType as a plain string (e.g. "journalArticle", "book", "preprint", "report") plus its valid fields, creators (each {creatorType, firstName, lastName} or {creatorType, name}), tags ([{tag}]), and collections (array of 8-char collection keys). To UPDATE an existing item, also include its key and current version; to CREATE, omit both. Every item is validated against the Zotero schema before anything is sent — if any item is invalid, nothing is written and the problems are returned. Use zotero_schema to discover valid fields/creator types for an itemType. Writes to your personal library go to the running Zotero desktop app (Zotero 10+) when it is up, otherwise to the cloud Web API (requires ZOTERO_API_KEY). When updating, take version from a read made the same way (zotero_get_item), since the desktop and the cloud number versions independently. To write to a GROUP library, pass its numeric library_id (from zotero_groups) together with library_type:"group". library_type alone is not enough, and the key needs write access to that group. Collection keys are per-library, so take them from zotero_list_collections with the same library_id.

Example:

{"items": [{"itemType": "journalArticle", "title": "The Role of Metadata in Machine Learning", "creators": [{"creatorType": "author", "firstName": "Ada", "lastName": "Lovelace"}], "date": "2024-01-15", "DOI": "10.1234/example.5678", "tags": [{"tag": "ml"}], "collections": ["ABCD1234"]}]}

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "items": "<items>"
    },
    "name": "zotero_create_items"
  }
}

Input Schema

NameRequiredDescriptionDefault
itemsYesArray of Zotero item-data objects (itemType + fields; include key+version to update). Example: {"items":[{"itemType":"journalArticle","title":"The Role of Metadata in Machine Learning","creators":[{"creatorType":"author","firstName":"Ada","lastName":"Lovelace"}],"date":"2024-01-15","DOI":"10.1234/example.5678","tags":[{"tag":"ml"}],"collections":["ABCD1234"]}]}
library_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

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).
createdYesOne entry per item Zotero accepted, created or updated.
libraryVersionNoThe library's Last-Modified-Version after this write.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.23.0
    • addedOutput schema / properties / target
      Added value: +{
      +  "description": "Where the write went: \"local\" (Zotero desktop local API), \"desktop\" (connector protocol) or \"cloud\" (Zotero Web API).",
      +  "type": "string"
      +}
  2. Changed1 schema field changedv1.21.0
    • addedInput schema / properties / library_id / exclusiveMinimum
      Added value: +0
  3. 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#"
  4. 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": {
      +    "created": {
      +      "description": "One entry per item Zotero accepted, created or updated.",
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "key": {
      +            "description": "Key of the item written.",
      +            "type": "string"
      +          },
      +          "version": {
      +            "description": "Its version after the write.",
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "key"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "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"
      +    }
      +  },
      +  "required": [
      +    "created"
      +  ],
      +  "type": "object"
      +}
  5. Changed2 schema fields changedv1.3.1
    • changedInput schema / properties / items / description
      Previous value: -"Array of Zotero item-data objects (itemType + fields; include key+version to update)."New value: +"Array of Zotero item-data objects (itemType + fields; include key+version to update). Example: {\"items\":[{\"itemType\":\"journalArticle\",\"title\":\"The Role of Metadata in Machine Learning\",\"creators\":[{\"creatorType\":\"author\",\"firstName\":\"Ada\",\"lastName\":\"Lovelace\"}],\"date\":\"2024-01-15\",\"DOI\":\"10.1234/example.5678\",\"tags\":[{\"tag\":\"ml\"}],\"collections\":[\"ABCD1234\"]}]}"
    • addedInput schema / properties / items / items / properties / itemType
      Added value: +{
      +  "description": "The Zotero item type as a plain string, e.g. \"journalArticle\", \"book\", \"preprint\", \"report\", \"thesis\".",
      +  "type": "string"
      +}
  6. First observedv1.0.4

TDQS

A4.8/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: batch auto-chunking at 50, atomic all-or-nothing validation before anything is written, desktop-app-vs-cloud routing with the ZOTERO_API_KEY requirement, and the fact that desktop and cloud number versions independently. These are exactly the operational hazards an agent needs and none of them are in 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?

The most important operational facts (array shape, chunking, validation, update-vs-create) are front-loaded, and the example is embedded inline. It is dense rather than padded, though the length is close to the upper bound for a description that could lean more on the schema.

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?

For a complex, destructive batch-write tool, it covers validation semantics, auth paths, library scoping, version sourcing, and key provenance. An output schema exists, so return-value explanation is correctly omitted.

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%, so the baseline is 3, but the description adds real meaning: itemType must be a plain string, creator/tag/collection object shapes, the create-vs-update role of key+version, and that library_id + library_type must be paired for group writes. It overlaps the schema in places, keeping it from a 5.

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 (create/update), a precise resource (Zotero items), and the batch scope with server-side chunking. It contrasts with siblings by covering both creation and update in one call, which distinguishes it from zotero_update_item and zotero_import.

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?

Gives explicit branch conditions: include `key`+`version` to UPDATE, omit both to CREATE. It routes the agent to alternatives for sub-tasks — zotero_schema for valid fields, zotero_get_item for version reads, zotero_groups for library_id, zotero_list_collections for collection keys — and states the group-write requirement.

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