ChiCTR MCP Server
A ChiCTR (Chinese Clinical Trial Registry) query server exposing 4 tools for searching trials, fetching full details, and managing the cache.
search_trials – Search ChiCTR clinical trials by title keyword (e.g.
KRAS G12C,胰腺癌), registration number (e.g.ChiCTR2500111173), and/or registration year; all params optional, returns a trial list withmax_results(default 20).get_trial_detail – Retrieve the complete structured detail record for a trial by its required registration number.
get_cache_stats – Inspect cache statistics such as search/detail cache hit rates.
clear_cache – Wipe all cached data.
Under the hood it reads live ChiCTR data (search list + ~76 detail fields per trial), making it useful for trial intelligence, RAG/knowledge-base ingestion, patient-matching filters (inclusion/exclusion criteria), and trend analysis by year or institution.
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., "@ChiCTR MCP Serversearch for KRAS G12D clinical trials from 2024"
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.
ChiCTR MCP Server
基于 Model Context Protocol (MCP) 的中国临床试验注册中心 (ChiCTR) 查询服务。
站点对 /searchproj.html(搜索)与 /showproj.html(详情)施加了阿里盾(阿里云 WAF)保护:
直连返回 405,换出口 IP 则变成一页需要执行 JavaScript 才能通过的挑战页。
本项目用「Node MCP 服务器 + Python sidecar 子进程」的两段式架构解决它 —— sidecar 过一次挑战
拿到 cookie,之后全程走纯 HTTP。
当前版本: v3.0.2 · MCP 工具: 10 个 · 详情字段: 76 个 · 默认数据通道: ChiCTR 原站直连
📍 目录
Related MCP server: Clinical Trials MCP Server
🧩 Scrapling 是什么
Scrapling 是一个第三方 Python 爬虫库(pip install scrapling,本项目用的 scrapling[fetchers]
实测版本 0.4.15)。它提供 Fetcher / StealthyFetcher / StealthySession 等一把好用的
抓取 API,把「伪装 TLS 指纹」「跑无头浏览器」「过挑战」收敛成几行调用。
⚠️ 关键结论:解决阿里盾 405 的不是 Scrapling 这个「框架」
这是本项目最重要的一条认知,也是「开箱即用」代价的来源:
真正过盾的是 Scrapling 捆绑的两个底层组件 ——
curl_cffi和patchright。 Scrapling 只是把它们包成了好用的 API。
组件 | 角色 | 在过盾中的实际作用 |
curl_cffi | TLS 指纹伪装(impersonate) | 让 Python HTTP 请求的 TLS 指纹(JA3/JA4)看起来像真 Chrome。它只把「硬 405」降级成「挑战页」,本身解不了挑战。 |
patchright | Chromium 反自动化补丁(Playwright 的 fork) | 让阿里盾的挑战脚本能真正跑完并算出 |
Scrapling( | 调用这两个组件的封装层 | 提供 API。它自带的 Cloudflare solver( |
三层证据(dev/browser-removal/SCRAPLING_SOLUTION.md,2026-10-04 本机实测):
层级 | 手段 | 结果 |
0 | 裸 curl / 裸 Node 直连 | ❌ 405 硬拦截 |
1 |
| ⚠️ 200,但只返回 17,136 字节的挑战页(含 |
2 |
| ✅ 200,42,178 字节真实页面( |
2' | 同样的活交给原生 Playwright + | ❌ 挑战脚本死循环,跑不完 |
推论:StealthyFetcher 与原生 Playwright 的差别就在 patchright 的指纹补丁;
正是这个补丁让挑战脚本得以走完。Cloudflare solver 与本case无关。
代价:依赖很重(约 1 GB)
「框架能力很强」的反面是依赖体积。因为要同时带上「TLS 伪装库」和「带补丁的 Chromium 内核」:
项目 | 实测体积 |
| 325 MB |
| 557 MB |
Node 侧 | 数百 MB |
合计 | ≈ 1 GB |
而且会存在两套 Chromium 内核:Node 侧 Playwright 要 chromium-1234,Python 侧 patchright 要
chromium-1243。这正是本项目不能做成「一个安装包全搞定」、必须把 Python 侧做成
运行时按需自举的根本原因(见 部署)。
🏗️ 架构与部署形态
运行时架构
MCP 客户端(Cherry Studio / Claude Desktop / …)
│ stdio(MCP 协议,stdout 专属通道)
▼
Node MCP server(dist/index.js) ← 对外协议、缓存、状态机、工具编排
│ CHICTR_USE_SIDECAR=1 时优先走这里
│ HTTP JSON → 127.0.0.1:8848
▼
Python sidecar(sidecar/chictr_sidecar.py) ← 过盾 + 抓取 + 解析
├─ curl_cffi 纯 HTTP + TLS 指纹伪装 ─────── 常规请求路径(约 1.5s/页)
└─ patchright StealthySession 无头浏览器 ── 仅 cookie 过期时过盾(约每小时 1 次)
▼
https://www.chictr.org.cn职责边界很清楚:sidecar 只负责「把 HTML 拿回来并解析成 JSON」,Node 侧负责一切对外契约。
三种部署形态
形态 | 组成 | 浏览器依赖 | 适用 |
A. sidecar 形态(推荐) | Node MCP server + Python sidecar | 仅过盾时拉一次 Chromium | 本机开发、桌面 App、长期驻留服务 |
B. 纯 Playwright 形态(默认/回退) | 只有 Node MCP server | 每次查询都要 Chromium | 已有浏览器环境、sidecar 不可用时的兜底 |
C. ICTRP 形态(规划中) | 只有 Node MCP server,走 WHO ICTRP | 无 | 轻量部署、批量检索;见 |
当前实现落地的是 A + B:sidecar 可用则走 A,任一环节失败自动回退 B,对外契约不变。 形态 C 仍是设计稿,尚未实现。
打包形态(形态 A 打成 dmg/exe 时):
你的 App.app / your-app.exe
├── node_modules/ # Node 依赖,打包器收集(几十 MB)
├── dist/ # TS 编译产物
├── sidecar/chictr_sidecar.py # 随包分发(package.json 的 files 已含 "sidecar")
└── (首次运行时在用户目录创建)
└── .venv/ # 325 MB,由 setup 创建,不进安装包关键约束:打成 dmg/exe 后安装器不会执行 package.json 的 postinstall(打包器只收集文件,
钩子被丢掉)。所以依赖准备必须由主程序在运行时驱动 —— 这就是 env-probe.ts + bootstrap.ts
存在的原因。
⚙️ sidecar 设计
接口(极小的 HTTP JSON)
sidecar 用标准库 ThreadingHTTPServer 暴露三个只读端点,没有框架依赖:
方法 | 路径 | 参数 | 返回 |
GET |
| — |
|
GET |
|
|
|
GET |
|
|
|
错误语义:过盾后仍拿到挑战页 → 503 {"error":"challenge_unsolved"};缺 proj → 400;
其他异常 → 502。默认监听 127.0.0.1:8848(--host / --port / CHICTR_SIDECAR_HOST /
CHICTR_SIDECAR_PORT 可覆盖,另有 CHICTR_SIDECAR_LOG 控制日志级别)。
/search 的 results[] 元素:
{
"project_id": "245719",
"registration_number": "ChiCTR2600133371",
"title": "阿得贝利单抗联合NALIRIFOX用于可切除胰腺癌新辅助治疗",
"institution": "浙江大学医学院附属第一医院",
"study_type": "干预性研究",
"registration_date": "2026/09/24",
"detail_url": "https://www.chictr.org.cn/showproj.html?proj=245719"
}核心机制:cookie 复用,浏览器降级为「低频刷新器」
这是整个设计的地基 —— 挑战解出的 cookie 可以脱离浏览器复用。
过一次挑战:
ChallengeSolver._solve()启动StealthySession(headless=True), 导航到/searchproj.html,从session.context.cookies()取出acw_sc__v2/acw_tc/ssxmod_itna/ssxmod_itna2四个 cookie。纯 HTTP 复用:
ChictrClient.get_html()用FetcherSession(impersonate="chrome")带上这组 cookie 请求,不再触碰浏览器。实测摊薄效果:
solve_count = 1支撑了 ≥13 次请求(含 3 并发 + 10 并发分页), 期间未触发重新过盾。一次过盾约 4.7–6.0s,此后约 1.5s/页。
设计上还有几处关键细节:
机制 | 实现 | 原因 |
双重检查锁 |
| 多线程并发首次请求时只跑一次浏览器 |
常驻 HTTP 会话 |
| 避免每个请求重建连接池 |
底层串行化 |
| curl_cffi 的底层 session 并非线程安全,并发是「排队」而非真并行 |
内容检测兜底 |
| 不信任 TTL,信任响应内容 |
一次重试 | 命中挑战页或请求异常 → | 恢复路径短且不会打转 |
⚠️ 重要发现:cookie 实际只有约 37.5 分钟,不是 1 小时
代码里 COOKIE_TTL_SECONDS = 55 * 60(55 分钟,比 acw_sc__v2 的 1 小时 expires 留了 5 分钟余量)。
但实测 cookie 实际存活约 37.5 分钟,TTL 判断偏乐观。
这个偏差不会造成故障,因为兜底不在 TTL 而在内容检测:
cookie 提前失效时,请求会返回挑战页而非报错,_is_challenge() 立刻识别出来 →
invalidate() 清空 cookie → 重新过盾 → 重试。实测约 5.7s 恢复,调用方只感知到一次稍慢的请求。
结论:fresh 只是「提前刷新」的优化信号,真正的正确性由响应内容检测保证。
运维上不应把 solver.fresh == false 当成故障(见监控)。
Node 侧客户端(src/runtime/sidecar-client.ts)
行为 | 实现 |
默认关闭 |
|
失败即回退 | 任何失败(不可达、非 JSON、非 2xx、 |
快速失败 | 请求带 |
状态可见 |
|
get_trial_detail 需要先有 project_id:客户端先查缓存里的「注册号 → project_id」映射,
没有就先用 /search?regno= 查一次拿 project_id,再调 /detail?proj=。
惰性初始化浏览器(关键修复)
原 src/index.ts 的 CallToolRequestSchema handler 在 switch 之前无条件执行
new BrowserManager() + initialize() —— 后果是即使 sidecar 命中也会先拉起 Chromium,
sidecar 的全部价值被这一行抵消。
现已改为 ensureBrowser() 惰性函数,只有真正会走 Playwright 的分支(含 sidecar 回退)
才初始化 Chromium。决定性验证:在一台刻意不安装 Playwright 浏览器内核的机器上
(Executable doesn't exist at .../chromium_headless_shell-1234/...),修复前 search_trials
直接抛错,修复后同样调用返回真实数据 —— 证明全程未触碰浏览器。
🚀 部署
用户视角:三步走
# 1. 体检(只读,不改任何东西;退出码 1 = 需要处理)
chictr-mcp-server doctor
# 2. 一键修复(创建 venv + 装依赖;联网,首次约 40s ~ 3min)
chictr-mcp-server setup
# 3. 启动 sidecar(前台运行,首次会过一次盾)
chictr-mcp-server sidecar然后让 MCP 客户端走 HTTP 路径:
export CHICTR_USE_SIDECAR=1
chictr-mcp-server --transport=stdio
setup默认不下载浏览器内核(省 560 MB)。sidecar 的纯 HTTP 常规路径不需要它; 只有「首次过盾」才需要 Chromium。需要时加--browser显式授权下载。也可以把这三步交给 AI —— MCP 工具
check_environment会返回同样的体检结论和修复建议。
退出码约定
码 | 含义 | 调用方应对 |
0 | 环境就绪 / 操作成功 | 继续 |
1 | 未就绪,需要用户动作 | 提示用户跑 |
2 | 自举失败(网络、磁盘、权限) | 展示错误,可重试 |
自动化的三个层次
启动时自检(已实现,无需配置):MCP 服务每次启动做一次体检,结果只写 stderr (stdout 是 MCP 协议通道,写进去会破坏协议)。体检永不阻塞启动、永不抛异常 —— 环境好坏都能启动服务,只是能力不同。
[chictr-mcp-server] 环境未就绪:未找到 Python 虚拟环境 [chictr-mcp-server] 运行 "chictr-mcp-server setup" 自动修复首次运行自动下载(可选,需显式授权):
setup --browser或代码里bootstrapEnvironment({ installBrowser: true, onProgress })。 刻意不做静默自动下载 —— 560 MB 在用户不知情时下载是冒犯行为。自举健壮性:
bootstrapEnvironment()是幂等的(已存在的 venv 不重建、已装的依赖 不重装,中断后重跑从断点继续);pip 镜像按首选 → 其他 → 官方源自动回退 (默认阿里云;清华镜像对 pip 26 的新版 User-Agent 返回 403,会把错误伪装成Could not find a version that satisfies the requirement scrapling[fetchers] (from versions: none), 极具误导性,故镜像回退是必需而非优化)。
环境变量总表
变量 | 默认 | 说明 |
| 自动推断 | 项目根目录(打包后位置非常规时必须设) |
|
| 虚拟环境目录 |
| 未设置(关闭) | 设为 |
|
| sidecar 地址 |
|
| sidecar 单次调用超时 |
|
| sidecar 监听地址(Python 侧) |
|
| sidecar 日志级别 |
| 未设置 | 代理(可选) |
用户环境要求
要求 | 说明 |
Node.js | ≥ 20(打包版自带,可忽略) |
Python | ≥ 3.10( |
磁盘 | 纯 HTTP 路径约 400 MB;含浏览器约 1 GB |
网络 | 首次 |
如果用户没有 Python:doctor 会报 venv: missing 并提示安装 Python。这是 setup
唯一无法自动解决的依赖。
⚠️
pip install --user在部分 macOS 上会因权限失败 (OSError: [Errno 1] Operation not permitted: .../site-packages/w3lib),必须用 venv。⚠️
.venv默认建在项目根。若安装目录只读(macOS/Applications、WindowsProgram Files),必须设置CHICTR_HOME指向可写目录;isWritable()会在体检报告里提示。
监控与排障
curl -sS http://127.0.0.1:8848/health
# {"ok": true, "solver": {"fresh": true, "age_seconds": 57.0, "solve_count": 1, "last_error": null,
# "cookie_names": ["acw_sc__v2","acw_tc","ssxmod_itna","ssxmod_itna2"]}}solver.solve_count:累计过盾次数。稳态下应长期为 1(约每小时 +1)。 快速上涨说明 cookie 被反复判失效,应检查是否被限流。solver.last_error:最近一次过盾失败原因,正常为null。MCP 侧可通过
get_runtime_metrics看sidecar: { enabled, available, baseUrl, lastError }。
症状 | 原因 | 处理 |
| sidecar 未启动 |
|
日志 | 正常噪声 | ChiCTR 用阿里盾不是 CF,可忽略;成功标志是紧随的 |
| 过盾后仍返回挑战页 | 通常是 IP 被限流,稍后重试 |
MCP 返回 Playwright 报错 | sidecar 未启用或不可达 | 确认 |
| pip 镜像 403 | 已自动回退;或 |
体检报 venv missing 但目录存在 | venv 损坏 |
|
启动即崩 |
| 见下 |
# better-sqlite3 原生绑定(Node 22 / ABI v127);npm rebuild 在受限沙箱会因
# 无法写 ~/Library/Caches/node-gyp 而失败,用预编译包绕过
cd node_modules/better-sqlite3 && npx prebuild-install -r node -t 22.19.0全新安装实测记录
在一个「什么都没有」的隔离目录(只有 package.json + dist/ + sidecar/chictr_sidecar.py,
共 592 KB)验证:
步骤 | 结果 |
| ✅ 正确报未就绪,退出码 1,给出 actions |
| ✅ 清华失败 → 自动回退阿里云成功(2m35s) |
| ✅ 全部就绪(venv 3.13.14 / 依赖 / 浏览器内核 / 脚本) |
启动 sidecar | ✅ 过盾成功 6.7s |
真实搜索「胰腺癌」 | ✅ |
MCP 工具 | ✅ 22ms(缓存命中) |
即:一台干净机器上,592 KB 的包 + 一条 setup 命令 = 可用。
🎯 应用场景
场景 | 怎么用 | 为什么合适 |
临床试验情报监测 | 按靶点/疾病关键词定时 | 原站是实时数据(WHO ICTRP 为每周同步,有滞后);约 1.5s/页使每日轮询成本可忽略 |
RAG / 知识库入库 |
| 详情页解析为中英对照的结构化字段,比裸 HTML 更适合切分与检索;v3.0.1 起含纳排标准、联系人、伦理委员会联系方式 |
患者匹配与入组筛选 | 用疾病名/基因突变(如 |
|
AI Agent 的循证工具 | 作为 MCP server 挂到 Cherry Studio / Claude Desktop 等客户端 | 中国临床试验数据对上 AI 助手是通用缺口;10 个工具里有 5 个是给 Agent 自诊断用的 |
科研回顾与趋势分析 | 按 | 支持按年份、注册号、关键词组合查询, |
部署自检(Agent 自助排障) |
| 让 AI 能在用户机器上自行判断「缺 Python 还是缺依赖还是 sidecar 没起」 |
📋 可用工具
共 10 个 MCP 工具(v3.0.0 起新增 check_environment;工具数未变,v3.0.1 扩充的是 get_trial_detail 的字段覆盖)。
# | 工具 | 用途 |
1 |
| 按关键词 / 注册号 / 年份搜索 |
2 |
| 按注册号查询完整详情 |
3 |
| 单层缓存统计(命中率等) |
4 |
| 清除所有缓存 |
5 |
| 双层缓存统计(L1 内存 + L2 SQLite) |
6 |
| 运行时编排指标 + sidecar 状态 |
7 |
| 访问状态机(NORMAL/SUSPECTED/CHALLENGED/COOLDOWN/RECOVERY) |
8 |
| 本机环境体检(Python venv / 依赖 / 浏览器内核 / sidecar),只读,不下载不改文件 |
9 |
| 创建人工验证会话 |
10 |
| 人工验证后恢复访问状态 |
search_trials
// 按关键词
{ "name": "search_trials", "arguments": { "keyword": "KRAS", "max_results": 20 } }
// 按注册号
{ "name": "search_trials", "arguments": { "registration_number": "ChiCTR2500111173" } }
// 按年份
{ "name": "search_trials", "arguments": { "year": 2024, "max_results": 20 } }
// 组合
{ "name": "search_trials", "arguments": { "keyword": "KRAS", "year": 2024, "max_results": 10 } }参数说明:
参数 | 类型 | 必填 | 说明 |
| string | 否 | 注册题目关键词,最长 200,如 |
| string | 否 | 注册号,形如 |
| integer | 否 | 注册年份,最小 2000,最大为当前年份 + 1 |
| integer | 否 | 最大返回数,默认 20,范围 1–100 |
get_trial_detail
{ "name": "get_trial_detail", "arguments": { "registration_number": "ChiCTR2500108082" } }返回详情页的全部结构化字段。v3.0.1 起解析器改为按 HTML 表格结构抽取,字段数由 29 个提升到 76 个、平均 58.6 字段/条(对 468 个真实页面实测),并已逐字段回查 HTML 原文校验(全库 28809 个字段值逐一回查,0 处不符、0 处伪造)。
主要字段分组:
分组 | 字段 |
注册信息 |
|
联系人 |
|
伦理委员会 |
|
单位与来源 |
|
设计与目的 |
|
干预与样本 |
|
结局指标 |
|
招募与共享 |
|
标本 |
|
全量 468 条中 100% 覆盖的字段有 37 个:
注册号注册号状态注册时间最近更新日期注册题目研究课题的正式科学名称研究疾病研究类型研究设计研究目的研究所处阶段研究实施时间征募观察对象时间征募研究对象情况随机方法(请说明由何人用什么方法产生随机序列)年龄范围性别指标中文名指标类型说明是否获伦理委员会批准是否公开试验完成后的统计结果申请人所在单位申请注册联系人申请注册联系人电话申请注册联系人电子邮件申请注册联系人通讯地址研究负责人研究负责人电话研究负责人电子邮件研究负责人通讯地址研究实施负责(组长)单位研究实施负责(组长)单位地址经费或物资来源注册人纳入标准排除标准。覆盖率差异是页面本身留空导致的,不是解析失败:
次要研究终点1/468、研究疾病代码5/468、研究负责人网址(自愿提供)6/468、干预措施代码7/468、测量方法60/468 均已抽查确认原页面为空。
check_environment
{ "name": "check_environment", "arguments": { "refresh": false } }refresh: true 忽略 30 秒缓存强制重新探测。返回 root / node / venv / pythonDeps / browser / playwrightBrowser / sidecarScript / sidecar / summary / actions / canRunBrowserless。
canRunBrowserless 是判断「能否免浏览器检索」的关键信号。
缓存与状态工具
{ "name": "get_cache_stats", "arguments": {} }
{ "name": "clear_cache", "arguments": {} }
{ "name": "get_cache_stats_v2","arguments": {} }
{ "name": "get_runtime_metrics","arguments": {} }
{ "name": "get_access_state", "arguments": {} }人工验证会话
{ "name": "prepare_verification_session",
"arguments": { "target_url": "https://www.chictr.org.cn/searchproj.html", "timeout_ms": 300000 } }
{ "name": "resume_after_verification", "arguments": { "verification_id": "verify_xxx" } }📡 MCP 配置说明
最简配置(npx)
{
"mcpServers": {
"chictr": {
"command": "npx",
"args": ["-y", "chictr-mcp-server@latest"]
}
}
}全局安装后
npm install -g chictr-mcp-server{ "mcpServers": { "chictr": { "command": "chictr-mcp-server" } } }启用 sidecar(推荐)
{
"mcpServers": {
"chictr": {
"command": "node",
"args": ["/Users/you/chictr_trials/dist/index.js"],
"env": { "CHICTR_USE_SIDECAR": "1" }
}
}
}前置:先另开一个进程跑 chictr-mcp-server sidecar。
带代理
{
"mcpServers": {
"chictr": {
"command": "npx",
"args": ["-y", "chictr-mcp-server"],
"env": { "HTTP_PROXY": "http://your-proxy-server:port" }
}
}
}通信方式
方式 | 状态 | 说明 |
stdio | ✅ 支持(默认) | 标准输入输出 |
http | 计划中 |
|
sse | 计划中 |
|
测试 MCP 服务
npx @modelcontextprotocol/inspector npx -y chictr-mcp-server🛠️ CLI 命令行工具
package.json 提供两个 bin:chictr-mcp-server(dist/index.js)与 chictr-setup
(dist/cli/setup-cli.js)。
npm install -g chictr-mcp-server # 全局安装
npx -y chictr-mcp-server # 或直接 npx(推荐)命令 | 说明 |
| 启动 STDIO MCP 服务 |
| 环境体检(只读,不修改任何文件) |
| 安装缺失依赖(幂等,可重复运行) |
| 同时下载浏览器内核(约 560 MB,需联网) |
| 指定 PyPI 镜像( |
| 单步超时(秒,默认 1800) |
| 前台启动 sidecar(自动带 |
| 删除虚拟环境以便重装 |
npm scripts 等价入口:npm run doctor / npm run setup / npm run sidecar。
🗄️ 批量抓取入库(tools/chictr_crawl.py)
需要把某个疾病的全量试验落成本地数据时用这个脚本。它随包分发
(node_modules/chictr-mcp-server/tools/chictr_crawl.py),只走 sidecar,
不碰浏览器与 TLS 指纹,因此必须先让 sidecar 跑起来。
# 1) 起 sidecar(另开一个终端,保持前台运行)
npx chictr-mcp-server sidecar
# 2) 先预览规模(只拉列表,不抓详情)
python3 node_modules/chictr-mcp-server/tools/chictr_crawl.py --keyword 胰腺癌 --list-years
# 3) 正式抓取 → SQLite(结构化字段 + 原始 HTML 双存)
python3 node_modules/chictr-mcp-server/tools/chictr_crawl.py --keyword 胰腺癌
# 4) 导出(JSON 不含原始 HTML;HTML 单独落盘便于核对原文)
python3 node_modules/chictr-mcp-server/tools/chictr_crawl.py --keyword 胰腺癌 --export-json
python3 node_modules/chictr-mcp-server/tools/chictr_crawl.py --keyword 胰腺癌 --export-html参数 | 说明 |
| 检索关键词,默认 |
| 只抓指定年份,如 |
| 只统计各年条数并估算耗时,不抓详情 |
| 请求间隔秒,默认 0.6 |
| 强制重抓已存在的记录(默认跳过) |
| 自定义输出路径 |
| 导出 JSON / 独立 HTML 文件 + |
增量行为:去重键是 project_id(不是注册号)——2018 年前注册的试验
ChiCTR 没发注册号(列表里该字段为 null),只按注册号去重会把 2010–2017
的记录整批丢掉(实测少 31 条)。重跑脚本只补缺失项,已抓过的直接跳过,
因此定时重跑即是增量同步。
存储结构:主表 trials 以 project_id 为主键,除全字段 JSON
(fields_json)与原始素材(raw_html / raw_text)外,另把
研究设计/研究疾病/纳入标准/排除标准/研究负责人 等映射为独立列并建索引,
方便直接 SQL 过滤。
📈 性能对比
路径 | 搜索耗时 | 说明 |
旧 Playwright 路径(回退形态) | 45s 超时上限 + 每页 5–10s 人为延迟(另有页间 3–6s、翻页前 2–4s 随机延迟) |
|
sidecar 路径(推荐形态) | 约 1.5s/页,搜索端到端 ~1.5–2.1s,详情 ~2s | 纯 HTTP + cookie 复用,无浏览器 |
端到端响应时间下降约一个数量级,且去掉了原有的随机延迟规避逻辑。
其他基线(实测):
指标 | 数值 |
冷启动过盾 | 4.7 / 5.9 / 6.0 / 6.7s(多次冷启动) |
热态单页检索( | 1.46s |
热态单页检索( | ~1.5s |
详情页 | ~2s |
一次过盾支撑请求数 | ≥ 13( |
并发 | 3 并发 3/3 成功;10 并发 10/10 成功(共 100 条),期间未重新过盾 |
cookie 实际存活 | 约 37.5 分钟(TTL 配置 55 分钟偏乐观,靠内容检测兜底,5.7s 恢复) |
缓存 | 搜索结果 5 分钟,详情 10 分钟;双层 L1 内存 + L2 SQLite |
服务端返回示例
{
"results": [
{
"registration_number": "ChiCTR2500108082",
"title": "谷氨酰胺联合奥沙利铂、卡培他滨(XELOX)和贝伐珠单抗一线治疗KRAS G12D基因突变型晚期结直肠癌的单臂Ⅱ期探索性研究",
"study_type": "干预性研究",
"registration_date": "2025/08/25",
"institution": "浙江大学医学院附属第二医院"
}
]
}🔔 版本更新
v3.0.2 (2026-10-04)
✅ 重写详情页解析器:字段数 29 → 76,平均 21.9 → 58.6 字段/条。根因是旧实现把整页压平成一串文本再用正则猜边界,而详情页实际是标准表格(标签在
<td class="left_title">,值在紧邻的下一个<td>)。改为按表格结构解析后,英文标签不再混入值、值也不再越过相邻字段✅ 补上此前完全缺失的字段:联系人/电话/传真/邮箱/通讯地址/邮编(申请注册联系人与研究负责人各一套)、伦理委员会联系人/地址/电话/邮箱、研究负责人所在单位、国家/省/市/单位(医院)/具体地址、研究所处阶段、组别、标本信息、数据共享与安全监察等
✅ 修复 900 字上限导致超长字段静默丢弃:实测「纳入标准」2242 字、「排除标准」1410 字、「研究实施地点」6964 字,旧正则
(.{0,900}?)匹配不到 → 字段整个消失。上限放宽至 60000✅ 修复老式注册号漏匹配:2018 年前的编号形如
ChiCTR-IIR-17013424,旧正则ChiCTR\d{6,}抓不到。改为ChiCTR(?:-[A-Z]{2,4})?-?\d{4,}✅ 修复区块标题被当作字段:
测量指标/采集人体标本/研究实施地点/申办者/干预措施的值在嵌套子表格里,朴素配对会抽到'组别'、'国家'、'Outcomes'这类伪值✅ 修复空值被兜底正则伪造:页面留空的字段(
研究课题代号(代码)等)会从扁平文本抽到下个标签名,产生'Study subject ID'假值✅ 修复 HTML 实体未解码:部分单元格用字面
 /'书写,导致「具体地址」入库为'上海市 普陀区…'✅ 修复导航栏同名标签误匹配:页面顶部「按经费或物资来源统计」早于正文真实字段(偏移 141 vs 3364),正文起点现定位到「注册号:」之后
✅ 修复复合结局指标块串味:
主要终点旧值会吞掉后续子标签(Measure time point of outcome: …)✅ 校验:对 468 个真实页面逐字段回查 HTML 原文,全库 28809 个字段值 0 处不符、0 处伪造值;重抓 468/468 成功
✅ 修复**「纳入标准」「排除标准」整字段丢失**(发布后复查发现,影响全部记录):两个标签从未进入字段白名单,结构解析直接跳过——尽管单元格配对本身正确。实测覆盖率 0/468,修复后 468/468
✅ 修复**
_TAG_RE吞掉正文中的小于号**:旧正则r"<[^>]+>"把'转导效率<10%…'里的<10%当成标签起点,一路删到后面某个>,导致 9 条记录正文被静默抹掉。收紧为r"</?[A-Za-z!][^>]*>"✅ 修复英文行空值覆盖中文行真实值:同一标签在页面出现两次(中文行 + 英文行),英文行值为空,旧代码的无条件赋值会覆盖中文行的真实值
✅
tools/chictr_crawl.py随包分发(npm install后位于node_modules/chictr-mcp-server/tools/):批量抓取入库脚本,支持--keyword换关键词、--list-years预览规模、--export-json/--export-html导出、按project_id去重、幂等续跑
v3.0.0 (2026-04-10)
✅ 新增 Python sidecar 通道:用 Scrapling(curl_cffi TLS 指纹 + patchright 反检测内核)过一次阿里盾挑战拿到 cookie,之后全程纯 HTTP。搜索从「每页 5–10s」降到 ~1.5s,详情 ~2s
✅ 新增环境自举:
chictr-mcp-server doctor / setup / clean三个 CLI 子命令,一条setup命令即可在干净机器上创建 venv、装依赖、按需装浏览器内核✅ 新增 MCP 工具
check_environment:Agent 可自查本机环境(Python / 依赖 / 浏览器内核 / sidecar 在线状态),按返回的actions决定是否调用setup✅ 修复浏览器惰性初始化:原先任何工具调用都会先拉起 Chromium,导致 sidecar 命中也要付浏览器的代价;现改为仅在真正走 Playwright 时才初始化
✅ npm 包内分发 sidecar 脚本(
sidecar/chictr_sidecar.py),装上即具备 sidecar 能力✅ 修复 Python 版本下限从未生效的问题(
MIN_PYTHON此前未被使用,低版本 Python 会被误判为「就绪」)✅ 缓存清除工具不再附带旧的随机延时(sidecar 通道下不再需要人为降速)
v2.0.2 (2026-04-09)
✅ 修复详情空对象缓存命中问题(自动失效并重查)
✅ 进一步提升详情查询的有效内容获取稳定性
v2.0.1 (2026-04-09)
✅ 修复 Cherry Studio 场景下
./cache路径导致的启动失败(ENOENT)✅ 默认缓存路径调整为
~/.chictr/cache/chictr_cache.db✅ 增加
/tmp/chictr/cache/chictr_cache.db兜底路径
v2.0.0 (2026-04-09)
✅ 新增请求编排层(限速/重试/熔断)
✅ 新增 Session 池化与生命周期回收
✅ 新增挑战状态机与恢复工具(get_access_state / prepare_verification_session / resume_after_verification)
✅ 新增双层缓存(L1 内存 + L2 SQLite)与 get_cache_stats_v2
v1.2.1 (2025-01-17)
✅ 更新 README,添加多维度搜索示例
✅ 添加版本升级指南
✅ 提供 Cherrystudio 缓存清除方案
v1.2.0 (2025-01-17)
✅ 新增按注册号搜索(registration_number 参数)
✅ 新增按年份搜索(year 参数,默认当前年份)
✅ 所有搜索参数改为可选
✅ 修复详情查询 400 错误(使用正确的 project_id)
v1.1.0 (2025-01-17)
✅ 修复分页功能,支持多页结果获取
✅ 支持代理配置(HTTP_PROXY/HTTPS_PROXY)
✅ 增加验证码检测与友好错误提示
🛠️ 技术栈
层 | 技术 |
Node 侧 | TypeScript、MCP SDK、Cheerio、node-cache、better-sqlite3、Playwright |
Python sidecar | Python ≥ 3.10、Scrapling( |
⚠️ 已知限制
诚实记录,未解决或未验证的项:
Node 侧 Playwright 回退路径在本机不可用,且补装内核也无意义:Node playwright 1.62.1 需要
chromium-1234,而缓存里只有chromium-1243(Python 侧 patchright 用的)。 但真正过不了阿里盾的是原生 Playwright,不是缺内核 ——dev/browser-removal/WAF_RESEARCH.md记录的「真实 Chromium 同样卡死」正是用原生 Playwright +page.setContent()得到的; 能过盾的是 patchright(反检测补丁)+ 真实导航。因此不建议补装 Node 侧内核(多约 359MB 换来一个仍会失败的路径,还会引入两套 Chromium 内核互相冲突),正确做法是把 sidecar 视为唯一路径。doctor里该项显示 ❌ 属预期,不影响退出码(src/runtime/env-probe.ts:391注明 Playwright 是「可选回退路径,不是故障」)。cookie 过期边界:实测存活约 37.5 分钟 < TTL 配置的 55 分钟。靠内容检测 + 重试恢复 (实测 5.7s),但 TTL 只是一个乐观的提前刷新信号。
并发上限未探明:只测到 10 并发(10/10 成功)。
ChictrClient._lock串行化了底层 HTTP 会话(curl_cffi session 非线程安全),所以并发是「排队」而非真并行。请勿盲目加大。长驻稳定性未验证:
StealthySession长时间运行的稳定性未测(当前每次过盾新建一次 浏览器上下文并退出)。请求频率上限未测:阿里盾在更高 QPS 下是否二次拦截未知。
研究实施时间字段含中英对照噪音:值为'从 \n From \n 2024-01-01 00:00:00 至 \n To \n 2027-01-01 00:00:00'形态,中英标签夹在值中间。已不再是「粘连下一个字段」,但含英文对照 文本,需要时可自行剥离From/To。ICTRP 双通道尚未实现:
dev/browser-removal/DUAL_CHANNEL_ARCHITECTURE.md是设计稿; 本项目当前没有 WHO ICTRP 通道,也没有source=参数。headless 模式下无法手动处理验证码:频繁请求仍可能触发滑动验证码。
⚖️ 合规说明
ChiCTR 在 re3data 登记为数据访问
restricted,站点页脚为All rights reserved.。无官方 API、无 bulk 下载通道。
因此:「可获得 ≠ 可再分发」。 本项目定位为受控环境下的个人研究/情报用途, 不做数据再分发。若要长期依赖 ChiCTR 直连,建议同时推进对
chictr-s7@wchscu.cn的正式授权问询。绕过 WAF 是与站点访问决策的对抗,属政策判断而非技术判断 —— 技术结论是 「访问可行」,合规判断请自行确认。相关背景见
dev/browser-removal/SCRAPLING_SOLUTION.md§6 与SIDECAR_RUNBOOK.md。
📄 许可证
MIT License
🙏 致谢
本项目使用中国临床试验注册中心 (ChiCTR) 的公开数据,感谢 ChiCTR 为医学研究做出的贡献。 特别感谢小胰宝和小x宝社区的❤️贡献与付出,用爱心与人工智能为癌症/罕见病患者及其家庭提供支持!
📞 相关文档
文件 | 说明 |
| 过盾可行性三层实测证据(含复现命令) |
| sidecar 运维手册 |
| sidecar 端到端验证报告与实测数据 |
| 开箱即用部署指南(dmg / exe) |
| 双通道降级架构(设计稿) |
| sidecar 实现(过盾 + 解析 + HTTP 服务) |
| Node 侧客户端(默认关闭,失败自动回退) |
如有问题,请提交 GitHub Issue。
Available Tools
4 toolsclear_cacheB
清除所有缓存数据
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. '清除所有缓存数据' implies a destructive mutation (clearing all cache), but it doesn't specify whether this action is reversible, requires authentication, has side effects (e.g., temporary slowdown), or returns confirmation. For a mutation tool with zero annotation coverage, this is a significant gap in safety and operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence ('清除所有缓存数据') with zero waste. It's front-loaded with the core action and resource, making it immediately understandable. No extraneous words or structural issues are present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (destructive mutation with no parameters) and lack of annotations/output schema, the description is incomplete. It doesn't cover behavioral aspects like permissions needed, confirmation process, or impact on system performance. For a tool that clears all cache data, this minimal description leaves critical operational gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters, and schema description coverage is 100% (empty schema). The description doesn't need to explain parameters, as there are none. It appropriately focuses on the tool's action without redundant parameter details, meeting the baseline for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description '清除所有缓存数据' (Clear all cache data) clearly states the tool's action and resource with a specific verb ('清除' - clear) and target ('所有缓存数据' - all cache data). It distinguishes from sibling tools like 'get_cache_stats' (read-only) and 'search_trials' (different resource), though it doesn't explicitly mention these distinctions. The purpose is unambiguous but lacks explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., admin permissions), consequences (e.g., performance impact), or when to avoid it (e.g., during peak usage). With siblings like 'get_cache_stats' for monitoring, the description fails to help the agent choose between read and write operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cache_statsB
获取缓存统计信息,包括搜索缓存和详情缓存的命中率等
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. While it mentions what statistics are retrieved (hit rates for search and detail caches), it doesn't disclose important behavioral traits like whether this requires authentication, rate limits, what format the statistics are returned in, or whether this is a read-only operation. The description is minimal and lacks operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that states the purpose without unnecessary elaboration. It's appropriately sized for a zero-parameter tool that retrieves statistics, though it could be slightly more structured by explicitly stating it's a read operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, no annotations, and no output schema, the description provides basic purpose information but lacks important context. For a statistics retrieval tool, it should ideally mention the format of returned data, whether it's real-time or cached statistics, and any authentication requirements. The description is minimally adequate but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has 0 parameters with 100% schema description coverage, so the baseline is 4. The description appropriately doesn't discuss parameters since none exist, and the schema already fully documents this (empty object).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: '获取缓存统计信息' (get cache statistics) with specific mention of '搜索缓存和详情缓存的命中率等' (hit rates for search cache and detail cache). It uses a specific verb ('获取' - get) and resource ('缓存统计信息' - cache statistics), though it doesn't explicitly distinguish from sibling tools like clear_cache.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. There's no mention of when this tool should be used, when it shouldn't, or how it relates to sibling tools like clear_cache, get_trial_detail, or search_trials.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trial_detailB
根据注册号查询临床试验的完整详细信息
| Name | Required | Description | Default |
|---|---|---|---|
| registration_number | Yes | 临床试验注册号,如 'ChiCTR2400084905' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states this is a query operation, implying it's likely read-only and non-destructive, but doesn't explicitly confirm this or describe other traits like error handling, rate limits, authentication needs, or what constitutes '完整详细信息' (complete detailed information) in the response. For a tool with zero annotation coverage, this leaves significant gaps in understanding its behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that directly states the tool's purpose without any wasted words. It's appropriately sized for a simple lookup tool and front-loaded with the core functionality, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (one required parameter, no nested objects) and high schema coverage, the description is adequate but has clear gaps. It lacks output schema information, so the agent doesn't know what '完整详细信息' entails in the response. Combined with no annotations and minimal behavioral context, this leaves the description incomplete for optimal agent use, though it meets minimum viability for a simple query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds minimal semantic context beyond the input schema. It mentions the parameter '注册号' (registration number), which aligns with the schema's 'registration_number' property. However, with 100% schema description coverage (the schema already documents the parameter as '临床试验注册号,如 'ChiCTR2400084905''), the description doesn't provide additional details like format examples or usage nuances. This meets the baseline score of 3 when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: '根据注册号查询临床试验的完整详细信息' (Query complete detailed information of clinical trials based on registration number). It specifies the verb ('查询' - query) and resource ('临床试验的完整详细信息' - complete detailed information of clinical trials), making the purpose unambiguous. However, it doesn't explicitly differentiate from sibling tools like 'search_trials', which might have overlapping functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'search_trials' or clarify scenarios where this tool is preferred (e.g., for looking up specific trials by exact registration number versus broader searches). There's also no information about prerequisites or exclusions, leaving usage context implied at best.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_trialsC
搜索ChiCTR临床试验。支持按标题关键词、注册号、年份进行搜索,返回试验列表。
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | No | 注册题目关键词,如 'KRAS G12C'、'胰腺癌' 等(可选) | |
| registration_number | No | 临床试验注册号,如 'ChiCTR2500111173'(可选) | |
| year | No | 注册年份,如 2024、2025,默认为当前年份(可选) | |
| max_results | No | 最大返回结果数,默认20 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. While it mentions the search functionality and return format (trial list), it lacks important behavioral details: whether this is a read-only operation (implied but not stated), any rate limits, authentication requirements, pagination behavior beyond max_results, or what happens when no results are found. The description provides basic functional information but misses key operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately concise - a single sentence that efficiently communicates the core functionality. It's front-loaded with the main action (searching ChiCTR clinical trials) followed by the search criteria and return format. There's no wasted language, though it could potentially benefit from slightly more detail given the lack of annotations and output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of a search tool with 4 parameters, no annotations, and no output schema, the description is incomplete. While it covers the basic 'what', it lacks important context: what the returned trial list contains, how results are ordered, whether all parameters are optional (implied but not stated), error conditions, or any limitations of the search functionality. The absence of output schema means the description should ideally provide some indication of return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions the three main search parameters (title keywords, registration number, year) which aligns with the input schema's properties. However, with 100% schema description coverage, the schema already provides excellent parameter documentation including examples and defaults. The description adds minimal value beyond what's in the schema - it confirms the parameter purposes but doesn't provide additional context about parameter interactions, search logic, or edge cases.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: searching ChiCTR clinical trials with specific search criteria (title keywords, registration number, year) and returning a list of trials. It uses specific verbs ('搜索' - search, '返回' - return) and identifies the resource (ChiCTR临床试验). However, it doesn't explicitly differentiate from sibling tools like 'get_trial_detail' which likely retrieves detailed information about a specific trial rather than searching multiple trials.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. While it mentions what the tool does, it doesn't indicate when it's appropriate to use search_trials versus get_trial_detail (which presumably gets details for a specific trial) or other siblings. There's no mention of prerequisites, limitations, or typical use cases beyond the basic functionality.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.2.1- First observed
clear_cache - First observed
get_cache_stats - First observed
get_trial_detail - First observed
search_trials
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose with no overlap: clear_cache removes data, get_cache_stats retrieves performance metrics, get_trial_detail fetches a single trial by ID, and search_trials finds multiple trials based on criteria. An agent can easily differentiate these functions.
All tool names follow a consistent verb_noun pattern in snake_case: clear_cache, get_cache_stats, get_trial_detail, and search_trials. This uniformity makes the set predictable and easy to understand.
With 4 tools, the count is reasonable for a ChiCTR trials server, covering core operations like search and detail retrieval. It feels slightly thin but not inadequate, as it supports basic workflows without bloat.
The toolset covers search and detail retrieval for trials, plus cache management, but lacks update or creation tools for trials, which might be expected in a full CRUD lifecycle. This gap could limit agent actions in dynamic scenarios.
Maintenance
Related MCP Connectors
Clinical trial search and status from ClinicalTrials.gov
Search ClinicalTrials.gov: find studies, retrieve results, match patients to candidate trials.
Search and analyze ClinicalTrials.gov: trials by keyword/condition/drug/status/phase, one study's…
Search and monitor ClinicalTrials.gov and EU trial registry records, with trial change tracking and
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables searching and retrieving information from the ClinicalTrials.gov database of over 400,000 clinical studies, including trial details, eligibility criteria, locations, and results across 220+ countries.5-
- AlicenseBqualityDmaintenanceEnables searching and querying clinical trials from ClinicalTrials.gov with intelligent filtering for recruiting studies, geographic search, and detailed trial information including contacts and eligibility criteria.36 npm6MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search and access clinical trial data from ClinicalTrials.gov, including searching trials by keywords, retrieving detailed trial metadata by NCT ID, and managing trial data in CSV format for research and analysis.17-
- FlicenseNot gradedqualityDmaintenanceEnables searching and retrieving detailed clinical trial information from ClinicalTrials.gov via the official API.1-