pubmed-mcp
Provides tools for searching PubMed via NCBI E-utilities, counting matching records, fetching abstracts by PMID, and retrieving linked records in PMC and other NCBI databases.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pubmed-mcp Search PubMed for recent papers on tooth resorption and fetch their abstracts."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pubmed-mcp
单文件 PubMed MCP 服务(stdio),裸打 NCBI E-utilities,不经过 pubmed-client 之类的中间层。
现在也带 pip install 入口:装完直接敲 pubmed-mcp 就是服务。
当前版本为 1.4.0〔本项目自订版本号;来源:pyproject.toml 的 project.version〕,新增系统综述检索助手(check_recall/mesh/diff/export)与可选检索留痕,并修复 issue:引号短语开头误报警告。既有基础工具的默认行为保持兼容,验证范围见下方记录。源码发行包附带文档、测试及夹具;wheel 是运行安装包,不附带开发测试材料。
本轮演练修复与验收见 正畸与深度学习修复记录,包含测试结果、首测失败原因与未验证范围。发布前安装包验证另记于 发布检查〔版本来源:pyproject.toml;本项目自订文档命名〕。
它存在的唯一理由:把「查不到」和「没有」分开。 文献工具最常见的失败是静默——参数被吞掉、词被丢弃、编码不对、请求根本没跑完, 而输出看起来完全正常,于是你拿一个无意义的数字去写论文。本工具的做法是能拦就拦, 拦不住的在输出里把动过的手脚说出来。
代码注释里保留了大量
〔实测 日期〕、〔推算〕、〔本项目口径〕、【已作废+理由+日期】标记。 读代码时请按那些标记理解证据强度,不要把带推算/未核实的行当事实引用。
快速开始(三条命令)
pip install git+https://github.com/rsvsv/pubmed-mcp.git
pubmed-mcp --check-key--check-key 应返回 rc=0 并打印 key 形状/限速档/依赖版本。mcp 1.x 与 2.x 都支持;要是它报
拿不到 MCP 服务类,说明你环境里的 mcp 既不是一代也不是二代,pip install "mcp>=1.26,<3" 即可
(缘由见下面「版本要求」与 docs/mcp-sdk-v2.md)。
然后告诉 Claude Code 去哪儿找它 —— 在 ~/.claude.json 里加:
{
"mcpServers": {
"pubmed": { "command": "pubmed-mcp", "args": [] }
}
}在 Claude Code 里跑 /mcp,确认 pubmed 那一行是连上的,不是 ✘。
上面那段 "command": "pubmed-mcp" 只在「命令真能在 PATH 里被找到」时成立。
〔本会话 2026-11-11 在作者机器实测〕分三种情况:
装进虚拟环境但没激活 → 裸命令找不到(实测
command -v pubmed-mcp无输出)。Claude Code 不会替你先激活 venv,所以配置里必须写绝对路径: Windows<venv>\Scripts\pubmed-mcp.exe,类 Unix<venv>/bin/pubmed-mcp。 不知道落在哪就跑python -c "import sys;print(sys.executable)"看你在哪个解释器里装的。装进系统 Python(非
--user) → 作者机器上那个Scripts目录确实在 PATH 里 (实测 PATH 第 20 项),所以裸命令可用。你的机器不一定,自己确认:where pubmed-mcp(cmd)或command -v pubmed-mcp(bash)。pip install --user→ 落点是%APPDATA%\Python\Python<XY>\Scripts, 这个目录默认在不在 PATH 里,本仓库未核实(作者机器上该目录不存在,测不了)。 别照抄这一种,要么用上面两种,要么先用where pubmed-mcp确认命令敲得到。
零安装路线(下面那节)不受这个影响,因为配置里写的就是绝对路径。
不想装包也能用(零安装,直接跑文件):
git clone https://github.com/rsvsv/pubmed-mcp.git
cd pubmed-mcp
pip install -r requirements.txt
python pubmed_mcp.py --check-key配置里就写绝对路径:
{
"mcpServers": {
"pubmed": { "command": "python", "args": ["-I", "/ABSOLUTE/PATH/TO/pubmed_mcp.py"], "env": {} }
}
}⚠️ 装依赖前先看清用的是哪个解释器
-I 是 Python 的隔离模式,等价于 -E -s:忽略 PYTHONPATH 与「用户」site-packages
(也就是 pip install --user 的落点),但照常读 venv 与系统 site-packages。
〔本会话实测 2026-11-10:作者机器上 python -I -c "import sys;print(sys.path)" 的 sys.path
里确实没有 AppData\Roaming\Python\Python313\site-packages;而 -I 仍能 import mcp,
因为那份 mcp 装在系统 site-packages。〕
后果:依赖必须装进「配置里那个 command 所指向的解释器」里。用 pip install --user 装、
再配 "command": "python", "args": ["-I", ...],服务会在 Claude Code 里静默起不来。
虚拟环境里请去掉 -I,或者用 venv 内那个 python 的绝对路径。
也可以用命令行加(这条本仓库未在本机验证过:作者机器上 claude 不在 PATH 里,
跑不了 claude mcp add --help;参数形状随版本变过,动手前先自己 --help 对一下):
claude mcp add pubmed -- pubmed-mcpRelated MCP server: PubMed MCP Server
版本要求
后续更新:已加入 自动回归配置,下面“本仓库没有 CI”为历史状态,现已作废。矩阵是测试目标,实际通过情况以对应提交的 Actions 结果为准;本地运行不能代替远端运行。
requires-python = ">=3.10"。〔本项目口径:源码用了 bool | str 联合类型标注,3.10 以下在
运行时求值会失败。但作者机器只有 3.13,本仓库没有 CI,所以这条下限错了也不会有人发现——
〔推算〕,别当已验证事实。〕
依赖:Python 标准库 + mcp(FastMCP 随它一起装)+ anyio。HTTP 走 stdlib urllib,
当前还直接使用 pydantic 的严格类型(由 MCP 依赖安装)。旧句“除这两个之外没有别的第三方依赖”已作废:源码后来增加了严格参数校验〔修订记录:2026-11-11;依据:pubmed_mcp.py 的 pydantic import〕。
mcp 的区间是 >=1.26,<3:1.x 和 2.x 都实测支持,3.x 没验过所以挡住。
下界是量出来的,不是拍的:〔实测 2026-11-11,三个干净 venv 配当前 pydantic 2.14.3〕mcp 1.2.0 与
1.21.0 都在 import 阶段就炸(cannot import name 'eval_type_backport' from 'pydantic._internal._typing_extra'),1.26.0 才 IMPORT_OK。原先写 >=1.2 等于承诺了一个
跑不起来的下界——那种装法看着成功、一跑就 traceback。
〔实测 2026-11-10,干净 venv〕原先只写 >=1.2 时,pip install git+https://… 会解析到
mcp 2.3.0,而 2.x 里 mcp.server.fastmcp 这个模块名已经没了 —— 装完第一次运行就
ModuleNotFoundError: No module named 'mcp.server.fastmcp'。作者本机是 1.29.0,
这类坑在作者机器上永远复现不出来,所以本仓库现在的验收一律用不带系统 site-packages 的
干净 venv 跑 pip install。
源码里因此加了一层 SDK 兼容层(1.x 拿 FastMCP,2.x 拿 MCPServer),两条通路各跑过完整
--probe:两代都是 0 失败〔实测 2026-11-11,mcp 1.30.0 与 2.3.0 各一轮,串行跑、中间隔 8 秒,
避免两轮在限速上互相干扰。〕
这里故意不写断言条数,也故意不写请求数:两个数都是「每加一条断言就变」那种,写死过一次就注定过期
(下面「自检」一节同此口径)。这句自己就过期过一回:此处原先写着「请求数仍是 89 次」,
后来又加了联网的冒烟断言(文档示例能不能真查到东西,光离线测不出来),89 已经不是实际值——
同一段文字里一边说「不写死条数」、一边写死另一个数,正是本 README 批评过的形状。
现在的条数、请求数与它们的变化链记在 docs/release-delta.md 的验收表里。
其中四条专门走 SDK 的工具包装层(search / count / fetch_abstracts / links 各一条)。
为什么值得为它们各写一条:2.x 会把非 ToolError 异常的文本剥掉,这条通路一旦退化,四个工具的
「为什么被拦」会同时缩成一句没有信息的 Error executing tool xxx,而探针其余断言都直调协程、
结构上看不见这一层。〔实测依据见 docs/mcp-sdk-v2.md〕
【已作废 2026-11-11,本会话 A/B 实测推翻】这一段原先写「v2 变了的那些(客户端字段改
snake_case、serverInfo.version 变空串、多 structuredContent)都在客户端侧,本服务不读,
所以不影响」。它漏了服务端这一手:2.x 会把非 ToolError 异常的文本从返回结果里剥掉。
同一个 sort="journal" 拦截,1.30.0 下调用方拿到 323 字符的完整解释,未修的 2.3.0 只拿到
27 字符的 Error executing tool search —— 本仓库的主承诺「失败绝不静默」就在新用户默认走的那条
路上被打穿了。现在 NcbiError 继承当前那代 SDK 的 ToolError,两代拿到的文本逐字相同;
--probe 里补了一条走包装层的断言当回归锁(其余断言都直调协程,结构上看不见这一层)。
原话留着不删,是因为「我不读那个字段,所以那个改动与我无关」这种推理会再犯第二次。
细节与逐字签名见 docs/mcp-sdk-v2.md。
新环境里 pip install 会拿范围内的最高版(眼下是 mcp 2.3.0)。想固定走 1.x:
pip install "mcp<2"。两代本仓库都跑过全量 --probe,但你的其它 MCP 应用如果要求
mcp<2,pip 会照它的约束留手——这也是上界写成 <3 而不是钉死某一版的原因。
作者开发时实测 2026-11-08 的版本是 mcp 1.29.0 / anyio 4.14.2 / pydantic 2.13.4〔实测,本机
importlib.metadata;未在跨版本环境复核〕。
NCBI API key(可选)
不设 key 也能跑,只是限速低一档。读取顺序:
环境变量
NCBI_API_KEY文件
~/.ncbi_api_key文件
~/.ncbi_api_key.txt都没有 → 匿名档
限速:有 key 10 次/秒,无 key 3 次/秒〔本项目口径:这是 NCBI 公布的档位, 作者没有逐字核对过官方页面,代码里也没做过计时测量,所以标口径不标实测〕。
key 文件的编码不用你操心。Windows 上 people 建这个文件默认拿到的往往是
PowerShell 5.1 的 UTF-16LE + BOM 或记事本的 UTF-8 带 BOM,两者都会让早期版本
抛裸 UnicodeDecodeError,或者让 混进 key( 不是空白,.strip() 剥不掉,
于是 NCBI 判 key 无效、而错误文本里看不出是编码的锅)。现在按 BOM 判编码、再兜一层
utf-8-sig、最后 latin-1 保命。本仓库不含任何 key,~/.ncbi_api_key* 也被 .gitignore 挡着。
用 --check-key 自检(它不发任何网络请求——但它是跑在这个文件里的:文件顶部要先 import 到
MCP 服务类,所以 mcp 没装齐时你会先看到兼容层那句 ImportError(那句里直接给了该跑的安装命令),
看不到 key 报告。这不是 bug,是「连依赖都没装对」时唯一有用的那句话):
python pubmed_mcp.py --check-key它会报告 5 组信息:key 的形状(只说长度/有没有混进文字,不打印值)、限速档位、
它实际读到的 key 文件绝对路径与该文件的编码、NCBI_EMAIL、以及 mcp/anyio/pydantic 版本。
把「放错位置的人只会看到 (无)」这个坑堵上了——注意输出里那行路径带你自己的用户名,
贴到 issue 前先知道这件事。
NCBI_EMAIL(可选):NCBI 建议请求里带联系邮箱,设了就会随每个请求发出〔NCBI 的 courtesy
建议,作者未逐字核对原文页面——〔未核实〕〕。
工具
八个 @mcp.tool()〔本 README 逐字对照源码装饰的定义数出,2026-11-11〕:
工具 | 作用 | 要点 |
| 检索,返回命中数 + 每条的 PMID/日期/期刊卷页/标题/作者/DOI/PMC |
|
| 只问「这个主题有多少篇」,不取记录 | 最省请求;查询被改写时印出「NCBI 实际执行」 |
| 按 PMID 取摘要原文 | 内部每 50 个一批并发;报「要几条/实取几条/缺哪些」 |
| 查这些 PMID 在别的数据库里的对应记录(elink) |
|
| 已知文献找回测试:一批已知相关 PMID 哪些被 | 分批 esearch 交集判定 found/missing(每批 50,避免 URL 超长 414);缺失项附标题与存在状态(present/unavailable/unknown);term 被 NCBI 忽略时显著告警;只证明已知集找回,不代表查全率 |
| 查 MeSH 主题词表 | 描述符、入口词(同义词)、树号、下位词、范围注;无描述符命中不等于主题无文献 |
| 对比两个查询的结果集 | 新增/丢失/共同 PMID;两查询都须在 9999 窗口内;集合差不判断相关性 |
| 取全某查询的 PMID 并写文件 | 超 9999 窗口自动按发表日期切片; |
旧说明“判断有没有免费全文可下”已作废,原因:数据库关联不能证明开放许可或此刻下载可用〔修订记录:2026-11-11;依据:links 当前工具说明〕。
按需精简检索结果
search 新增可选 detail,默认 full。已有调用不传此参数时维持完整输出;as_json 仍独立控制输出格式。
detail | 返回内容 | 保留的功能与限制 |
| 原有完整题录字段 | 默认行为及 JSON 字段保持兼容 |
| PMID、日期、完整标题、全部文献类型 | 仍读取元数据;不删除撤稿、勘误类型;省略的作者、期刊、DOI/PMC 不表示来源缺失 |
| 按 esearch 返回顺序给 PMID | 跳过 esummary;未获取元数据、未检查撤稿等类型;JSON 的 returned 按 PMID 计,esummary_missing 为 null |
各档均保留实际执行式、查询警告、零结果解释与检索窗口上限提示。文本中的执行式沿用原有截断规则,完整执行式始终可从 JSON 的 querytranslation 取得。ids 不适合直接据此判断文献质量或引用细节。
调用示例(本项目自订使用示例):
search('"root resorption"[tiab]', detail="brief")
search('"root resorption"[tiab]', detail="ids", as_json=True)精简不保证每次输出更短:少量短题录可能因必要说明而抵消节省。尚未测量实际模型 token 或费用收益。
系统综述检索助手(1.4.0 新增)
四个新工具加可选留痕,支撑系统综述的检索环节。设计依据与实测前提见 docs/systematic-review-plan.md,方法学工作流见 docs/systematic-review-workflow.md(亦作为 /systematic-review skill 随仓库分发)。
分工〔本项目自订〕:工具只做机械可复现的事(检索、集合运算、导出、留痕);拆概念、选同义词、判断相关性、定纳入排除由人与 LLM 按预设标准做。工具不声称查全率/查准率,已知集找回只证明这批已知文献被检回。
check_recall(term, pmids):分批 esearch 交集判定 found/missing;present 表示记录存在但本次实际执行式未检回,unavailable/unknown 表示存在性未确认。任一批仅剩 UID 条件时置term_ignored;部分概念消失、解析警告或原式语法失真时置term_degraded。空执行式归为信息不足,不能直接断言 term 被忽略。JSON 的querytranslations保存各批执行式;这些标记是保守诊断,仍须核对原式,不能把全部 found 当真实查全率。mesh(term):esearch/esummarydb=mesh,给入口词、树号、上下位词、历史前身词(previous indexing)、范围注与引入年份。本次返回候选中的字面精确项自动置顶;关联名称缺失时保留 UID 并告警。〔来源:源码mesh;验证见演练修复记录〕diff(term_a, term_b):两查询各取全窗口内 ID,本地集合差给新增/丢失/共同。任一超窗拒绝并提示改用 export。export(term, path, format):超检索窗口按发表日期递归二分,切片计数与总数核对、按 PMID 去重。每次使用唯一临时文件;Windows 用不覆盖的 rename,其他系统用硬链接原子发布,文件系统不支持则报错。清理失败会警告;path 不得已存在。CSV 不含摘要,MEDLINE 保留来源已有字段。安全上限为十万条〔本项目自订;源码 EXPORT_MAX〕。检索留痕:设环境变量
PUBMED_AUDIT_DIR,工具在完成路径追加 JSONL 到searches.jsonl。search/count 区分input_params与实际request_params;记录实际返回数、执行式、警告和运行源码版本,search 元数据失败另记error。fetch_abstracts/links 记录请求 PMID;check_recall 记录各批执行式。留痕默认关闭;写失败报 stderr。参数校验失败、网络中断等并非所有失败路径都有日志,不能当完整请求流水账。引文补查:
links(to="refs")/links(to="citedin")给参考文献/施引文献;有展示上限并显示截断,只限 PubMed 已录入关系。
实测注意〔2026-11-11 live,verify_sr_live.py〕:大题目切片计数和可能大于总数——同一记录带多个发表日期时会落进多个年份切片,去重后与总数一致;警告会如实说明,这不是错误。例:dental implant 命中 73612,切片计数和 78474,去重后 73612〔实测;重复数 4862 为推算 DV-SR-DEDUP〕。
验收:离线 84 项(mcp 1.30.0 与 2.3.0 各 84 通过)+默认行为 A/B 49 组逐字一致+真实联网验收 PASS+对抗性探针找坑并修复 3 处+真实题目端到端演练〔实测 2026-11-11,详见 docs/sr-tools-validation.md〕。尚未测量新工具的实际 token 开销;工具描述总字符由 1325 增至 2328〔实测 list_tools〕,描述体积回归上限相应由 2000 上调到 2600〔本项目自订〕。
自动回归
regression.yml 在推送、拉取请求和手动触发时安装项目,检查依赖,执行离线回归,并验证已安装 CLI 与新 stdio 进程。需要把配置推送至 GitHub 才会触发远端运行。
Python 3.10 / 3.13、MCP 一代 / 二代组合为本项目自订验证矩阵(来源:regression.yml);每个区间由 pip 选择兼容版本,不代表全部版本或最低 SDK 均已验证。
日常测试不查询 NCBI;离线运行器拦截本进程的外部 socket 连接,保留事件循环需要的本机回环连接。依赖安装仍需联网,安装烟测不作全系统断网保证。
完整联网
--probe单独手动运行,不将外部网络故障混入普通提交检查。Actions 红灯不会自动禁止合并;强制通过后才允许合并需要仓库分支保护规则,本配置不会改动该设置。
本地执行同一套离线检查:
python -I tests/run_offline.pyBehavior contract —— 它到底替你拦了什么
下面每条都在源码里有实测锚点或断言覆盖(本仓库的 --probe 会替你复验,包括第 1 条那个
200 + HTML 分支——它已落成一条离线断言,不再只是防御性假设)。
失败绝不静默。 请求失败抛
NcbiError并带回 NCBI 原文;HTTP 200 + 一段 HTML、 或 200 +{"ERROR": ...}都算失败,不会被说成「NCBI 里没有这篇」。 〔实测 2026-11-11:这条曾在 mcp 2.x 上被打穿过——SDK 把非ToolError的异常文本剥掉,调用方 只剩一句Error executing tool <name>。现在的基类写法与那条走包装层的回归断言见 docs/mcp-sdk-v2.md。〕0 条必须说清是哪一种 0。 真的没有匹配 / 词被当停用词忽略 / 整个引号短语在索引里不存在 / 两段同字段日期不相交 /retstart越页 /retmax=0且命中>0(只要计数、没要记录)——这几种各说各的话, 不统一兜底成「PubMed 里没有匹配」。field=走白名单,宁拦勿吞。 实测 NCBI 对认不出的field静默忽略(拼错一个字母=限定被吃掉、 且没有任何提示)。keywords/PMC Number/ISSN实测被整条忽略,MeSH Terms/Publication Type实测让esearch不返回count——这五个都直接报错并给改写建议。sort=只收pub_date/relevance/author〔实测 2026-11-10 本机 idlist 两两对照〕。journal/relevancy/keyword实测顺序与不传时逐字相同,所以放进黑名单而不是白名单。best match会被改写成relevance下发,并且输出里明说这次改写。单边日期补哨兵,并声明补了什么。 实测 NCBI 对只给一端的
mindate/maxdate整条忽略。 补的是不可能生效的哨兵0001-01-01/2999-12-31,不是「今天」或「收录起点」—— 后者是真边界,本机日历与 NCBI 服务器日历差一天时会静默切掉那一天的文献。reldate原样下发,本工具不做日历换算。 「近 N 天」由 NCBI 按它自己的服务器日历算。摘要按
^PMID:行计数,不拿请求数冒充返回数。不存在的 PMID 会回「要 N 条 / 实取 M 条」, 并点名取不到的那个号;"实取"按 efetch 正文里的 PMID 行计,所以没有摘要的社论照样算实取 〔实测 2026-11-11:99999999 / 9999999999 → 要 1 条 / 实取 0 条〕。PMID 解析不猜。
1,234,567这种带千位分隔符的形(从 Excel 复制一列号很常见)直接拦—— 旧写法会切成 3 个真实存在的 PMID,抓回三篇不相干文献、条数还看着正常。async 工具 + 网络调用出事件循环。 mcp 1.x 对非 async 工具是裸
return fn(**kwargs)、 没有 threadpool,一次 40s 的efetch能把整个 server 冻住〔依据:作者读的mcp/server/fastmcp/utilities/func_metadata.py〕。 〔实测 2026-11-10:这一条只在 1.x 成立 —— 2.3.0 把该文件挪到mcp/server/mcpserver/utilities/func_metadata.py,非 async 分支改成await anyio.to_thread.run_sync(functools.partial(fn, **kwargs)),也就是 SDK 自己开始卸载了。 本服务全部工具均为async def;装饰后协程属性和包装层透传由离线测试与源码 stdio 烟测覆盖。 〔这条后半句此前没有断言钉住——而它才是承重的部分:装饰之后的名字一旦不再是协程函数, SDK 就走同步分支。现在有一条离线断言专门问【装饰之后】那四个名字,两代各测一次都仍是协程函数 〔实测 2026-11-11〕。〕key 一个字符都不外泄。 错误文本里只报 key 长度不报片段;
_mask无条件整串替换成定长掩码 (旧写法既留前 4 位、又只在长度 > 8 时才掩)。〔已知边界:key 以 URL 百分号编码形态出现在 报错文本里时仍替换不到——过度设计,记着当边界,别当已修好。〕
自检
python pubmed_mcp.py --check-key # 零网络请求,先看 key/限速/依赖装对没
python pubmed_mcp.py --probe # 完整回归断言,需要联网,见下方警告
python pubmed_mcp.py --selftest "tooth resorption"
python pubmed_mcp.py --concurrent "tooth resorption"⚠️ --probe 不是健康检查,是一轮重流量回归。它自己会在末行报数:
「N 通过 / M 失败 —— 本轮 K 次 HTTP 请求(含退避重试的每一次)」。
本 README 故意不写死任何条数——写死过一次就注定过期(这份代码里有一条真实的过期记录)。
按量级估:一轮要按几十秒到几分钟算,还要看你在 10 次/秒还是 3 次/秒档。
怎么确认它真的跑完了:看末行有没有那句「N 通过 / M 失败」,并看退出码 (非 0 即有 FAIL)。这条不是形式主义——作者踩过一次「探针中途崩掉、日志却显示 28 通过 / 0 失败」, 崩掉的探针看起来像通过,比一条 FAIL 危险得多。
复现编码相关的 bug 时别加 -I:隔离模式会忽略 PYTHONIOENCODING,stdout 直接落回 utf-8,
于是旧版也不会报错,你会得出「旧版也没问题」的假结论。
Limits(诚实清单)
查询以实际执行式为准。 中文片段可能消失,混合查询仍可能命中剩余英文概念;不能把命中数当成完整原查询结果。 【已作废,修订日期:2026-11-12】旧“只索引英文”与“空执行式等于没解析出条件”结论过强;缺少执行式只能说明解析信息不足。
esearch 最多取回前 9,999 条,
retstart上限 9998(NCBI 硬墙,越界本工具直接报错)。 1.4.0 的export通过按发表日期切片取全超过此窗口的结果(history 服务器同样受此限制〔实测 2026-11-11〕);search/diff仍受窗口约束。retmax上限 1000 是本工具自订的,不是 NCBI 的限制;要一次多拿就改那个常量, 或按年份/字段把查询切小分批取。夹过都会在输出里说明是本工具夹的。PubMed 没有「按期刊影响力排序」这个概念,
sort里不存在这种值。本仓库也不含这类脚本 ——要那种排序得自己接外部期刊指标数据源。默认
datetype="pdat"(发表日期)。不带datetype时 NCBI 按入库日期算,两者结果不同〔实测〕。分批大小(esummary 100、efetch 50)与超时(25s/40s)是本项目口径/推算值, 不是量出来的最优点;它们挂在「实测」标题下的段落里容易被误读,源码里已就地标注。
为什么不用现成的包
作者初版对比的是 pubmedmcp 0.1.4 + pubmed-client 0.2.0,结论是那两个包不读 API key、不设 timeout、
出错时把异常打成空字符串。
⚠️【已不可就地复核,2026-11-08 作者自查】:那几条对比是当时看过源码得出的,但复核时本机
pip show 两个包均 not found、无可执行文件、无 pipx,现在无法重跑验证。
别当事实引用;要用就重装那两个包再看。
这份发布版与作者开发版的关系
公开仓库里的 pubmed_mcp.py 不是作者机器上正在跑那份的逐字节副本:它带着若干处发布专用改动
(_mask 收口、--selftest 不再打印 key 前缀、工具说明补上 author、journal-rank 指路改成不指向
本仓库没有的文件,以及三条新增离线断言)。逐处理由与依据见
docs/release-delta.md。
License
MIT — 见 LICENSE。
源码注释里的 〔实测〕/〔推算〕/【已作废+理由+日期】 标记请一并保留:
作废的推断不删除、只标注,是因为删掉之后人会重新踩同一个坑。
Available Tools
8 toolscheck_recallA
已知文献找回测试:一批已知相关 PMID 里哪些被 term 检回。pmids 逗号/空格分隔,去重后最多 200 个。 分批 esearch 交集判定 found/missing(每批 50 个,避免 GET URL 超长被 NCBI 414);缺失项附标题与存在状态。 只证明这批已知集的找回,不代表整体查全率;金标准集本身可能有偏。 逐块诊断用 count("概念块 AND pmid[uid]")。查询警告原样透传;term 被忽略或部分词未生效时显著告警。
Inputs: term (required), pmids (required), as_json. Returns: result
countA
只取 PubMed 命中数,不取题录;需要题录直接用 search,避免重复检索。
term、field、日期参数规则同 search:英文词,大写 AND/OR/NOT,日期按发表日期。 返回实际执行式及 ⚠️;丢词/短语改写后的计数不能当原查询计数。0 条不证明主题无文献, 有命中也不证明原短语存在;确认短语须读取题录或摘要。完整解析可用 search(retmax=0, as_json=True)。
Inputs: term (required), field, maxdate, mindate, +1 more. Returns: result
diffA
对比两个 PubMed 查询的结果集:b 相对 a 新增、丢失了哪些 PMID。 检索式迭代前后核对增减;两查询都须在 9999 窗口内,超窗报错(先缩小或改用 export)。 max_show 默认 20、上限 200,文本档每侧只展示部分;as_json=True 给完整列表。 集合差只描述增减,不判断相关性;命中更多不等于更好。两次查询间数据库可能更新。
Inputs: term_a (required), term_b (required), as_json, max_show. Returns: result
exportA
取全某查询的 PMID 并写文件;超 9999 窗口自动按发表日期二分切片。 format: pmids(纯 PMID 列表)/ csv(核心题录字段,不含摘要)/ medline(.nbib,保留来源中已有的摘要与主题词)。 只回摘要(总数/片数/去重/路径/sha256),不回记录本身。path 显式给出且不得已存在(不覆盖)。 切片计数与总数核对,不一致如实报告;检索期间数据库可能更新,结果以导出时点为准。 自订安全上限 10 万条。筛选工具导入兼容性以对方文档为准;不保证与 PubMed 网页导出逐字一致。
Inputs: path (required), term (required), format, as_json. Returns: result
fetch_abstractsA
按逗号/空格分隔的 PMID 取 NCBI 原排版摘要;保留结构化段落、作者信息和声明。
自动去重、归一补零号、分批。建议先筛选题录,再只取需要的摘要以节省输出。 返回请求数、实际记录数和缺失号;有记录不等于有摘要,社论可能只有引文。 网络失败报错,不冒充无记录。文献数值引用仍须核对原文位置。
Inputs: pmids (required). Returns: result
linksA
查 PMID 的数据库关联或引文追踪。pmids 用逗号/空格分隔,去重后最多 50 个。
to: pmc(默认)/ gene / nucleotide / pubmed / citedin(施引)/ refs(参考文献),大小写不敏感。 每行列直接关联号;方括号是其它关联计数。citedin/refs 供滚雪球追踪(0 条仅限 PubMed 已录入关系,不等于无引文)。 to=pubmed 是相关文献,含自身;to=pmc 是 PMC 关联,不保证开放许可或此刻可下载。 无关联、元数据不可用与存在性未知分开报告;esummary 缺失不证明 PMID 不存在。 search 已给 PMC 时无需重复查询 links。内部逐 PMID 请求以保留归属,失败明确标注。
Inputs: pmids (required), to. Returns: result
meshA
查 MeSH 主题词表:描述符、入口词(同义词)、树号、上下位词、历史前身词(previous indexing)、范围注、引入年份。 词表以查询时点 NCBI 返回为准;retmax 默认 5、上限 20(本批候选内精确匹配置顶)。 历史前身词供扩展旧标引词,不保证补齐;下位词(最多展 10 个)供决定是否展开。 无描述符命中不等于主题无文献;NCBI 报 phrasesnotfound 时告警。
Inputs: term (required), retmax, as_json. Returns: result
searchA
检索 PubMed,返回命中数及 PMID、日期、期刊、标题、作者、DOI、PMC、文献类型。
term 使用英文 PubMed 语法:resorption[Title]、"root resorption"[tiab]、AND/OR/NOT、截词 *。 布尔算子写大写,引号只包短语,括号须配对。MeSH 请核对实际执行式:写错的带引号词会报 quotedphrasesnotfound,不带引号可能改写成别的概念;有命中不证明原短语存在。 sort: pub_date / relevance / author;不能按期刊质量排序。 field 可用 Title、Title/Abstract、Journal、Author、Affiliation、Language、Grant、PMID 等; 未支持值会报错。MeSH/文献类型请写进 term 的 [MeSH Terms]/[Publication Type] 标签。 日期按发表日期;mindate/maxdate 接受 YYYY、YYYY-MM、YYYY-MM-DD 或斜杠写法。 单端日期自动补另一端并提示。reldate=0 不限,正数为最近天数;和显式日期同时给时做 AND。 retmax 默认 20,上限 1000;retstart 为零起始偏移,上限 9998,最多可翻前 9999 条。 只要计数用 count;需要题录直接 search,无需先 count。as_json=True 返回完整解析和结构化记录。 detail: full 默认完整题录;brief 仅 PMID/日期/标题/全部文献类型;ids 仅 PMID,不取元数据或检查撤稿类型。 各档保留查询警告;brief 省略字段不表示缺失,ids 的 returned 计 PMID 数、esummary_missing 为 null。 先读 ⚠️:改写后的命中数不等于原查询命中数;0 条不证明主题无文献。PMC 号不保证立即可下载。
Inputs: term (required), sort, field, detail, +6 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool has a distinct role: record search, count-only, abstract retrieval, link/citation traversal, recall testing, MeSH lookup, query diffing, and bulk export. Overlaps such as search versus count and search versus fetch_abstracts are explicitly clarified by output scope and intended use.
Multiword names use snake_case, but the set mixes verb-first names (fetch_abstracts, check_recall), bare verbs (search, count, export), and bare nouns (links, mesh, diff). It is readable, but there is no single predictable naming convention.
Eight tools is well scoped for a PubMed research workflow and each tool supports a distinct part of literature retrieval or analysis. The count tool is somewhat redundant with search but is a reasonable lightweight convenience rather than bloat.
The surface covers search, counts, abstracts, related records/citations, MeSH vocabulary, recall checks, set comparison, and bulk export. Minor gaps remain around full-text/PMC retrieval and citation-manager export formats such as RIS or BibTeX.
Maintenance
Related MCP Connectors
PubMed MCP — wraps the NCBI E-utilities API (biomedical literature, free, no auth)
Auditable MCP server for PubMed, Europe PMC, ClinicalTrials.gov, and bioRxiv/medRxiv queries
NCBI E-utilities MCP — federated Entrez search/fetch.
Search biomedical literature, get article details, find related articles, and explore MeSH terms
Related MCP Servers
- AlicenseNot gradedqualityDmaintenance🔍 Enable AI assistants to search, access, and analyze PubMed articles through a simple MCP interface.132MIT
- FlicenseNot gradedqualityCmaintenanceEnables searching PubMed's biomedical literature database and retrieving article metadata, abstracts, and full content through the E-utilities API. Supports advanced queries, batch operations, and multiple output formats with automatic rate limiting.2-
- AlicenseAqualityDmaintenanceAn MCP server that provides direct access to PubMed and PubMed Central via the NCBI E-utilities API. It enables AI models to search biomedical literature, retrieve detailed article metadata, and download open-access full texts.5MIT
- AlicenseAqualityDmaintenanceExposes NCBI PubMed as MCP tools for searching literature, fetching abstracts, exploring citation graphs, and finding author publications without requiring an API key.4MIT