merge_duplicates
Merge duplicate Zotero items by transferring metadata, tags, and collections to a keeper item while removing duplicates to clean your library.
Instructions
Merge duplicate Zotero items: transfer metadata, tags, collections to keeper, trash rest
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keep_key | Yes | ||
| remove_keys | Yes |
Implementation Reference
- src/zotero_mcp/server.py:186-190 (handler)Registration and handler definition for the 'merge_duplicates' MCP tool.
@mcp.tool(description="Merge duplicate Zotero items: transfer metadata, tags, collections to keeper, trash rest") def merge_duplicates(keep_key: str, remove_keys: list[str]) -> str: """Merge duplicates into one item. Fills empty fields from duplicates.""" result = _get_client().merge_duplicates(keep_key, remove_keys) return json.dumps(result, ensure_ascii=False) - src/zotero_mcp/client.py:312-353 (handler)Core logic implementation for merging duplicate Zotero items.
def merge_duplicates(self, keep_key: str, remove_keys: list[str]) -> dict: """Merge duplicates into keeper: transfer fields, tags, collections, trash rest.""" keeper = self.zot.item(keep_key) removed_titles = [] for rk in remove_keys: dup = self.zot.item(rk) dup_data = dup["data"] removed_titles.append(dup_data.get("title", rk)) # Fill empty fields from duplicate for field, value in dup_data.items(): if field in ("key", "version", "dateAdded", "dateModified"): continue keeper_val = keeper["data"].get(field) if not keeper_val and value: keeper["data"][field] = value # Merge tags existing_tags = {t["tag"] for t in keeper["data"].get("tags", [])} for t in dup_data.get("tags", []): if t["tag"] not in existing_tags: keeper["data"].setdefault("tags", []).append(t) existing_tags.add(t["tag"]) # Merge collections existing_cols = set(keeper["data"].get("collections", [])) for col in dup_data.get("collections", []): if col not in existing_cols: keeper["data"].setdefault("collections", []).append(col) existing_cols.add(col) # Trash the duplicate self.zot.trash_items([dup]) self.zot.update_item(keeper) return { "kept": keep_key, "removed": remove_keys, "removed_titles": removed_titles, "keeper_title": keeper["data"].get("title", ""), }