zotero-cli 技能实战指南:在 shell 中直达 Zotero 文献库的检索、阅读、标注与写作全流程

原创2026-10-03 12:20:23599 阅读
文章标签:MCP 服务AI 应用人工智能知识管理

zotero-cli 技能实战指南:在 shell 中直达 Zotero 文献库的检索、阅读、标注与写作全流程

zotero-cli 是本仓库(zotero-mcp)随包发布的命令行技能,它让具备 shell 访问能力的 AI Agent 或开发者不经过 MCP 服务器,直接读写 Zotero 文献库——从关键词/语义检索、读取 PDF 全文与指定页范围,到设置元数据、管理合集与标签、批量添加条目和导出参考文献。读完本文,你将掌握 zotero-cli 的完整命令体系、--json 机器可读输出契约,以及一套"先定位键(key)、再对键执行动作"的高效工作流,并能结合仓库源码理解其底层实现原理。

为什么需要 zotero-cli:省掉每轮 ~14k token 的上下文开销

zotero-cli 与 Zotero MCP 服务器的定位不同:MCP 服务器的工具 schema 在每次请求时都会占用约 14k token 的上下文(无论你是否真正用到这些工具),而命令行方式"只为你实际运行的那次调用付费"。因此 SKILL.md 明确建议:当你有 shell 访问权限时,优先使用 zotero-cli 而非 MCP 服务器。

该技能本体打包在 wheel 内部,由 zotero-mcp install-skill 安装到当前 Agent 环境中。skill_install.py 的模块注释解释了它的分发策略:不同 Agent 读取约定不同——Claude Code 读取 skills 目录下的 SKILL.md,Cursor 与 Windsurf 读取带各自 frontmatter 的规则文件,而 Codex、Amp、OpenCode、Jules、Gemini 等工具读取单文件项目级指令。install-skill 通过检测磁盘上已有的目录(如 .cursor/、AGENTS.md)自动判断目标,而不是要求用户学习这些工具的"分类法"。安装过程遵守两条铁律:绝不覆盖(目标已存在且内容不同时只报告、不覆写,除非传入 --force)和渐进式披露(共享指令文件只写一小段指针块,完整技能正文放在旁边文件,避免把约 1400 token 的技能全文塞进每个 Agent 的常驻上下文)。

首次调用前的环境检查

在第一次真实调用之前,先确认环境可用:

zotero-cli config          # 打印解析后的 Zotero 设置

该命令在源码中的实现(cli_standalone.py)会调用 setup_zotero_environment(),然后汇总所有 ZOTERO_ 前缀环境变量以及 OPENAI_API_KEY、GOOGLE_API_KEY、GEMINI_API_KEY;默认对 API key 做脱敏显示,只有加 --show-secrets 才显示完整密钥。

如果 config 失败,说明 Zotero 不可达,需要区分两种模式:

  • 本地模式:Zotero 桌面应用正在运行且已启用本地 API;
  • Web 模式:需要设置 ZOTERO_API_KEY 与 ZOTERO_LIBRARY_ID 环境变量。

遇到这种情况应如实说明 Zotero 不可达,而不是去猜测库中内容。

机器可读输出:--json 信封契约

默认输出是给人看的 Markdown;--json 则保证每次调用输出一个形状稳定的 JSON 对象,让你永远不必解析散文:

{"ok": true, "command": "search", "schema": 1, "data": {...}}
{"ok": false, "command": "search", "schema": 1, "error": {"message": "...", "code": "..."}}

成功与失败的信封都写到 stdout,[INFO]/[WARN] 诊断信息写到 stderr。使用时先检查 ok 再使用 data。运行 zotero-cli --json-schema 可查看完整的输出契约文档。

这一契约的源码实现在 cli_json.py:envelope() 统一构造 {"ok", "command", "schema": 1} 形状,SCHEMA_VERSION = 1 表示信封自身结构的版本(各命令向 data 中新增字段属于兼容的增量变更,删除字段则不允许)。值得注意的是 emit_error() 的注释刻意把失败信封也写到 stdout——调用方只读一个流时,不必合并两个流才能发现调用失败;而人类可读路径则把错误写到 stderr,这对终端用户更合适。

另一个关键设计在 _out()(cli_standalone.py):底层工具多数以散文形式返回失败而非抛出异常,若不处理,这些散文会变成 ok: true 的信封并以退出码 0 结束,让检查 ok 的调用方误以为写操作成功。因此 _reports_failure() 用固定开头的正则(Error、Failed to、Could not、Cannot)识别失败散文,在 JSON 模式下转为 ok: false 信封并 sys.exit(1)。cli_standalone.py 的 main() 还保证异常同样以统一形状输出,且 ZOTERO_CLI_DEBUG 环境变量可触发 traceback 输出。

三级条目投影:keys_only / summary / full

任何列出条目的命令都返回相同的条目形状(project_item),因此针对 search 写的管道同样适用于 get recent 或 get collection-items:

  • keys_only:key、itemType、title、date——足以决定下一步取什么,且小到可以列整个库;
  • summary(默认):在 keys_only 基础上增加作者、DOI、出版物、标签、所在合集;
  • full:再增加摘要和完整的原始 data 字典(放在 raw 下)。

每级都携带 key 与 itemType,方便调用方识别手中对象;若条目在回收站,会额外带 "deleted": true。相关测试见 test_cli_json_output.py 与 test_library_code_keeps_stdout_clean.py(后者专门守护 stdout 纯净性,确保 zotero-cli --json 系列绝不输出非 JSON 内容)。

核心工作循环:find keys → act on keys

几乎所有任务都遵循同一模式:先找到条目键,再对键执行动作。条目键(item key)是 8 个字符,是每个命令之间传递的"货币"。

# 1. find - 用 --detail keys_only 在浏览时保持结果小巧
zotero-cli --json search "attention mechanisms" --limit 10 --detail keys_only

# 2. act - 取元数据、全文,或一个页范围
zotero-cli --json get metadata ABCD1234
zotero-cli --json get fulltext ABCD1234
zotero-cli --json read ABCD1234 --start-page 3 --end-page 8

把键直接管道给下一个调用:

zotero-cli --json search "diffusion models" --limit 5 --detail keys_only \
  | jq -r '.data.items[].key' \
  | while read -r key; do zotero-cli --json get metadata "$key"; done

这个循环的 JSON 路径很有意思:cmd_search 在 JSON 模式下并非重新实现一遍选择逻辑,而是先调用与 Markdown 模式完全相同的工具函数获取结果文本,再用 _keys_from_markdown() 从固定格式的 **Item Key:** KEY 行中把键读回来(cli_standalone.py)。这样搜索级联、语义排序、合集限定等逻辑只存在一份,JSON 只改变渲染方式,两种模式在"哪些条目命中"上永远一致。_fetch_projected() 还会按给定顺序重新投影条目,因为顺序本身承载意义(相关性、时间新近度)。

选择正确的搜索模式

search(别名 s)提供六种模式,按需选择:

模式 适用场景 命令示例
items(默认) 你知道标题、作者或某个短语 search "Vaswani attention"
semantic 只关心主题或想法,没有确切措辞 search --mode semantic "why transformers scale"
tag 按标签筛选已归档条目 search --mode tag "to-read,important"
advanced 结构化字段条件组合 search --mode advanced --conditions '[...]'
citekey 按 BibTeX 引文键查找 search --mode citekey smith2020
notes 搜索笔记正文(而非条目字段) search --mode notes "research question"

semantic 模式依赖搜索索引:用 zotero-cli db status 检查、zotero-cli db update 构建。若索引为空,应回退到 items 模式并说明原因,而不是报告"无结果"。

items 模式还支持 --qmode 参数(titleCreatorYear,默认,或 everything),以及 --sort-by、--sort-direction、--collection 限定范围。advanced 模式通过 --conditions 传入 JSON 数组、--join-mode 指定 all/any 连接。semantic 模式可用 --filters 传 JSON 过滤器。

跨库搜索:--all-libraries

默认每次搜索只覆盖当前活动库。当你不确定条目在哪个库、或单库搜索落空但条目可能存在于群组库时,加 --all-libraries:

zotero-cli search "Cladder-Micus" --all-libraries

此时每个结果会标注 **Library:** <name>。该选项需要 SQLite 后端(本地模式默认),未启用时会明确报错,因此先试一次,被拒绝就回退到逐个库搜索。标签过滤可以与它配合;--collection 不行,因为合集只存在于某一个库内。

高效阅读:outline 定位 + read 页范围

对一本书那么长的 PDF 执行 get fulltext 会返回海量文本。当你只需要某一段内容时,先读目录(outline)定位,再只读那几页:

zotero-cli --json outline ABCD1234
zotero-cli --json read ABCD1234 --start-page 42 --end-page 55

对于"我的库对 X 说了什么"这类问题,优先 search --mode semantic 然后定向 get metadata,而不是通读整篇论文。

read 命令(cli_standalone.py)在 JSON 模式下返回 {item_key, start_page, end_page, text, chars}。文本模式走 read_pdf_text(..., surface="cli");--end-page 默认等于 --start-page(即只读一页),且会自动钳制到最后一页。

数学、图表和表格:文本不可靠时的图片模式

提取出的文本对正文(prose)可靠,对数学公式、图和表不可靠——符号会丢失、表格单元格会粘连在一起。read 会在发生这种情况的每一页上标注,例如 "Garbled in this text: Equation (1), Table 2"。对这些页,如果你能看图,就直接看页面本身:

zotero-cli read ITEM_KEY --start-page 4 --format image                         # 每页一张 PNG,最多 10 页
zotero-cli read ITEM_KEY --start-page 4 --format image --rect 0.35,0.49,0.3,0.05   # 放大到某个区域

--rect 只与 --format image 搭配(源码中会以 bad_rect 错误拒绝其他组合),坐标为归一化 0–1 的 x,y,width,height;图片写入 --out 指定目录,默认是新的临时目录(tempfile.mkdtemp(prefix="zotero_pages_")),每张 PNG 命名为 <item_key>-p<页码>.png,带 --rect 时后缀 -region。JSON 模式返回每张图片的路径、宽高和页码。

分页:处理超过 --limit 的列表

列表类命令以 --limit 封顶。当还有更多数据时,响应会提示并给出下一个 offset:

zotero-cli --json get collection-items QS7TQPPA --limit 100 --offset 100

持续翻页,直到 data.count 小于 --limit 为止。注意 get collection-items 的 --detail 默认是 summary,--limit 默认 50;get collections 与 get tags 的 --limit 默认 500,get recent 默认 10,get feed-items 默认 20。

写入操作:add、edit、notes 与 batch

写命令把操作结果以文本形式放在 data.text 下:

zotero-cli add doi 10.1038/s41586-021-03819-2 -c "Reading List"
zotero-cli edit ABCD1234 --title "Corrected Title" --add-tags reviewed
zotero-cli notes create --item-key ABCD1234 --text "Key finding: ..."
zotero-cli batch --item-keys A1B2C3D4,E5F6G7H8 --add-tags screened

add 有五个子命令,覆盖常见入库路径:

  • add doi <doi>:按 DOI 入库(还有 add url、add isbn);
  • add file --filepath:导入本地文件,--item-type 默认 document,可用 --title 覆盖元数据提取失败的情况;
  • add bibtex:--bibtex 内联或 --file 指定 .bib/.bibtex 文件;
  • add csl-json:--json 内联或 --file 指定 .json/.csljson 文件。

所有 add 子命令共享 --collections(逗号分隔的键/名称/路径)、可重复的 -c/--collection(不按逗号拆分,因此含逗号的合集名也能用)、--tags、--create-collections(自动创建不存在的合集,含父子路径)以及 --if-exists 三值选项:

  • file(默认):条目已存在时复用旧条目并补齐缺失的合集与标签;
  • skip:完全不动已存在条目;
  • duplicate:无论如何都新建条目。

因此 add 默认是幂等的:重复运行只是把已有条目归入指定合集,不会制造重复记录。部分子命令还提供 --attach-mode(auto/linked_url/import_file/none/required)。

在进行破坏性变更(delete、duplicates merge、对大量条目的 batch)之前,先与用户确认并展示将影响哪些条目。delete item 默认拒绝删除笔记(笔记通常是误删),必须显式加 --allow-note。批量更新条目由 batch 承担:除了 --item-keys,还可以用 --query(按搜索词选条目)或 --tag(按标签选)圈定目标,支持 --add-tags/--remove-tags 以及用 --set/--remove-keys 读写 Extra 字段。

本地写入授权

本地模式的写操作需要一次性执行 zotero-mcp authorize-local(Zotero 10 或更新版本),或提供 Web API 凭据。如果写入因这个原因被拒,错误信息会明确指出。

阅读并标注一篇论文:四步工作流

先定位附件键、读文本、必要时再看文件路径:

zotero-cli get children ITEM_KEY                          # 该条目的 PDF 附件键
zotero-cli read ITEM_KEY --start-page 1 --end-page 99     # 结束页自动钳到最后一页
zotero-cli path ATTACHMENT_KEY                            # PDF 在磁盘上的路径

标注的正确姿势是:把一切都计划好、检查无误,然后一次性写入。SKILL.md 给出了严格的四步流程:

  1. zotero-cli --json layout ATTACHMENT_KEY:列出图表与公式框及其题注,每个框都带一个可直接粘贴的 rect_arg(源码 cmd_layout 走 annotations.detect_layouts(),--pages 可指定 all/3/3-6/1,4,6-9);
  2. 每行写一个 JSON 对象。三种标注形态:
    • 高亮:{"page": 4, "text": "exact words", "comment": "...", "color": "yellow"}——高亮文本必须从 read 中逐字复制,系统会在该页及其前后各两页范围内搜索它;
    • 框选:{"page": 3, "rect": "x,y,w,h", "comment": "..."};
    • 便签:{"page": 1, "note": "x,y", "comment": "..."}——以某个点为中心放置,文本就是 comment;
  3. zotero-cli annotations batch --attachment-key ATTACHMENT_KEY --file plan.jsonl --dry-run:先试跑一次,显示每个高亮将覆盖哪些文字,修正所有未命中的地方;
  4. 去掉 --dry-run 真正执行。任何未落地的条目会列在 data.results 中,ok: false,退出码为 1。

批量输入文件 --file 默认 -(读 stdin),既支持 JSON Lines,也支持单个 JSON 数组;_read_annotation_specs() 会逐行校验 JSON 并拒绝空批次(empty_batch)。_annotations_batch() 实现中,各 spec 按附件分组、每组一次调用(PDF 只取一次),即使部分 spec 失败也会逐个尝试全部、逐个列出结果,方便只重试失败项。颜色接受 Zotero 的命名:yellow、red、green、blue、purple、magenta、orange、gray(也接受十六进制,默认 #ffd400)。三四种有固定含义的颜色比八种都好读——建议在条目上加一条笔记说明各颜色含义。

annotations(别名 ann)其余子命令:list(可加 --pdf-extraction,默认按 Zotero 已保存标注)、create(单条创建,与 JSONL spec 同字段)、update(--text/--comment/--color/--add-tags/--remove-tags)、delete。

当结果看起来不对:诊断路径

  • 空搜索结果:先检查 zotero-cli config,语义模式还要 zotero-cli db status。在确认库确实可达且已建索引之前,不要报告"你没有关于 X 的论文";
  • ok: false:读 error.message,它指出了原因;
  • 搜索结果带 partial-results 提示:说明扫描被截断,不是"没有其他匹配",收窄查询条件后重跑;
  • 条目标记 "deleted": true:说明它在回收站,不要当作活动库内容处理。

完整命令参考与参数速查

reference.md 位于本技能目录 src/zotero_mcp/skills/zotero-cli/reference.md,列出每个命令与全部 flag,由 scripts/gen_skill_reference.py 从 CLI 自身的参数解析器生成(勿手改)。SKILL.md 未覆盖的需求,先查它;任何单个命令也可用 zotero-cli <command> --help。

需要留意的全局规则(reference.md 开头):--json 与 -v 定义在顶层解析器和每个一级命令上,因此可以放在命令名前或后,但不能跟在子命令后面——get --json metadata KEY 能解析,get metadata --json KEY 不行。完整的命令族包括:

  • 元数据与全文:get metadata|fulltext|bibtex|collections|collection-items|children|tags|recent|libraries|feeds|feed-items,outline、read、path、layout、export;
  • 搜索:search(六模式)、related(按 DOI/arXiv ID/条目键查引用方向,--direction references|citations|both,默认 20 条)、coverage(按合集统计库覆盖)、duplicates find|merge(--method title|doi|both,合并前建议 --dry-run);
  • 整理:collections create|update|search|manage、tags(--query/--tag/--add/--remove)、edit(标题、作者 JSON 数组、日期、DOI、URL、Extra、卷期页码等二十余个字段)、batch、library switch|list|reset(--library-id + --library-type user|group);
  • 库级任务:db update|status|inspect|batch-status|batch-import(更新索引,--force-rebuild/--limit/--fulltext/--openai-batch)、synthesize(按合集或标签汇总标注,--format markdown|json,默认上限 200 条)、attach(--file 上传或 --url 建链接)、notes list|create|update|delete、delete item|collection|annotation、config。

小结

zotero-cli 把 Zotero 文献库变成了一组可组合的 shell 命令:--json 信封保证机器可读,find keys → act on keys 的工作循环让检索、阅读、标注、写入都能流水线化,六种搜索模式覆盖从精确到语义再到笔记正文的检索需求,而 layout + annotations batch 的四步标注流程让批量标注既准确又可回滚。它既是 MCP 服务器之外更省 token 的替代通道,也是脚本、定时任务与 Agent 集成 Zotero 的统一入口。

登录后查看全文
zotero-mcp