关于 MCP Zotero
MCP Zotero 将 LLM 接入 Zotero 文献库,供研究者管理文献并在文档中插入引文。它集成了文献检索、论文与 PDF 处理、全文读取及 Word 实时引文插入。
主要功能
- 01搜索文集与文献条目
- 02按 DOI 或元数据添加论文
- 03导入 PDF 并读取全文
- 04附加开放获取 PDF
- 05向 Word 文档插入实时引文
- 06控制删除权限
适用场景
- 01查找来源并获取条目元数据
- 02按 DOI 向 Zotero 文库添加论文
- 03读取 PDF 文本并附加可获取的 PDF
- 04制作带引文的 Word 文档
MCP 相关
这是一个 MCP 服务,向 MCP 客户端开放 Zotero 文库浏览、条目与 PDF 管理及引文工具。它通过 MCP 提供工作流说明,工具无需外部文档即可发现。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @xevos117/mcp-zoteroZOTERO_API_KEY密钥Zotero Web API key (zotero.org/settings/keys) with library read/write and file accessZOTERO_USER_IDYour numeric Zotero user ID (shown on zotero.org/settings/keys); the default library is this user'sZOTERO_LIBRARY_TYPEDefault library type: 'user' (personal library) or 'group'ZOTERO_LIBRARY_IDNumeric group ID; required when ZOTERO_LIBRARY_TYPE is 'group', otherwise defaults to ZOTERO_USER_IDUNPAYWALL_EMAILEmail sent to the Unpaywall API to find open-access PDFs; if unset, OA PDF lookup is skippedUNSAFE_OPERATIONSDeletions allowed: 'none' (default, all blocked), 'items' (delete_items) or 'all' (also delete_collection)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MCP Zotero
注意: 这是一个非官方社区项目,与 Zotero 团队或 Corporation for Digital Scholarship 无关,也未获得其认可或支持。“Zotero”是 Corporation for Digital Scholarship 的注册商标。
一个用于集成 Zotero 的模型上下文协议服务。它让任何大模型都能全面访问你的 Zotero 文库:搜索、整理、通过 DOI 添加论文、导入 PDF、阅读全文内容,以及将实时引文插入 Word 文档。
最初基于 Abhishek Kalia 编写的 mcp-zotero。 此后,本项目经过了大幅重写,采用全新架构,工具数量从 5 个增至 15 个,并增加了引文插入、PDF 管理和 Claude 技能支持。
工作原理
该服务旨在无需外部文档即可供任何大模型使用。连接时,它会通过 MCP 的 instructions 字段发送工作流说明,而每个工具的描述中都包含交叉引用和使用指南。即使此前从未接触过此服务的大模型,也能直接通过工具列表了解完整工作流,从添加论文到生成带引文的 Word 文档。
对于高级用例(PDF 上传策略、引文格式指南、来源透明度),本项目为 Claude.ai Projects 提供了一个 Claude 技能。不过,该技能是可选的:MCP 服务本身已提供完整文档。
本地与远程大模型
| 场景 | MCP 服务 | 是否需要技能? |
|---|---|---|
| 可访问文件系统的大模型(Claude Code、LM Studio 等) | 全部 15 个工具 | 否 |
| 无法访问文件系统的大模型(Claude.ai Projects、Claude Desktop) | API 工具(搜索、添加、元数据) | 是,用于插入引文 |
可访问文件系统的大模型可以直接使用所有工具,包括可读取和写入磁盘上 .docx 文件的 inject_citations。
无法访问文件系统的大模型(包括无法在本地生成文件、但可以连接 MCP 的 Claude Desktop)可以使用附带的 Claude 技能(skills/zotero-skill-mcp-integrations/),该技能可完全在沙盒内执行引文插入。MCP 工具负责处理所有 Zotero API 操作;该技能负责组装文档。
Claude 技能设置(适用于 Claude.ai Projects 和 Claude Desktop)
- 从最新的 GitHub Release 下载技能
.zip - 解压后,将该文件夹作为技能上传到你的 Claude.ai Project
- 该技能可直接在沙盒内插入引文,无需访问本地文件系统
设置
需要 Node.js 22 或更高版本。
此服务已列入官方 MCP Registry,登记名称为
io.github.Xevos117/mcp-zotero(从 2.0.2 之后的首个版本开始),因此,支持注册表的客户端可以从中查找并安装此服务;
以下配置适用于任何 MCP 客户端。
-
获取你的 Zotero 凭据:
# Create an API key at https://www.zotero.org/settings/keys # (enable library read/write + file access) # Then retrieve your user ID: curl -H "Zotero-API-Key: YOUR_API_KEY" https://api.zotero.org/keys/current -
设置环境变量:
export ZOTERO_API_KEY="your-api-key" export ZOTERO_USER_ID="user-id-from-curl" export UNPAYWALL_EMAIL="[email protected]" # Optional: enables OA PDF lookup via Unpaywall export UNSAFE_OPERATIONS="none" # Optional: "none" | "items" | "all" (see below)
指定群组文库
默认情况下,该服务面向你的个人 Zotero 文库(/users/<ZOTERO_USER_ID>/...)。
若要改为指定群组文库,请额外设置两个环境变量:
| 变量 | 取值 | 必填? | 默认值 |
|---|---|---|---|
ZOTERO_LIBRARY_TYPE | user | group | 否 | user |
ZOTERO_LIBRARY_ID | 数字文库 ID | 当类型为 group 时必填;否则回退使用 ZOTERO_USER_ID | — |
群组文库示例:
ZOTERO_API_KEY=...
ZOTERO_USER_ID=12345 # optional for groups: used by get_user_id and per-call library_type="user"
ZOTERO_LIBRARY_TYPE=group
ZOTERO_LIBRARY_ID=6178978 # the group ID
ZOTERO_API_KEY 中的 API 密钥必须有权访问目标群组文库。请前往 https://www.zotero.org/settings/keys 生成密钥或设置密钥权限范围。
如果设置了 ZOTERO_LIBRARY_TYPE=group 却未设置 ZOTERO_LIBRARY_ID,或者文库 ID 不是数字,该服务将拒绝启动。
单次调用的库覆盖
每个工具都接受两个可选参数,可覆盖本次调用的环境变量默认值:
library_type—"user"或"group"library_id— 数字形式的库 ID
解析顺序:单次调用参数 > 环境变量 > 隐式默认值(user、ZOTERO_USER_ID)。library_id 必须是数字。在配置为用户库的服务上将 library_type 覆盖为 group 时,必须提供 library_id;在未提供 library_id 的情况下,将群组服务上的 library_type 覆盖为 user,则会使用 ZOTERO_USER_ID。
请注意,单次调用覆盖设置可让 LLM 访问 API 密钥有权限访问的任何库。请将密钥的权限范围限制为你希望开放的库;删除操作仍受 UNSAFE_OPERATIONS 限制。
这样,一个 MCP 实例就能在无需重启的情况下指向多个库(例如,一个暂存群组和一个最终输出群组):
// First call targets the staging group
{
"tool": "add_items",
"args": {
"items": [...],
"library_type": "group",
"library_id": "5597114"
}
}
// Second call targets DART-output (different group)
{
"tool": "add_items",
"args": {
"items": [...],
"library_type": "group",
"library_id": "6178978"
}
}
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
ZOTERO_API_KEY | 是 | Zotero Web API v3 的 API 密钥。请在 zotero.org/settings/keys 创建密钥,并授予库读写权限和文件访问权限。 |
ZOTERO_USER_ID | 是 | 你的 Zotero 数字用户 ID。可通过 curl -H "Zotero-API-Key: KEY" https://api.zotero.org/keys/current 获取。 |
UNPAYWALL_EMAIL | 否 | 用于 Unpaywall API 请求的电子邮件地址(速率限制政策)。启用 add_items_by_doi 和 find_and_attach_pdfs 中的 OA PDF 查找功能。如果未设置,则会静默跳过 OA PDF 功能。 |
UNSAFE_OPERATIONS | 否 | 控制破坏性操作(删除)。请参阅下方的不安全操作。默认值:none(阻止所有删除)。 |
不安全操作
默认情况下,MCP 服务不允许任何删除操作。这是一项安全措施,可防止 LLM 意外删除库中的条目或分类。
要启用删除功能,请将 UNSAFE_OPERATIONS 环境变量设为以下值之一:
| 值 | delete_items | delete_collection | 使用场景 |
|---|---|---|---|
none(默认) | 已阻止 | 已阻止 | 安全模式 — 无法执行删除 |
items | 允许 | 已阻止 | 允许删除条目,但保护分类结构 |
all | 允许 | 允许 | 完全访问 — 可删除条目和分类 |
重要说明:
- 如果未设置
UNSAFE_OPERATIONS、其值为空或无法识别,则默认值为none。 - 值不区分大小写(例如,
ALL、Items、NONE均有效)。 delete_items会永久删除条目:Zotero Web API 的多条目 DELETE 不会将其移至 Zotero 回收站,因此无法从桌面客户端恢复。delete_collection仅移除分类(文件夹)——其中的条目不会被删除,仍保留在库中。all值同时包含条目和分类删除权限,因为管理分类本身就需要条目级访问权限。
配置示例:
{
"mcpServers": {
"zotero": {
"command": "npx",
"args": ["-y", "@xevos117/mcp-zotero"],
"env": {
"ZOTERO_API_KEY": "YOUR_API_KEY",
"ZOTERO_USER_ID": "YOUR_USER_ID",
"UNSAFE_OPERATIONS": "items"
}
}
}
}
与 Claude Desktop 集成
安装为 Claude Desktop 扩展(一键安装)
- 从最新版本下载
mcp-zotero.mcpb(从 2.0.2 之后发布的第一个版本开始提供)。 - 使用 Claude Desktop 打开该文件(macOS 或 Windows,例如双击),并在安装对话框中确认。
该扩展包本身不受平台限制(
manifest.json中列出了 macOS、Windows 和 Linux,CI 也会在 Linux 上运行),因此其他兼容 MCPB 的客户端也可以安装。 - 填写你的 Zotero API 密钥和 Zotero 用户 ID(见设置)。可选设置:文库类型和 群组 ID(适用于群组文库)、用于 Unpaywall(开放获取 PDF 查找)的邮箱,以及允许哪些删除操作 (默认:无,见不安全操作)。
扩展包含服务及其所有依赖项,因此无需运行 npm install。它需要 Node.js 22 或更高版本
(清单中的 compatibility.runtimes.node):根据 MCPB 文档,Claude Desktop 会使用随应用附带的运行时
运行 Node.js 扩展。API 密钥被声明为敏感设置(输入内容会被隐藏,并由客户端安全存储)。除非你在
扩展设置中更改 允许的删除操作,否则删除功能会保持禁用状态。
该扩展仅包含 MCP 服务:skills/ 中的 Claude skills(在沙盒中注入引用、科学写作)
需从同一版本中的 .zip 文件单独安装,具体请参阅
Claude Skill 设置。
手动配置(适用于任何 MCP 客户端)
将以下内容添加到 Claude Desktop 配置(或其他 MCP 客户端对应的文件)中:
{
"mcpServers": {
"zotero": {
"command": "npx",
"args": ["-y", "@xevos117/mcp-zotero"],
"env": {
"ZOTERO_API_KEY": "YOUR_API_KEY",
"ZOTERO_USER_ID": "YOUR_USER_ID",
"UNPAYWALL_EMAIL": "YOUR_EMAIL"
}
}
}
}
与 Claude Code 集成
claude mcp add zotero -e ZOTERO_API_KEY=YOUR_API_KEY -e ZOTERO_USER_ID=YOUR_USER_ID -- npx -y @xevos117/mcp-zotero
根据需要添加 -e UNPAYWALL_EMAIL=... 或 -e UNSAFE_OPERATIONS=items,并添加 --scope user,使服务
在每个项目中都可用(默认的 local 作用域仅适用于当前项目)。从本仓库的克隆目录中运行
npx tsx src/server.ts,则会改为从源代码运行服务(见开发)。
可用工具
浏览文库
| 工具 | 描述 |
|---|---|
get_collections | 列出所有文集(文件夹),包括键、名称和父级关系 |
get_collection_items | 获取指定文集中的条目,包括键、标题、作者和日期 |
search_library | 按查询词搜索,或按字段(日期、标题等)排序列出条目 |
get_items_details | 批量获取多个条目的元数据——返回所有类型特有字段(bookTitle、proceedingsTitle、university 等)、authors 字符串和结构化的 creators;不在文库中的键会列在 not_found 中 |
get_item_fulltext | 通过 Zotero 的全文索引获取 PDF 附件的全文内容 |
添加内容
| 工具 | 描述 |
|---|---|
add_items_by_doi | 通过 DOI 添加论文,并自动解析元数据。通过 Unpaywall 自动附加开放获取 PDF |
add_items | 直接使用元数据添加条目——支持全部 37 种 Zotero 条目类型(书籍、论文、报告等),支持批量操作 |
create_collection | 创建新文集,可选择嵌套在某个父级文集下 |
import_pdf_to_zotero | 从 URL 下载 PDF,上传至 Zotero 存储,并自动索引全文 |
find_and_attach_pdfs | 通过 Unpaywall 批量查找开放获取 PDF 并自动附加(按条目键或文集查找) |
add_linked_url_attachment | 为现有条目附加 URL,或创建独立链接 |
删除内容
| 工具 | 描述 |
|---|---|
delete_items | 每次调用最多永久删除 50 个条目(不会移至 Zotero 回收站)。需要设置 UNSAFE_OPERATIONS=items 或 all |
delete_collection | 删除文集(文件夹)。其中的条目会保留。需要设置 UNSAFE_OPERATIONS=all |
引用与文档
| 工具 | 描述 |
|---|---|
inject_citations | 将实时 Zotero 引用插入 Word 文档。支持 APA、IEEE、Vancouver、Harvard、Chicago。输出文件保存在与输入文件相同的文件夹中,并添加 _cited 后缀(例如,paper.docx → paper_cited.docx) |
get_user_id | 返回已配置的 Zotero 用户 ID |
开发
npm install
npm run build # Compile TypeScript
npm test # Unit and per-tool tests (vitest, fetch faked, ~1000 tests)
npm run test:e2e # Built server over stdio against a local fake Zotero API
npm run smoke # Quick stdio smoke test of the built server (user + group library)
npm run bundle # Claude Desktop extension: dist/mcp-zotero.mcpb (production dependencies only)
npm run smoke -- --bundle dist/mcp-zotero.mcpb # smoke test of the unpacked bundle, started from its manifest
npx tsx src/server.ts # Run directly without building
测试
| 层级 | 命令 | 运行时机 | 覆盖范围 |
|---|---|---|---|
| 单元测试 / 每个工具 | npm test | 每个 PR(Node 22、24、26) | 通过真实 MCP 客户端测试每个工具;在 fetch 层模拟 Zotero;根据官方 CSL 架构验证生成的 .docx 文件,并使用 citeproc-js 进行渲染(test/helpers/docx-validate.ts) |
| E2E + 冒烟测试 | npm run test:e2e、npm run smoke | 每个 PR | 通过 stdio 测试已编译的服务、用户库和群组库 |
| 实时测试 | npm run test:live(工作流,与 Agent 冒烟测试共用) | 来自此仓库的 PR、main、每周(周五)及手动运行 | 使用专用测试账户调用真实的 Zotero Web API(test/live);仅在设置了 ZOTERO_TEST_API_KEY 时运行 |
| Agent 冒烟测试 | 工作流,实时测试套件通过后运行 | 来自此仓库的 PR、手动运行(例如,合并后在 main 上运行) | Claude Code Agent 像用户一样使用服务,并遵循已纳入版本控制的技能 .claude/skills/test-mcp-zotero:在每种样式中检查 inject_citations ⇄ inject.js 的一致性、固定边缘情况,并针对 PR 的变更进行最多 5 个探索性场景测试。工作流会设置 MCP 服务、工具集和防护钩子(Bash 允许列表、删除策略、审计日志);本地运行使用相同组件(test/live/agent/README.md)。判定结果来自 test/live/verify-claims.mjs,而非 Agent;每次运行都会生成一份 Job Summary(判定结果、场景、探索性发现、摩擦点、轮数/成本/耗时),并持续更新 PR 上的一条评论;两者都会清除所有可用于识别测试账户的信息 |
| Word | 手动 | 每次发布 | test/WORD_CHECKLIST.md:使用 Zotero 插件在 Word 中打开插入了引用的文档 |
每个测试用例都列在 test/TEST_CASES.md 中。
本地运行实时测试仅使用 ZOTERO_TEST_* 变量,绝不使用你的 ZOTERO_API_KEY:
ZOTERO_TEST_API_KEY=... ZOTERO_TEST_USER_ID=... [email protected] npm run test:live
针对个人文库时,添加 ZOTERO_LIVE_SAFE_MODE=1:测试套件只会创建名称为 mzt-<runId>… 且带有标签 mzt-run:<runId> 的条目和分类,只会删除这些条目,并跳过分类删除和群组写入。专用测试账户会通过名为 __mzt_disposable__ 的分类进行标记。
依赖项每月由 Claude Code Agent 更新(工作流,技能 .claude/skills/deps-update);仅包含补丁更新的 PR 会在所有必需检查通过后自动合并,其他 PR 则等待审核。GitHub Actions 版本由 Dependabot 更新。
CI 设置(仓库所有者)
| 环境 | 密钥 | 变量 |
|---|---|---|
zotero-live(实时测试、Agent 冒烟测试) | ZOTERO_TEST_API_KEY、ZOTERO_TEST_USER_ID、ZOTERO_TEST_USERNAME、ZOTERO_TEST_GROUP_ID(可选)、UNPAYWALL_EMAIL | ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_ID |
claude-deps(依赖 Agent) | — | 相同的四个 ANTHROPIC_* 变量(联邦规则可以不同) |
这些 Agent 使用 Anthropic 工作负载身份联合(GitHub OIDC,无需 API 密钥)向 Claude API 进行身份验证。建议每个环境使用一条联邦规则,并尽可能缩小规则范围:
| 规则适用对象 | subject(精确匹配,不含 *) | claims(精确字符串键值对) | condition(CEL) |
|---|---|---|---|
zotero-live | repo:Xevos117/mcp-zotero:environment:zotero-live | repository_id: 1152178663、repository_owner_id: 86290818 | claims.job_workflow_ref.startsWith("Xevos117/mcp-zotero/.github/workflows/claude-agent-smoke.yml@")(PR 运行使用 PR ref) |
claude-deps | repo:Xevos117/mcp-zotero:environment:claude-deps | repository_id: 1152178663、repository_owner_id: 86290818、job_workflow_ref: Xevos117/mcp-zotero/.github/workflows/deps-update.yml@refs/heads/main | — |
Claims 是精确匹配的字符串键值对(只有 subject_prefix 支持末尾带 *),因此,像“此工作流在任意 ref 上运行”这样的前缀必须写成 CEL condition,如上所示;精确的 job_workflow_ref(claude-deps,仅限 main)可以作为普通 claim。
受众为 https://api.anthropic.com。除非 subject 以 * 结尾,否则 subject 必须精确匹配;使用环境的作业会获得 OIDC subject repo:Xevos117/mcp-zotero:environment:<environment>,因此,为分支或 PR subject 编写的规则永远不会匹配。使用数字 ID(而非名称)可以避免仓库或账户重命名或重新创建后匹配成功。
zotero-live 的权衡:Agent 冒烟测试需要“任意 ref”条件才能在拉取请求上运行,但这也会接受推送到此仓库任意分支的该工作流文件修改副本(只有有写入权限的人才能推送)。将其固定为精确 claim job_workflow_ref: Xevos117/mcp-zotero/.github/workflows/claude-agent-smoke.yml@refs/heads/main 可以弥补这一漏洞,但会禁用 PR 上的 Agent 冒烟测试(之后它只会在从 main 手动运行时执行)。
所有者的其他设置:
- Zotero 测试账户需要一个名为
__mzt_disposable__的集合。 - 仓库设置:“允许自动合并”和“允许 GitHub Actions 创建并批准拉取请求”(依赖工作流会使用
GITHUB_TOKEN创建 PR)。将规则集的必需批准数保持为 0:依赖 PR 的自动合并依赖此设置,这也是第二项设置可以接受的原因。这是经过权衡的设置:它允许工作流创建 PR(必需)并批准 PR(此处没有任何工作流会这样做);如果将来要求批准,此设置会允许工作流批准自己的 PR,因此应与任何审批要求一并重新评估。 - 任何工作流都不会使用 GitHub App(这些 Agent 使用工作负载身份联合向 Anthropic 进行身份验证,并且在 GitHub 上仅使用
GITHUB_TOKEN;Agent 只有只读权限)。如果 Claude GitHub App 已安装在此仓库上,请将其卸载。 - 在联邦规则所用的 Anthropic 工作区上设置每月支出上限:这是 Agent 费用的实际上限。
- 剩余风险:持有 OIDC 令牌的 Agent 冒烟测试作业也会运行根据 PR 代码构建的 MCP 服务(这是它的测试内容)。该作业只会针对仓库所有者或机器人发起的同仓库 PR 运行,令牌绑定到
zotero-live环境,工作区支出上限则可限制任何滥用造成的费用。 - 堆栈合并后需要通过的检查:
test (node 22)、test (node 24)、test (node 26)、live-tests、agent-smoke。
发布
- 更新
CHANGELOG.md(将Unreleased移至新版本),以及package.json、server.json(version和packages[0].version)和manifest.json中的版本(如果这些版本不一致,npm test会失败)。 - 确保
main上的 CI、在线测试和 Agent 冒烟测试均通过。 - 在由候选版本注入的文档上运行手动 Word 检查清单,并将结果记录在其日志中。
- 在首次发布包含 Claude Desktop 扩展的版本之前(以及每当
manifest.json或 Node.js 要求发生变化时):使用npm run bundle构建扩展,在实际的 Claude Desktop(macOS 或 Windows)中安装一次dist/mcp-zotero.mcpb,填写测试密钥和用户 ID,并检查是否显示全部 15 个工具,以及get_collections是否能正常响应。 - 发布 GitHub 版本:发布工作流会运行测试、发布到 npm、将
server.json发布到 MCP 注册表,并附上技能压缩包和 Claude Desktop 扩展(mcp-zotero.mcpb)。发布标签必须是版本号(例如2.0.3):注册表和打包任务会检出该标签,如果package.json中的版本不一致,则会失败。 - 如果只有
mcp-registry任务失败,请在运行页面中使用 Re-run failed jobs:Re-run all jobs 会在发布到 npm 时停止(该版本已存在),因此不会运行到注册表发布步骤。
使用 MCP Inspector 调试
npx @modelcontextprotocol/inspector npx tsx src/server.ts
许可证
MIT - 详情请见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。