github 54yyyu/zotero-mcp v0.13.2

2 hours ago

Fixed

  • Duplicate detection agrees with itself (#496). Duplicate grouping, the auto-merge DOI-conflict guard, the pre-add existence check and the semantic index's preprint filter now take their keys from zotero_mcp.identifiers, so DOIs match in canonical form (10.1000/ABC, https://doi.org/10.1000/abc) and titles fold the way Zotero's own duplicate finder folds them. A DOI field holding a placeholder such as article no longer groups every item that carries it, and re-adding a paper whose stored DOI differs only in case no longer creates a second copy.
  • File uploads into a group library no longer go to your personal WebDAV (#591). Group libraries always store files in Zotero Storage, but with ZOTERO_WEBDAV_* configured and writes going through the Web API, zotero_add_item and zotero_attach_file sent the file only to WebDAV and left the group attachment without one. Other attach paths PUT a second copy to WebDAV, and if that failed they deleted the group attachment even though its file was already in Zotero Storage. The WebDAV steps now skip group libraries.
  • Automatic tags read as automatic in local mode (#620). Items read from zotero.sqlite listed every tag without its type, so zotero_get_item_metadata(format="json") and other reads showed automatic tags as manual, unlike the Zotero API. They now carry "type": 1.
  • Exported bibliographies are numbered 1..N (#619). zotero_export_bibliography numbered entries before dropping the ones that are empty once their HTML is stripped, so each dropped row used up a number and a 12-item collection came out as 4, 5, 7, 9, … Entries are now filtered first, then numbered.
  • PDFs with a scanner OCR text layer are no longer indexed metadata-only (#611). Files from Xerox or ABBYY scanners carry their text as an invisible layer over a page image, and pdf-inspector's markdown pass returned nothing for every page; Ghostscript and PDFCreator output could make it fail outright. Extraction now falls back to pdf-inspector's plain-text pass when the markdown pass yields no text or raises. That pass cannot be split by page, so the text is attributed to the first page and a max_pages cap is applied as the same share of the text; an explicit page subset (as in zotero_read_pdf_pages) is unchanged. Reported by @timmyfaraday.
  • Percent-encoded doi.org URLs are read as the DOI they name (#630). A DOI URL copied from a browser's address bar, such as https://doi.org/10.1002/%28SICI%291097-4636..., kept its %28/%3C escapes through normalize_doi, so the item was saved with the encoded string in its DOI field and duplicate detection and if_exists treated it as different from the same DOI written plainly. A URL with an encoded %2F was not recognised as a DOI at all. The URL path is now percent-decoded; a bare DOI is left as written.
  • Merging duplicates no longer trashes distinct linked-file attachments (#633). zotero_merge_duplicates skips a duplicate's attachment when the keeper "already has" it, but the check compared only content type, filename, md5 and URL. Linked-file PDFs carry none of the last three, so any linked PDF on a duplicate matched any linked PDF on the keeper, stayed behind, and went to the Trash with the duplicate. Attachments are now compared by link mode and path as well, and one with no md5, path or URL is never treated as a duplicate.
  • Automatic tags stay automatic when tags are edited or items merged (#618). add_tags/remove_tags on zotero_update_item and zotero_update_annotation, and the keeper's tags in zotero_merge_duplicates, were rebuilt from tag names alone, so automatic tags (e.g. MeSH headings from PubMed) became manual and "Delete Automatic Tags in This Library…" no longer reached them. Existing tags now keep their type, and tags copied from a duplicate keep the duplicate's. Reported by @rizakardas.
  • A read right after a write sees the write (#228). In local mode the database copy that reads use is refreshed at most every ZOTERO_MCP_DB_SNAPSHOT_MIN_INTERVAL seconds, and a write tool's own read just before writing usually used up that window, so zotero_get_item_metadata after zotero_set_item_collections, or zotero_get_annotations after zotero_create_annotation, still showed the old state. After zotero-mcp writes, the next read takes one fresh copy regardless of that interval, then the interval applies again.
  • Switching to the personal library by the id zotero_list_libraries shows now works (#603). In local mode the listing showed the personal library as libraryID=1, but zotero_switch_library only accepted 0 for library_type='user', so the list-then-switch workflow the tool descriptions recommend always failed. Local mode now accepts 0, user, or the personal library's listed libraryID (other ids are still rejected), and web mode maps user/0 to the configured ZOTERO_LIBRARY_ID unless ZOTERO_LIBRARY_TYPE is group. Reported by @mronkko.
  • A failed re-embed no longer deletes an item's passages (#610). New passages are now written before the stale tail is pruned, so an embedding error no longer leaves the item unsearchable. A run with items still failing after the end-of-run retry no longer advances the sync watermark, and a process that fails to take the update lock no longer truncates the holder's PID.
  • Changing an item's type keeps type-specific fields (#636). zotero_update_item(fields={"item_type": ...}) dropped every field the new type names differently, so turning a journal article into a conference paper lost its publicationTitle instead of moving it to proceedingsTitle, and the success report did not mention it. Values now carry over through their shared Zotero base field, as in the desktop client, and the success report lists what was carried over.

Don't miss a new zotero-mcp release

NewReleases is sending notifications on new releases.