Zotero Skill
Interact with Zotero personal or group libraries via the REST API v3.
Setup
Requires two environment variables:
CODEBLOCK0
For group libraries, set ZOTERO_GROUP_ID instead of ZOTERO_USER_ID.
Optional env var for CrossRef/Unpaywall polite pool (improves DOI lookup success rate):
CODEBLOCK1
If credentials are missing, tell the user what's needed and link them to the key creation page.
CLI Script
All operations use scripts/zotero.py (Python 3, zero external dependencies).
CODEBLOCK2
Commands
| Command | Description | Example |
|---|
| INLINECODE3 | List top-level items | INLINECODE4 |
| INLINECODE5 |
Search by query |
zotero.py search "cognitive load" |
|
get | Full item details + attachments |
zotero.py get ITEMKEY |
|
collections | List all collections |
zotero.py collections |
|
tags | List all tags |
zotero.py tags |
|
children | List attachments/notes for item |
zotero.py children ITEMKEY |
|
add-doi | Add item by DOI (dedup enabled) |
zotero.py add-doi 10.1234/example |
|
add-isbn | Add item by ISBN (dedup enabled) |
zotero.py add-isbn 978-0-123456-78-9 |
|
add-pmid | Add item by PubMed ID |
zotero.py add-pmid 12345678 |
|
delete | Move items to trash (recoverable by default) |
zotero.py delete KEY1 KEY2 --yes |
|
update | Modify item metadata/tags |
zotero.py update KEY --add-tags "new" |
|
export | Export as BibTeX/RIS/CSL-JSON |
zotero.py export --format bibtex |
|
batch-add | Add multiple items from file |
zotero.py batch-add dois.txt --type doi |
|
check-pdfs | Report which items have/lack PDFs |
zotero.py check-pdfs |
|
crossref | Match citations vs library |
zotero.py crossref bibliography.txt |
|
find-dois | Find & add missing DOIs via CrossRef |
zotero.py find-dois --limit 10 |
|
fetch-pdfs | Fetch open-access PDFs for items |
zotero.py fetch-pdfs --dry-run |
Global Flags
- -
--json — JSON output instead of human-readable (works with items, search, get)
Common Options
- -
--limit N — Max items to return (default 25) - INLINECODE39 — Sort by dateModified, title, creator, date
- INLINECODE40 — Sort direction
- INLINECODE41 — Filter by or add to collection
- INLINECODE42 — Filter by item type (journalArticle, book, conferencePaper, etc.)
- INLINECODE43 — Add tags when creating items
- INLINECODE44 — Skip duplicate detection on add commands
Workflows
Add a paper by DOI
CODEBLOCK3
Duplicate detection: translates DOI to metadata, searches library by first author, compares DOI fields.
Bulk add from a file
CODEBLOCK4
Skips duplicates. Reports summary: added/skipped/failed.
Export bibliography
CODEBLOCK5
Update tags/metadata
CODEBLOCK6
Delete items
CODEBLOCK7
Cross-reference citations
CODEBLOCK8
Extracts Author (Year) patterns from text and matches against library.
Find missing DOIs
CODEBLOCK9
Scans journalArticle and conferencePaper items missing DOIs, queries CrossRef, and matches
by title similarity (>85%), exact year, and first author last name. Dry run by default — use
--apply to write. Only patches the DOI field; never touches other metadata. 1s delay between
CrossRef requests (polite pool with mailto).
Fetch open-access PDFs
CODEBLOCK10
Tries three legal OA sources in order: Unpaywall → Semantic Scholar → DOI content negotiation.
By default creates linked URL attachments (no Zotero storage quota needed). Use --upload for
full S3 upload to Zotero storage. Use --download-dir to also save PDFs locally.
Sources: unpaywall, semanticscholar, doi (default: all three)
Rate limits: 1s between Unpaywall/Semantic Scholar requests, 2s between DOI requests.
Scripting with JSON
CODEBLOCK11
Notes
- - Zero dependencies — Python 3 stdlib only (urllib, json, argparse)
- Write operations require an API key with write permissions
- If Zotero translation server is down (503), DOI lookups fall back to CrossRef
- Input validation: DOIs must be
10.xxxx/... format. Item keys are 8-char alphanumeric (e.g., VNPN6FHT). ISBNs must be valid checksums. - INLINECODE54 fetches all items; for large libraries (500+), this may be slow
- INLINECODE55 also processes all items — use
--collection to scope for large libraries - Rate limits are generous; batch-add includes 1s delay between items
- For common errors and troubleshooting, see references/troubleshooting.md
Zotero 技能
通过 REST API v3 与 Zotero 个人或群组文献库交互。
设置
需要两个环境变量:
ZOTEROAPIKEY — 在 https://www.zotero.org/settings/keys/new 创建
ZOTEROUSERID — 在同一页面找到(数字格式,非用户名)
对于群组文献库,请设置 ZOTEROGROUPID 代替 ZOTEROUSERID。
用于 CrossRef/Unpaywall 礼貌池的可选环境变量(提高 DOI 查找成功率):
CROSSREF_EMAIL — 您的邮箱(可选;未设置时使用备用方案)
如果缺少凭证,请告知用户所需内容并链接到密钥创建页面。
CLI 脚本
所有操作均使用 scripts/zotero.py(Python 3,零外部依赖)。
bash
python3 scripts/zotero.py <命令> [选项]
命令
| 命令 | 描述 | 示例 |
|---|
| items | 列出顶级条目 | zotero.py items --limit 50 |
| search |
按查询搜索 | zotero.py search 认知负荷 |
| get | 完整条目详情 + 附件 | zotero.py get ITEMKEY |
| collections | 列出所有合集 | zotero.py collections |
| tags | 列出所有标签 | zotero.py tags |
| children | 列出条目的附件/笔记 | zotero.py children ITEMKEY |
| add-doi | 通过 DOI 添加条目(启用去重) | zotero.py add-doi 10.1234/example |
| add-isbn | 通过 ISBN 添加条目(启用去重) | zotero.py add-isbn 978-0-123456-78-9 |
| add-pmid | 通过 PubMed ID 添加条目 | zotero.py add-pmid 12345678 |
| delete | 将条目移至回收站(默认可恢复) | zotero.py delete KEY1 KEY2 --yes |
| update | 修改条目元数据/标签 | zotero.py update KEY --add-tags 新标签 |
| export | 导出为 BibTeX/RIS/CSL-JSON | zotero.py export --format bibtex |
| batch-add | 从文件批量添加条目 | zotero.py batch-add dois.txt --type doi |
| check-pdfs | 报告哪些条目有/缺少 PDF | zotero.py check-pdfs |
| crossref | 将引用与文献库匹配 | zotero.py crossref bibliography.txt |
| find-dois | 通过 CrossRef 查找并添加缺失的 DOI | zotero.py find-dois --limit 10 |
| fetch-pdfs | 获取条目的开放获取 PDF | zotero.py fetch-pdfs --dry-run |
全局标志
- - --json — JSON 输出替代人类可读格式(适用于 items、search、get)
常用选项
- - --limit N — 最大返回条目数(默认 25)
- --sort FIELD — 按 dateModified、title、creator、date 排序
- --direction asc|desc — 排序方向
- --collection KEY — 按合集筛选或添加到合集
- --type TYPE — 按条目类型筛选(journalArticle、book、conferencePaper 等)
- --tags tag1,tag2 — 创建条目时添加标签
- --force — 在添加命令中跳过重复检测
工作流程
通过 DOI 添加论文
bash
python3 zotero.py add-doi 10.1093/jamia/ocaa037 --tags 综述
如果已在文献库中则发出警告。使用 --force 覆盖。
重复检测:将 DOI 转换为元数据,按第一作者搜索文献库,比较 DOI 字段。
从文件批量添加
bash
每行一个标识符,# 表示注释
python3 zotero.py batch-add dois.txt --type doi --tags 已导入
跳过重复项。报告摘要:已添加/已跳过/失败。
导出参考文献
bash
python3 zotero.py export --format bibtex --output refs.bib
python3 zotero.py export --format csljson --collection COLLKEY
更新标签/元数据
bash
python3 zotero.py update ITEMKEY --add-tags 重要 --remove-tags 未读
python3 zotero.py update ITEMKEY --title 更正后的标题 --date 2024
python3 zotero.py update ITEMKEY --doi 10.1234/example
python3 zotero.py update ITEMKEY --url https://example.com/paper
python3 zotero.py update ITEMKEY --add-collection COLLKEY
删除条目
bash
python3 zotero.py delete KEY1 KEY2 --yes # 回收站(可恢复,默认)
python3 zotero.py delete KEY1 --permanent --yes # 永久删除
交叉引用
bash
python3 zotero.py crossref my-paper.txt
从文本中提取作者(年份)模式并与文献库匹配。
查找缺失的 DOI
bash
试运行(默认)— 显示匹配结果但不写入任何内容
python3 zotero.py find-dois --limit 20
实际将 DOI 写入 Zotero
python3 zotero.py find-dois --apply
按合集筛选
python3 zotero.py find-dois --collection COLLKEY --apply
扫描缺少 DOI 的 journalArticle 和 conferencePaper 条目,查询 CrossRef,并通过标题相似度(>85%)、精确年份和第一作者姓氏进行匹配。默认试运行 — 使用 --apply 写入。仅修补 DOI 字段;从不触碰其他元数据。CrossRef 请求之间间隔 1 秒(使用 mailto 的礼貌池)。
获取开放获取 PDF
bash
试运行 — 显示哪些 PDF 可用及来源
python3 zotero.py fetch-pdfs --dry-run --limit 10
获取并作为链接 URL 附加(不占用存储配额)
python3 zotero.py fetch-pdfs --limit 20
同时本地保存 PDF
python3 zotero.py fetch-pdfs --download-dir ./pdfs
上传到 Zotero 存储而非链接 URL
python3 zotero.py fetch-pdfs --upload --limit 10
仅尝试特定来源
python3 zotero.py fetch-pdfs --sources unpaywall,semanticscholar
按顺序尝试三个合法的 OA 来源:Unpaywall → Semantic Scholar → DOI 内容协商。默认创建链接 URL 附件(不需要 Zotero 存储配额)。使用 --upload 进行完整的 S3 上传到 Zotero 存储。使用 --download-dir 同时本地保存 PDF。
来源: unpaywall、semanticscholar、doi(默认:全部三个)
速率限制: Unpaywall/Semantic Scholar 请求之间间隔 1 秒,DOI 请求之间间隔 2 秒。
使用 JSON 编写脚本
bash
python3 zotero.py --json items --limit 100 | jq .items[].DOI
python3 zotero.py --json get ITEMKEY | jq .title
注意事项
- - 零依赖 — 仅使用 Python 3 标准库(urllib、json、argparse)
- 写入操作需要具有写入权限的 API 密钥
- 如果 Zotero 翻译服务器宕机(503),DOI 查找将回退到 CrossRef
- 输入验证: DOI 必须为 10.xxxx/... 格式。条目键为 8 位字母数字(例如 VNPN6FHT)。ISBN 必须为有效校验和。
- check-pdfs 获取所有条目;对于大型文献库(500+),可能较慢
- fetch-pdfs 也处理所有条目 — 对于大型文献库,使用 --collection 限定范围
- 速率限制较为宽松;批量添加在条目之间包含 1 秒延迟
- 有关常见错误和故障排除,请参阅 references/troubleshooting.md