视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
zotero-skills【文档与办公】Full CRUD on a Zotero library: search, add, update, tag, trash/restore, delete, merge duplicates, and attach PDFs. Writes use pyzotero's Web API even though the separately configured zotero MCP server's tools are read only: call credentials_status() to check for a key (never open ~/.claude/.env or config.json yourself). Merges duplicates (no native m…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
| Task | Possible? | How (function) | Caveat |
|---|---|---|---|
| Read / search items | Yes | Local API via MCP tools, or dual.search() / dual.get_item() | Needs Zotero desktop running; falls back to Web API automatically |
| Write fields, tags, collections | Yes | dual.update_item(), dual.add_tags(), dual.add_to_collection() (Web API via pyzotero) | The mcp__zotero__* MCP tools are read only; that is not evidence writes are blocked |
| Trash (recoverable) vs delete (permanent) | Yes, both | dual.trash_item() sets deleted=1; dual.restore_item() sets deleted=0; dual.delete_item() is permanent | Default to trash; delete only after explicit confirmation since it does not go to trash |
| Merge duplicates | Yes | dual.merge_duplicates(keep_key, dup_key) | No native merge endpoint; covers the core of a desktop merge (move children, union collections/tags/relations, add a dc:replaces relation, trash the duplicate). Does not repoint other items' relations to the duplicate, reconcile dateAdded, or dedupe identical PDFs. Confirm with the user first, it trashes an item |
| Attach a PDF | Yes | dual.attach_pdf(parent_key, path) | Long Windows paths with spaces can make pyzotero's attachment_simple fail silently; this copies to a short, zot_-prefixed safe filename first and raises the failed-upload detail pyzotero returns (not a deeper server reason, pyzotero does not expose one) |
| Find a missing PDF | Guidance only, no helper | Check ~/Downloads, Zotero's storage folder, then, with the user's explicit OK, a browser MCP in their logged-in session | Stop at any CAPTCHA or login wall and ask the user; never guess a password or bypass a paywall |
| Where the API key lives | n/a | credentials_status() reports booleans + source (env / ~/.claude/.env / config.json), never the value | Never open ~/.claude/.env or config.json yourself to check; an empty shell env var is not proof no key exists |
Do not conclude a task is impossible without checking these first:
ZOTERO_API_KEY in the shell environment" does not mean writes are impossible. Call credentials_status() instead of opening a file: it resolves env var > ~/.claude/.env > config.json internally and reports booleans + source, never the value. The separately configured mcp__zotero__* MCP tools being read only is not evidence either, that server's own tools simply do not cover writes.dual.merge_duplicates() (or follow references/merge-duplicates.md by hand): move children, union collections/tags/relations, add a dc:replaces relation, then trash the duplicate. This reproduces the core of what Zotero desktop's own merge button does, though not everything it does (see the Merge duplicates row above for what is skipped).~/Downloads and Zotero's storage folder first, then, with the user's explicit OK, try a browser MCP in their logged-in session before asking them to fetch it. Stop and ask at any CAPTCHA or login wall.Dual-API CRUD for a Zotero library: search / read via the local desktop API, write via the Web API. Claude routes the request, picks local-API for reads and Web-API for writes, and verifies the result.
http://localhost:23119/api, header Zotero-Allowed-Request: true). Fast, no key needed, only available while Zotero desktop is running.https://api.zotero.org, header Zotero-API-Key: <key>) via pyzotero. Always.zotero MCP server's tools (mcp__zotero__*) are read only; that is not evidence writes are impossible. This plugin does not bundle that MCP server. zotero_create_note / zotero_batch_update_tags hit the local API and fail with 400/501. Use pyzotero from the shared client instead; it writes through the Web API using a key resolved from env vars, then ~/.claude/.env, then config.json.~/.claude/.env or config.json to check credentials, and the API key never appears in commits, notes, or vault files. Call credentials_status() (returns booleans + source, never the value). See references/api-setup.md.from zotero_client import get_client, ZoteroDualClient) instead of constructing API requests by hand. The shared client handles dual-API routing, rate-limit backoff, and credential loading.*, or a blank filter must never trigger an operation across the entire library.trash_item() (recoverable — sets deleted=1; reverse it with restore_item(), which sets deleted=0). delete_item() is PERMANENT and does NOT go to the trash (verified against the live API), so use it only on explicit confirmation and state clearly that it is irreversible.merge_duplicates() ends by trashing the duplicate item. Get explicit user confirmation (keep key + title, duplicate key + title) before calling it, exactly as for any other delete.Trigger phrases: "add paper to Zotero", "search Zotero", "update this collection", "tag these items", "find duplicates", "create a note on item X", "merge these duplicates", "attach the PDF", "find/download the PDF", "move to trash", "Zotero / 文獻 / 引用 / 參考文獻管理 / 合併重複 / 重複條目 / 附加 PDF / 下載論文 / 刪除條目 / 移到垃圾桶 / 改作者 / 修正書目".
NOT for: auditing the library for cleanup (use zotero-library-curator first to plan, then come back here for the apply step).
check_local_api() returns True/False; falls back to Web API automatically if not.zotero_search_items / zotero_get_collections MCP tools, or direct local-API GET. See references/read-operations.md.references/create-operations.mdreferences/update-operations.mdreferences/delete-operations.mdreferences/merge-duplicates.mdreferences/create-operations.md (attach caveat); a missing PDF has no helper, follow the "find a missing PDF" guidance row abovezot.item(key) and confirm the change matches intent.This skill is interactive — there is no machine-readable result file. After every write, surface to the user: the operation performed (CREATE / UPDATE / DELETE), the affected item key(s), and any reversible vs. irreversible aspect (e.g. trash vs. permanent).
pyzotero >= 1.5, MCP zotero server (any recent version).safe_api_call() handles 429 backoff automatically.references/api-setup.md — full API architecture, credentials, shared-client setupreferences/read-operations.md — search, get-by-key, list collections, fetch attachmentsreferences/create-operations.md — add items / child notes / attachments / batchreferences/update-operations.md — patch metadata, tags, collection membershipreferences/delete-operations.md — single + batch delete with safety patternsreferences/merge-duplicates.md: merge two duplicate items (no native API endpoint, done in steps)references/error-handling.md — common 4xx / 5xx + retry strategyreferences/endpoint-cheatsheet.md — flat URL / verb tablereferences/api-reference.md — raw HTTP request bodies, less-common collection-membership operationsreferences/item-types.md — JSON templates for journalArticle, book, conferencePaper, etc.scripts/zotero_client.py — the shared client referenced above. Import it for any Zotero operation.scripts/add_literature.py — batch import script template; use as a starting point when adding many items at once.