pydantic-zotero-mcp
pydantic-zotero-mcp
一个为 AI 代理提供 Zotero 库只读访问的 MCP 服务器——支持搜索、条目元数据、集合、标签、研究者自己的笔记,以及所附 PDF 的索引全文。
需求见 PRD.md。
状态:M1(读取核心)+ M2(全文)已实现。 引文格式化和导出(M3)、提示词(M4)和写入工具(M5)尚未构建——见尚未实现。
安装
作为工具安装(pipx)
将 zotero-mcp 命令安装到其独立的隔离环境中:
pipx install pydantic-zotero-mcp # or: pipx install /path/to/checkout
zotero-mcp --help安装到其他项目的环境中
uv add pydantic-zotero-mcp # or: uv pip install pydantic-zotero-mcp在此服务器上进行开发
git clone https://github.com/jmlon/pydantic-zotero-mcp
cd pydantic-zotero-mcp
uv sync # creates ./.venv from this project's own lock file
uv run pytest
uv run ruff checkRelated MCP server: zotero-cli-cc
配置
从 https://www.zotero.org/settings/keys 获取一个只读 API 密钥和你的数字用户 ID。库 ID 是数字,不是你的用户名。
export ZOTERO_API_KEY=...
export ZOTERO_LIBRARY_ID=123456 # numeric
export ZOTERO_LIBRARY_TYPE=user # or group变量 | 默认值 | 用途 |
| — | Web API 密钥(除非 |
| — | 数字形式的用户或群组 ID |
|
|
|
|
| 改为读取 Zotero 7 桌面版 API:无需密钥、无速率限制、只读 |
|
| 为 M5 预留;目前尚无写入工具 |
|
| 默认全文上限;单次调用的 |
|
| 为 M3 预留 |
|
| 上游请求并发上限(Zotero 要求 ≤ 4) |
|
|
|
|
| HTTP 绑定地址 |
|
| HTTP 端口 |
|
| HTTP 挂载路径 |
| — | Bearer 令牌;HTTP 模式下必填 |
CLI 标志会覆盖环境变量。
运行
安装后,zotero-mcp 就是入口点——无需解释器路径、无需 python -m、无需操心工作目录,这正是 MCP 客户端的 command: 所期望的:
# stdio (default) — an agent launches this as a subprocess
zotero-mcp
# streamable HTTP — requires ZOTERO_MCP_AUTH_TOKEN
ZOTERO_MCP_AUTH_TOKEN=secret zotero-mcp --transport http --port 8000
# read the Zotero desktop app instead of the web API
zotero-mcp --local从代码检出目录运行,无需安装,python -m zotero_mcp 同样可用:
uv run python -m zotero_mcp以 --transport http 启动且未提供令牌时,程序会以退出码 2 结束,而不是提供未认证的服务:这是一条通往个人库的只读通道。
内存模式(嵌入到代理进程中)
无需子进程、无需套接字。设置通过注入传入,因此宿主环境无需环境变量:
from fastmcp import Client
from zotero_mcp import ZoteroSettings, create_server
server = create_server(
ZoteroSettings(
api_key=key,
library_id="123456",
library_type="user",
)
)
async with Client(server) as client: # lifespan opens here
result = await client.call_tool("search_items", {"query": "attention"})
print(result.structured_content["items"]) # dict; result.data is a model导入 zotero_mcp 不会产生任何副作用——不读取配置、不构建客户端、不发起网络请求——这正是嵌入式使用所必需的。有一个测试专门验证这一点。
通过入口点发现
对于通过 Python 入口点发现捆绑 MCP 服务器的宿主应用,此包在 deep_research.mcp_servers 组中声明了一个入口点:
[project.entry-points."deep_research.mcp_servers"]
zotero = "zotero_mcp:build_server"build_server() 不接收参数,从环境变量读取设置——将此包安装到宿主环境中后,宿主即可按名称 zotero 解析并进程内运行该服务器,无需从配置文件按路径导入任何内容。
一个针对自动化宿主的调优提示:此服务器的默认全文上限为 100,000 字符(约 25–30k token,针对单次 get_item_fulltext 调用),对交互式使用来说很充裕,但对一个在 token 预算内进行大量调用的代理来说就太大了——请按调用传入更小的 max_chars,或调低 ZOTERO_FULLTEXT_MAX_CHARS。
工具
工具 | 用途 |
| 库规模、模式、权限。廉价的定向调用——请优先使用 |
| 主要入口点。 |
| 最近添加的条目,最新在前 |
| "我是否已有此条目?"——按 DOI、ISBN、arXiv ID 或 key 查询 |
| 完整元数据; |
| 附件和笔记,每个附件标注 |
| 研究者自己的笔记,已去除 HTML |
| 已索引的附件文本;从父条目解析到附件 |
| 嵌套集合树 |
| 某个集合中的条目 |
| 标签词汇表,可选前缀过滤 |
资源:zotero://library/info、zotero://collections、zotero://items/{key}、zotero://items/{key}/fulltext、zotero://collections/{key}/items、zotero://schema/item-types、zotero://schema/item-types/{type}/fields。
设计说明
投影是关键。 原始 Zotero JSON 每个条目约 1 KB 的 links、library、meta 和空的类型字段。zotero_mcp/projection.py 将一页 25 个条目从约 6,100 个估算 token 缩减到约 2,400 个(原始量的 39%),低于 PRD 的 4,000 预算。CompactModel 在序列化时丢弃空字段。
pyzotero 是同步且有状态的。 Zotero.request 和 Zotero.links 在每次调用时被覆盖,Total-Results 在调用后从实例上读回——因此一个共享客户端在并发使用时可能会报告另一次调用的总数。gateway.py 维护一个最多 ZOTERO_MAX_CONCURRENCY 个客户端的池,每次操作取出一个,并在持有该客户端的同一个工作线程内读取响应元数据。每次调用都通过 anyio.to_thread.run_sync 执行,因此事件循环永远不会阻塞。
退避是 pyzotero 的职责。 pyzotero ≥ 1.13 已经处理 Backoff / Retry-After 并在内部重试 429,因此网关不会重新实现。它只额外增加了对瞬时传输错误和 5xx 故障的有界 3 次重试。
不会静默截断。 搜索会报告 total_matched、truncated 和 next_start;全文会报告 total_chars 和 truncated。
结果是候选,不是定论(PRD D3)。find_item_by_identifier 返回 matched_on(key / doi / title / identifier / none)以及置信度和所有合理候选——预印本及其正式发表版本都会保留。由调用方自行筛选。
与 PRD 的偏差
值得了解,因为每一项都是在实现过程中做出的判断:
没有模块级
mcp对象。 PRD 7.2 同时要求模块级mcp = create_server()和没有导入时副作用。这两者相互冲突:构建服务器需要验证配置,因此模块级实例会在任何没有 Zotero 环境变量的机器上抛出ImportError,并破坏它本应支持的内存模式。只存在create_server()/build_default_server()。写入工具将按条件注册,而非
enabled=False。 PRD 5.5 指定了@mcp.tool(enabled=False),但 FastMCP 3.x 没有enabled关键字参数,而且一个被禁用但仍列出的工具仍然消耗上下文。当 M5 落地时,写入工具将直接不注册,除非ZOTERO_ALLOW_WRITES=true。此服务器面向 FastMCP 3.x。3.x 的两个特性塑造了这里的代码:装饰器中已移除
enabled,且result.data是生成的 pydantic 模型,而result.structured_content是普通字典——测试断言后者,这也同时验证了传输中的空值省略。has_fulltext是三值的。 PRD 6 将其类型定为bool,但确定父条目的该值需要对每个条目单独发起一次子条目请求,这会使 25 条搜索变成 26 次请求。当条目完全没有子条目时为False,对附件以及调用get_item(include_children=True)之后为True/False,无法确定时为null(省略)。ItemSummary.num_children提供了廉价的信号。find_item_by_identifier返回CitationMatch,而非ItemSummary | None。 这是 D3 的推论——旧签名恰恰做了那个决策移交给客户端的身份判断。matched_on在 PRD 的四个值之外增加了key和identifier,以区分精确的 key 命中与弱搜索命中。list_recent_items(since_days=...)在本地过滤。 Zotero 没有服务端日期过滤器,因此窄时间窗口可能返回少于limit的条目;响应的hint会说明何时发生了这种情况。
测试
uv run pytest # 80 passed测试套件使用 FastMCP 的内存传输,针对一个复现 pyzotero 从实例读取元数据行为的 FakeZotero。无网络、无子进程、无真实凭据。覆盖率:schema 表面、投影与 token 预算、分页与截断报告、全文上限与父条目解析、匹配召回(预印本/正式版成对返回)、错误信息质量、资源模板验证(包括遍历尝试)、配置验证、CLI 优先级、网关重试/缓存,以及一个导入纯净性检查——如果导入包时触达网络则测试失败。
尚未实现
M3 —
format_citation、format_bibliography、export_itemsM4 — 四个提示词(
literature_review、find_related_work、check_citations、summarize_reading)、Logfire 插桩M5 — 写入工具(
create_item、update_item_fields、add_item_tags、add_items_to_collection、create_note),采用带版本检查的 PATCH 语义。删除操作永久不在范围内。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceA lightweight MCP server that connects AI agents to a local Zotero library for paper management and metadata retrieval. It enables users to search titles and abstracts, browse collections, and automatically ingest papers via arXiv ID or DOI with PDF attachments.815MIT
- AlicenseNot gradedqualityAmaintenanceMCP server that exposes 45 tools for Zotero reference management, enabling AI agents to read/write items, search, extract PDF text, and manage workspaces via the Zotero CLI.198AGPL 3.0
- AlicenseNot gradedqualityAmaintenanceMCP server that lets AI assistants search, create, organize, and cite from a Zotero library.3MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that connects AI assistants to your Zotero library, enabling full-text PDF extraction and metadata search.MIT
Related MCP Connectors
Remote MCP server for full read/write access to a Zotero library
Agentic search over your Dewey document collections from any MCP-compatible client.
An MCP server that gives your AI access to the source code and docs of all public github repos
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmlon/pydantic-zotero-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server