我平时最常开着的三个东西Zotero 管文献VS Code 写东西Claude Code 处理杂活。以前这三者是割裂的——我写论文的时候得先在 Zotero 里搜半天文献复制标题和摘要再切到终端里让 Claude Code 帮我总结、翻译、理思路。来回切窗口切得人崩溃。后来我想明白一件事Claude Code 本质是一个能执行命令的对话终端而 Zotero 7 自带本地 HTTP API我只需要在中间加一层极薄的查询脚本就能让 Claude 自己“翻”我的文献库。这篇文章就把我这两周在 Windows 和 Mac 上分别接通的完整过程和踩过的坑写出来给有同样需求的人省点时间。内容分四条线为什么要这么接、环境怎么准备、Windows 和 Mac 两套步骤、我遇到的 8 个实际问题。无论你是刚装好 Zotero 的新手还是已经在用 Claude Code 的老手照着走一遍基本都能通。1. 为什么折腾文献管理和终端之间的反复横跳到底有多浪费时间1.1 我的工作流痛点我写综述类文章时最频繁的操作是打开 Zotero搜索关键词点开一篇文献复制摘要切到终端粘贴给 Claude让它帮我提炼观点。然后回到 Zotero再找下一篇。平均一篇文献要来回切三四次窗口十分钟能搜完的资料硬生生拖到半小时。更烦的是多轮对话的信息丢失。我让 Claude 总结五篇文献它总结完了我想让它“把第三篇和第五篇做一个对比”它得重新读一遍我之前粘贴的东西。一旦我粘贴时漏了某个字段或者复制错了摘要整个讨论基础就是歪的。这个问题本质上不是“AI 不行”而是“输入链路太原始”。Claude Code 本身已经具备读文件、执行命令的能力那为什么不把 Zotero 也变成它可以主动访问的资源1.2 接入前先想清楚到底让 Claude 读什么最开始我野心很大想让 Claude 直接读 PDF 全文、总结每篇论文。做完一轮发现这属于自讨苦吃。Zotero 的本地 API 返回的是结构化的文献元数据包括题目、作者、年份、期刊、摘要、标签、DOI 这些。这些字段足够覆盖 80% 的日常需求。PDF 全文是另一套复杂路径文件存在 Zotero 的 storage 目录里文件名是乱的PDF 解析还需要额外的库处理起来非常容易翻车。所以我把核心目标定为让 Claude 能够按关键词、作者、标签、年份检索我的 Zotero 条目并拿到摘要和笔记。全文读取放到后面的扩展计划里而不是第一步就做。1.3 三种接入方案对比我最后选了哪条方案一Zotero Web API API Key。优点是不依赖本机任何设备都能连缺点是数据要走云同步我一些书和未发表的笔记不想上传到服务器而且申请 Key、处理限流都很麻烦。方案二Better BibTeX 定期导出 JSON/CSV让 Claude 直接读文件。优点是实现最简单一个文件就搞定缺点是实时性差每次改完 Zotero 都得手动导出字段命名也和 Zotero 本地 API 不一致Claude 读起来容易糊涂。方案三Zotero 本地 API 轻量查询脚本。Zotero 7 自带一个本地 HTTP 服务默认监听 23119 端口返回的就是标准 JSON 字段。把查询封装成一个命令行脚本Claude 需要时直接运行这个脚本拿结果。我最后选了方案三同时把方案二作为离线备份。本地 API 的好处其实很明显实时、免费、不依赖云同步返回的数据结构和 Zotero 官方一致。你只需要在 Zotero 设置里打开一个开关然后自己写一个几行字的脚本就能跑通。2. 基础环境Windows 和 Mac 上先把这两个工具的坑填平2.1 打开 Zotero 的本地 API 开关这一步两平台一模一样Zotero 7 及以上版本才能稳定使用本地 API。如果你还在用老版本我建议先升级很多本地接口的体验在 7 里才正常。打开 Zotero进入菜单栏的“编辑”里的“设置”切到“高级”选项卡往下拉找到“允许本机其他应用程序与 Zotero 通信Allow other applications on this computer to communicate with Zotero”勾上它。勾选之后Zotero 会在本机启动一个 HTTP 服务默认端口 23119。注意一个很容易踩的细节勾选后最好完全退出 Zotero 再重新打开。我一开始只改了设置没重启端口一直没监听白白排查了十分钟。重启后无论 Windows 还是 Mac理论上都应该能通过 http://localhost:23119 访问到服务了。2.2 安装 Claude Code并确认它能调用外部命令Claude Code 我是在 VS Code 里集成的因为我的写作和代码都在 VS Code 里完成计划文档、论文草稿、脚本全部一个窗口搞定。安装过程不复杂按照官方文档拉到本地 PATH 里就行。装完在终端输入 claude 能进交互界面就算成功。这里有个很关键的认知Claude Code 默认不会随便执行外部命令。当它第一次准备调用某个工具或脚本时会弹出权限确认。很多人在这里选择了“拒绝”结果后面 Claude 就不碰脚本了还误以为它能力不行。正确的做法是先想清楚这条命令安不安全安全就给放行或加入允许列表。像我们后面要写的查询脚本是只读操作逻辑上不碰任何文件风险很低完全可以放心让它跑。我当时在 Windows 和 Mac 上都做了同样的事情先确认 Zotero 端口通再装 Claude Code再验证它能正常执行 python 脚本最后才写接入层。这个顺序不建议颠倒因为我见过有人一口气配完才发现 Zotero 设置没开回头排查时多花了三倍时间。2.3 Windows 和 Mac 的路径差异先记在心里Zotero 的数据目录Windows 一般在 C:\Users\你的用户名\ZoteroMac 一般在 ~/Zotero。后面写脚本时尽量不要硬编码路径最好用 Python 的 pathlib 按用户目录去拼。这个细节一开始不在乎等你换电脑或者别人拿你的脚本用时就会感谢这个决定。另外一个差异是 Python 命令名。Windows 上很多人敲 pythonMac 上通常敲 python3。为了省事我脚本里统一用 sys.platform 做了编码适配命令行调用时两个平台分别写成 python 和 python3CLAUDE.md 里也把两条命令都列出来让 Claude 自己根据系统选。3. Windows 完整接入流程写一个能被 Claude 调用的查询脚本3.1 第一步探测本地 API 是否存活打开 PowerShell执行这条命令Invoke-RestMethod http://localhost:23119/connector/ping如果返回一个单词 ping说明 Zotero 本地服务已经活了。如果报错先检查 Zotero 设置有没有勾选再检查是否重启了 Zotero最后看端口是否被其他程序占用。顺手也可以把 23119 端口的情况查清楚Windows 上我用netstat -ano | findstr 23119能看到 LISTENING 就说明端口监听了。这一步能帮你后面排除“端口占用”还是“Zotero 没启动”的迷案。3.2 第二步写一个查询脚本 zotero_query.py这个脚本是整条链路的核心作用就是把 Zotero 本地 API 的查询结果变成干净、易读的文本。我用了 Python 标准库 urllib没有引入 requests这样可以省掉安装依赖的麻烦Windows 和 Mac 上跑起来都省心。#!/usr/bin/env python3 # -*- coding: utf-8 -*- import argparse import json import sys import urllib.parse import urllib.request ZOTERO_LOCAL_API http://localhost:23119/api ZOTERO_USER_ID 0 def fetch_items(query: str, limit: int): url f{ZOTERO_LOCAL_API}/users/{ZOTERO_USER_ID}/items params {q: query, limit: limit, format: json} url ? urllib.parse.urlencode(params) req urllib.request.Request(url, headers{User-Agent: zotero-helper/1.0}) with urllib.request.urlopen(req, timeout10) as resp: data json.loads(resp.read().decode(utf-8)) return data def format_creators(creators): names [] for creator in creators or []: if creator.get(firstName) or creator.get(lastName): names.append(f{creator.get(lastName, )}, {creator.get(firstName, )}) elif creator.get(name): names.append(creator[name]) return ; .join(names) def format_item(item): data item.get(data, {}) lines [] if data.get(title): lines.append(f标题: {data[title]}) if data.get(creators): lines.append(f作者: {format_creators(data[creators])}) if data.get(date): lines.append(f日期: {data[date]}) if data.get(publicationTitle): lines.append(f期刊: {data[publicationTitle]}) if data.get(abstractNote): snippet data[abstractNote].strip().replace(\n, ) if len(snippet) 180: snippet snippet[:180] ... lines.append(f摘要: {snippet}) if data.get(tags): tags [t.get(tag, ) for t in data[tags]] lines.append(f标签: {, .join(tags)}) return \n.join(lines) def main(): if sys.platform.startswith(win): sys.stdout.reconfigure(encodingutf-8, errorsreplace) parser argparse.ArgumentParser(descriptionQuery Zotero local API) parser.add_argument(--q, default) parser.add_argument(--limit, typeint, default10) args parser.parse_args() items fetch_items(args.q, args.limit) if not items: print(没有找到匹配的文献条目。) return for idx, item in enumerate(items, 1): print(f[{idx}]) print(format_item(item)) print() if __name__ __main__: main()这个脚本刻意做得很朴实一个查询参数、一个数量参数输出就是带编号的列表。摘要超长时只截前 180 个字符避免 Claude 的上下文被一大段废话塞满。Windows 下用 sys.stdout.reconfigure(encodingutf-8, errorsreplace) 解决控制台中文乱码问题这个我后面在第 6 节会专门展开讲。注意我在输出里没有包含 Zotero 的 item key 和 PDF 路径第一版尽量保持干净。等你想要做更深度的操作让 Claude 回写笔记或者定位文件时再把关键字段加进去。3.3 第三步把脚本放到 Claude Code 能找到的位置我建议在用户目录下建一个 bin 文件夹专门放这种“给 AI 用的小工具”然后把 zotero_query.py 放进去并把这个目录加入 PATH。Windows 上可以通过系统设置把 C:\Users\你的用户名\bin 加入 PATH也可以直接用高级系统设置里的环境变量面板操作。加完之后另开一个新的终端窗口运行python C:\Users\你的用户名\bin\zotero_query.py --q edge computing --limit 5如果输出正常说明脚本本身没问题。如果你电脑上 python 命令启动不了试一下 py 前缀py C:\Users\你的用户名\bin\zotero_query.py --q edge computing --limit 5这一步看着不起眼但特别容易卡人。Windows 的 Python 启动器有 python、py 两种别名不同安装方式默认不一样。我的建议是脚本写好后先手动把整条命令跑通再去接 Claude Code不然很难判断到底是环境问题还是 Claude 的问题。3.4 第四步在 CLAUDE.md 里定义调用规则Claude Code 在一个项目目录下工作时会读取该目录下的 CLAUDE.md 作为上下文规则。我就在自己的论文项目根目录里建了一个 CLAUDE.md加了这样一段## Zotero 文献查询 当用户需要检索文献、查看文献信息、整理引用时使用以下命令 - Windows: python C:\Users\用户名\bin\zotero_query.py --q 关键词 --limit 10 - macOS: python3 ~/bin/zotero_query.py --q 关键词 --limit 10 执行后按顺序输出标题、作者、日期、期刊、摘要、标签。 只基于脚本返回的结果回答用户的问题不要编造不存在的文献条目。之后的对话里我只要说“帮我找三篇最近三年关于联邦学习的文献”Claude 就会自己去执行命令再把结果格式化给我。这一步做完Windows 这边的链路就彻底通了。4. Mac 接入流程同样的思路换一套环境细节4.1 Mac 上的探测方式与 Windows 的差异Mac 上同样要先确认 Zotero 本地接口活着。打开终端运行curl -s http://localhost:23119/connector/ping正常会输出 ping。如果没反应同样先检查 Zotero 设置里的“允许本机其他应用程序与 Zotero 通信”然后完全重启 Zotero。Mac 上查看端口监听我习惯用lsof -i :23119能看到 Zotero 进程监听了 23119 就行。Mac 一般不会有防火墙拦 localhost 的问题比 Windows 省心一些但也不是零坑。4.2 zsh 环境变量与 python3 定位Mac 上最容易踩的第一个坑是找不到合适的 python3。系统自带的 /usr/bin/python3 版本可能偏老而且如果你装了 Homebrew 的 Python它默认在 /opt/homebrew/binApple Silicon或 /usr/local/binIntel Mac。问题是 zsh 的 PATH 里不一定有这个目录。我用的是 Apple Silicon Mac装完 Homebrew 后先遇到了 python3 指向老版本的问题。当时 which -a python3 出来的路径乱七八糟。修复方法是在 ~/.zprofile 里追加一行export PATH/opt/homebrew/bin:$PATH然后 source ~/.zprofile重新打开终端再确认一下 python3 --version。确保版本不低于 3.8因为 urllib 和 reconfigure 这些用法在更老的版本里可能不稳定。因为我的脚本只用标准库理论上任何 Python 3 都能跑所以这一步主要是确保权限和路径正确。如果你装了 conda 或者 pyenv谨慎起见可以给 zotero_query.py 加个 shebang或者用绝对路径调用 python3省得到时候 Claude 找到的 Python 和你预期的不一致。4.3 Mac 上的运行验证路径没问题之后把 zotero_query.py 复制到 ~/bin/然后在终端测试python3 ~/bin/zotero_query.py --q LLM --limit 3Mac 终端默认 UTF-8正常不会有 Windows 那种中文乱码。看到带标题、作者、摘要的输出就说明链路通了。然后在项目的 CLAUDE.md 里把 macOS 的命令路径写好。我直接在同一个 CLAUDE.md 里同时写了 Windows 和 Mac 两个版本Claude 会根据执行环境自动选。实测下来它基本能判断对这个偶尔判断错你就纠正一下“在 Windows 上跑那条”它就记住了。5. 真实使用场景接入之后我是怎么用的5.1 场景一让 Claude 按关键词检索文献并给出摘要现在我的日常操作变成了这样我只需说一句“帮我找最近三年关于模型剪枝的文献每篇用一句话说它做了什么”。Claude 就会执行 zotero_query.py --q model pruning --limit 10然后从结果里筛出最近三年的按年份排好逐条给我摘要。省掉的不只是粘贴复制的操作还有筛选过程。以前我得自己先看一遍 Zotero 搜索结果再手动挑几篇发给 Claude现在是 Claude 先把结构化结果读一遍再标记出它认为相关的条目让我确认。虽然它偶尔会误判但整体效率提升非常明显。5.2 场景二批量生成 BibTeX 引用格式写论文时需要按期刊模板整理参考文献这个工作我以前是一篇篇从 Zotero 导出。现在直接让 Claude 基于查询结果生成 BibTeX 条目会快很多。本地 API 的 data 字段里正好包含 title、creators、date、publicationTitle、DOI、ISBN 这些足够拼出标准的 BibTeX。示例对话“把刚才那三篇文献生成 BibTeX 给我。”Claude 会输出类似article{liu2023edge, title {Edge Computing for Autonomous Driving}, author {Liu, Wei and Zhang, Hao}, year {2023}, journal {IEEE Transactions on ...}, doi {10.xxxx/xxxx} }当然更严谨的做法还是用 Better BibTeX 插件从 Zotero 直接导出官方格式但 Claude 生成的版本可用于初稿或者在你只需要两三篇引用时应急。用过之后你会发现“批量生成引用”这个场景其实非常吃字段的规范性所以我在脚本里特意把 DOI、期刊这些字段输出完整。5.3 场景三文献笔记的归纳整理Zotero 的条目不仅有元数据还有你手动添加的笔记这些笔记会作为子条目挂在主条目下面。本地 API 可以通过 /items/{itemKey}/children 拿到。我第一版脚本没把这个加进去后来在场景需求里补上了让 Claude 批量读取某一个课题下的文献笔记然后按主题归纳。这样做的价值在于Zotero 里的笔记通常是你自己写的、认为重要的内容质量比全文本摘要高很多。Claude 基于这些笔记去整理综述提纲会比直接读 PDF 全文更聚焦。当然前提是你平时确实有写笔记的习惯。5.4 场景四生成文献周报和选题盘点这个是我后来临时加的。每个月末我会让 Claude 统计最近 30 天加入 Zotero 的文献按标签分组生成一份“本月新增文献概览”。脚本里加一个 --since 参数就能实现。想想以前人工打开 Zotero 按时间排序、逐条看过去现在一句话就搞定了。6. 踩坑记录我在 Windows、Mac 上遇到的 8 个问题先列个总览表后面逐个展开。问题表现核心原因Windows 防火墙拦截浏览器能访问Python 请求超时Python 进程被拦中文乱码标题摘要变成乱码Windows 默认编码与 UTF-8 冲突Mac 找不到 python3命令报错无法执行Homebrew 路径未加入 PATH设置勾了不生效端口没监听Zotero 没完全重启端口被占用连接失败其他进程占用了 23119Better BibTeX 字段冲突Claude 答错信息JSON 字段和本地 API 不一致Claude Code 拒绝执行脚本从未运行权限未放行读不到 PDF 全文只有元数据本地 API 默认不含全文内容6.1 Windows 防火墙把 localhost 请求拦了我第一次在 Windows 上跑通脚本时遇到了一个很尴尬的情况浏览器输入 http://localhost:23119/connector/ping 能返回 pingInvoke-RestMethod 也能通但 Python 脚本跑起来就是超时。排查链路是这样的先确认端口监听正常再确认 Python 能访问外网最后发现是 Windows 防火墙把 Python 进程的入站请求拦了。浏览器之所以能通是因为它被加入了放行名单而 Python 没有。修复方法不是让你关防火墙而是在防火墙设置里给 Python 解释器单独放行勾选“专用网络”即可。或者更省事的方法当你第一次运行脚本时Windows 会弹出入站允许提示选允许就可以了。如果之前手滑点了取消就去“控制面板 - Windows Defender 防火墙 - 允许应用通过防火墙”里手动添加。6.2 Windows 终端打印中文乱码编码问题脚本在 Windows 终端执行后英文标题完全正常中文标题和摘要全变成乱码。原因很明确Python 在 Windows 下默认使用系统编码 GBK 输出而 Zotero 返回的是 UTF-8 字符串。修复方式我在脚本里已经写了if sys.platform.startswith(win): sys.stdout.reconfigure(encodingutf-8, errorsreplace)这行代码会把标准输出强制切回 UTF-8。如果你是在 cmd 里跑还可以把代码页先切到 65001chcp 65001。但最省事的还是上面那行代码。后来我发现 Windows Terminal 本身就支持 UTF-8所以换掉老旧的 cmd 也能少一半问题。6.3 Mac 找不到 python3Homebrew 路径没进 PATH在 Mac 上第一次执行 python3 ~/bin/zotero_query.py 时系统调用的 /usr/bin/python3 版本很老虽然也能跑但我担心时间长了出问题。后来装了 Homebrew 的 Python版本倒是新的但 zsh 里 which python3 依然指到系统自带。这个问题排查起来很枯燥echo $PATH看了一眼发现 /opt/homebrew/bin 根本没在里面。把 export 加进 ~/.zprofile 再 source 之后就正常了。我特意写出来是因为 Mac 新手经常会在这里卡住看着像 Python 问题实际是 shell 配置问题。6.4 Zotero 勾了设置却不生效重启服务进程我在 Windows 上改完 Zotero 设置后信心满满地探测端口结果连接被拒绝。排查步骤很顺利先看端口netstat 里没有 23119说明服务没起来。再看设置勾是勾了但 Zotero 没重启。Zotero 的本地 HTTP 服务是在软件启动时根据配置决定是否监听的改完设置最好彻底退出再打开。这个坑本身不大但非常容易忽略建议大家勾选后第一时间重启别在这个环节浪费时间。6.5 端口 23119 被占用有次我把 Zotero 开着一查端口监听发现 23119 被另一个程序占了。排查时先用 netstat 查到 PID再打开任务管理器定位占用的进程。如果那个进程无关紧要可以在任务管理器里结束它然后重启 Zotero 让它重新抢回端口。如果你不想动那个占用进程Zotero 的配置里也有一个端口设置项可以改在配置编辑器里找 httpServer 相关字段把端口改成别的值再同步修改脚本里的 ZOTERO_LOCAL_API。我个人不推荐主动改端口因为默认 23119 已经被大量教程和工具约定好了改了以后换环境总是要多想一步。6.6 Better BibTeX 导出的 JSON 字段和本地 API 字段不一致这个坑很有意思。本地 API 返回的字段是 title、creators、date而 Better BibTeX 导出的 JSON 里是 title、author、issuedtags 的层级结构也不一样。当时我让 Claude 在同一个对话里先读了本地 API 结果、又读了一个 Better BibTeX 导出文件它就开始混了把 author 字段当成完整的作者列表日期解析也出了偏差。修复方式是在 CLAUDE.md 里明确写清楚优先使用 zotero_query.py 的输出字段如果读取 Better BibTeX 的 JSON必须先做字段映射author 对应 creatorsissued 对应 date。写清楚之后Claude 就不再犯迷糊了。6.7 Claude Code 拒绝执行未授权命令Claude Code 的安全机制是默认征求允许再执行命令。我第一次在对话里说“帮我跑一下 zotero_query.py”它没有直接执行而是问我是否允许。当时我点了允许后面它就记住了。但是如果你点了拒绝后面再想让它执行同一个会话里它可能就会一直犹豫。解决办法有两个一是在权限确认时明确允许这条命令二是把 zotero_query.py 加入允许列表。我建议至少给脚本设置一个只读确认模式不要为了图省事把所有命令都一把梭放开尤其是涉及文件删除、网络请求的脚本还是保留审核比较好。6.8 读不到 PDF 全文的边界问题本地 API 返回的条目里确实没有 PDF 全文内容只有元数据。第一次测试时我让 Claude“总结这篇 PDF 的内容”它说找不到全文我一开始还以为是脚本写错了查了半天才发现这是接口边界。搞清楚边界很重要想让 Claude 读 PDF就得单独处理文件路径去 Zotero 的 storage 目录里找对应附件再交给 PDF 解析工具。这条路径我已经在计划中了但第一步不推荐全部堆进去。先把元数据链路跑通再逐步扩展不然到时候这个报错那个乱码你根本分不清是哪一层的问题。7. 一套链路跑通后我后来又改进了什么脚本跑通到现在我给它加了几个小参数--tag 按标签过滤、--since 按日期过滤、--json 输出原始 JSON 给 Claude 做结构化处理。加参数的方法很简单都是 argparse 的标准玩法但如果一开始就全加进去调试时变量一多反而容易糊涂。我的建议是如果你也想做这个接入第一步务必复刻最小可用版本Zotero 设置打开、脚本能查关键词、Claude 能调用命令、输出格式干净。这个版本哪怕只有 50 行代码都比一个功能复杂但跑不通的“理想版本”有价值。跑通了再慢慢加比如 PDF 全文、笔记子条目、引用生成这些都可以作为第二阶段计划。另外一个小技巧脚本里输出摘要时我限制了长度这是为了让 Claude 的上下文窗口不被无关信息塞满。当你命令输出几百行文本时Claude 反而会抓不住重点。给 AI 的工具输出要像给人看的工作报告一样克制一点。Zotero 接了 Claude Code 之后我现在可以完全在终端里完成文献检索、摘要整理、引用生成、笔记归纳这些事。Zotero 本身还是我收藏和管理文献的库但它不再是一座信息的孤岛。