内容
align="center">
<br/>
<picture>
<source media="(prefers-color-scheme: darkset="docs/header-dark <img src="docs/cdisc-mcp.png"CDISC MCP" width="728">
</picture>
<br/>
**CDISC 库 MCP 服务器** — 直接从 AI 助手查询临床数据标准(SDTMM、CDASH)。
<br/>
[](https://python.org)
[](https://github.com/jlowin/fastmcp)

[](tests/)
[](https://library.cdisc.org)
<br/>
**🌐 翻译:** [中文 README](docs/README.zh.md) · [日本語 README](docs/README.ja.md)
<br/>
</div>
---
## 这是什么?
**CDISC MCP 服务器** 将 AI 助手(Claude、VS Code Copilot、Cursor 等)连接到 [CDISC 库 REST API](https://library.cdisc.org),公开了 11 种用于查询临床试验数据标准的工具。向您的 AI 助手提问,例如:
> *"SDTM AE 域中有哪些变量?"/m*
> *"在 ADaM IG 1.3 中显示 ADSL 变量"*
> *"列出所有可用的受控术语包"*
有关完整的设置说明,请参阅 **[用户手册 →](docs/user-manual.md)**。有关实际对话示例,请参阅 **[示例 →](docs/examples.md)**。
---
## 快速入门
### 0 · 一键 AI 安装
让 AI 助手为您安装所有内容:
```bash
curl -fsSL https://raw.githubusercontent.com/Teninq/cdisc-mcp/main/install.md
```
> 将输出粘贴到 Claude、Copilot 或任何 AI 聊天中 - 它将读取指南并交互式地引导您完成整个设置过程。
---
### 1 · 获取 CDISC 库 API 密钥
在 **https://library.cdisc.org** 注册并获取个人 API 密钥。
### 2 · 安装
```bash
# 仅运行时
pip install -e .
# 带有开发依赖项
pip install -e ".[dev]"
# 带有 Web 资源管理器
pip install -e ".[web]"
```
### 3 · 设置 API 密钥
```bash
# Linux / macOS
export CDISC_API_KEY=your_key_here
# Windows — 命令提示符
set CDISC_API_KEY=your_key_here
# Windows — PowerShell
$env:CDISC_API_KEY = "your_key_here"
```
### 4 · 运行
```bash
# 启动 MCP 服务器(用于 AI 助手集成)
cdisc-mcp
# 或:启动 Web 资源管理器(快速交互式测试)
python web/app.py
```
---
## Web 资源管理器 — 快速交互式测试
无需任何 AI 客户端即可验证您的设置并探索工具 **的最快。
```bash
# 1. 安装 Web 依赖项
pip install -eweb]"
2. 设置您的 API
export CDISC_API_KEY=your_key_here Linux/macOS
set_API_KEY=yourere # Windows CMDenv:CDISC_API "your_key_here Windows PowerShell
3. 启动桥接python web/app.py 4. 在浏览器
# → http:8080
```
资源管理器提供:
- **栏导航** —11 种工具按标准SDTM / ADaM / CDASH / 术语)
- **自动生成的表单 版本和域的下拉变量的文本输入 **实时 JSON 响应** — 语法高亮、可复制的输出,带有响应- **桥接状态指示器** — 确认 密钥和连接性
> **提示:**破折号的版本 `3-4` `3.41-3`1.3> 示例:SDTM-IG `3-4ADaM-IG-3`,CDASH-IG `2----
## 可用工具 # | 工具 | 标准 | 描述 |
|---|------|----------|-------------|
| 1 | `list_products` | — | 列出所有可用的 CDISC 标准和已发布的| 2 | `dtm_domains SDTM | 列M-IG所有数据集 |
| `get_sdtm` | SDT 列出 SDT域/数据集中的所有| 4 | `dtm_variable`M | 获取特定M 变量的 |
| 5 | `get_adam_datas` | ADaM | 列出 ADaM-IG 版本中的所有数据结构 |
| 6 | `get_adam_variable` | ADaM | 获取特定 ADaM 变量的定义 |
| 7 | `get_cdash_domains` | CDASH | 列出 CDASH-IG 版本中的所有域 |
| 8 | `get_fields` | CDASH | 获取 CDASH 域的所有数据收集字段 |
| 9 | `list_ct_packages` | CT | 列出所有可用的受控术语包 |
| 10 | `get_codelist` | CT | 获取 CT 代码列表的定义和元数据 |
| | `get_codel` | CT | CT 代码列表中的所有有效术语 |
### 版本参考
| 标准 | 可用版本(使用破折号) |
|----------|--------------------------------|
| SDTM-IG | `3-4` · `3-3` · `3-2` · `3-1-3` |
| ADaM-IG | `1-3` · `1-2` · `1-1` · `1-0` |
| CDASH-IG | `2-1` · `2-0` · `1-1-1` |
---
## 连接到 AI 助手
### Claude 桌面版
添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"cdisc": {
"command": "cdisc-mcp",
"env": {
"CDISC_API_KEY": "your_key_here"
}
}
}
}
```
### VS Code / Cursor
添加到 `.vscode/mcp.json` 或等效的 MCP 配置:
```json
{
"servers": {
"cdisc": {
"command": "cdisc-mcp",
"env": {
"CDISC_API_KEY": "your_key_here"
}
}
}
}
```
### Claude 代码(CLI)
Claude 代码在两个范围内支持 MCP 服务器:**用户**(全局,所有项目)和 **项目**(本地,仅当前项目)。
**选项 A — CLI 命令(推荐)**
```bash
# 全局添加(在所有项目中可用)
claude mcp add cdisc-mcp -e CDISC_API_KEY=your_key_here -- python -m cdisc_mcp.server
# 仅为当前项目添加
claude mcp add cdisc-mcp --scope project -e CDISC_API_KEY=your_key_here -- python -m cdisc_mcp.server
# 验证服务器是否已注册
claude mcp list
```
**选项 B — 直接编辑 `~/.claude.json`**
```json
{
"mcpServers": {
"cdisc-mcp": {
"command": "python",
"args": ["-m", "cdisc_mcp.server"],
"env": {
"CDISC_API_KEY": "your_key_here"
}
}
}
}
```
> **提示:** 如果 `CDISC_API_KEY` 已存在于您的系统环境中,请省略整个 `env` 块 — Claude Code 自动继承它。
注册后,在任何 Claude Code 会话中用 `/mcp` 确认,然后对话式地使用工具:
```
用户:SDTM 3.4 版本中定义了哪些域?
Claude:[调用 get_sdtm_domains,版本="3-4"] ...
```
---
## 在您自己的 Python 工具中使用
您可以使用官方 MCP 客户端 SDK 从任何 Python 脚本以编程方式调用 CDISC MCP 工具。
### 安装客户端
```bash
pip install mcp
```
### 最小示例
```python
import asyncio
import os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
SERVER = StdioServerParameters(
command="python",
args=["-m", "cdisc_mcp.server"],
env={"CDISC_API_KEY": os.environISC_API_KEY"]},
)
async def main():
async with stdio_client(SERVER) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 列出所有可用工具
tools = await session.list_tools()
print([t.name for t in tools.tools])
# 调用工具
result = await session.call_tool(
"get_sdtm_domains",
arguments={"version": "3-4"},
)
print(result.content[0].text)
asyncio.run(main())
```
### 可重用帮助程序
```python
import asyncio, os, json
from contextlib import asynccontextmanager
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
_SERVER = StdioServerParameters(
command="python",
args=["-m", "cdisc_mcp.server"],
env={"CDISC_API_KEY": os.environ["CDISC_API_KEY"]},
)
@asynccontextmanager
async def cdisc_session():
"""异步上下文管理器,生成已初始化的 MCP 会话。"""
async with stdio_client(_SERVER) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
yield session
async def call(tool: str, **kwargs) -> dict:
async with cdisc_session() as s:
result = await s.call_tool(tool, arguments=kwargs)
return json.loads(result.content[0].text)
# --- 使用示例 ---
async def demo():
# 获取 SDTM 域
domains = await call("get_sdtm_domains", version="3-4")
# 获取 AE 域中的所有变量
variables = await call("get_sdtm_domain_variables", version="3-4", domain="AE")
# 查找单个变量
aeterm = await call("get_sdtm_variable", version="3-4", domain="AE", variable="AETERM")
print(aasyncio.run(d```
### 可用(快速参考)
```python
# 产品
await session.calllist_products", {}DTM
.call_tool("get_domains",": "3"})
await session.call_tool("get_sdtm {"version": "4", "domain": "AE"})
await sessionget_sdt", {"version3-4",": "AE", "AETER)
# ADaM
await session.call_tool_adam_datas", {"version1-3"})
.call_tool("get_adam_variable", {"version": "1-3data_structure": "ADSL", "variable": "USUBJID"})
# CDASH
await session.call_tool("get_cdash_domains", {"version": "2-0"})
await session.call_tool("get_cdash_domain_fields", {"version": "2-0", "domain": "AE"})
# 受控术语
await session.call_tool("list_ct_packages", {})
await session.call_tool("get_codelist", {"package_id": "sdtmct-2024-03-29", "codelist_id": "C66781"})
await session.call_tool("get_codelist_terms", {"package_id": "sdtmct-2024-03-29", "codelist_id": "AGEU"})
```
> **版本格式:** 始终使用破折号,而不是点 — `"3-4"` 而不是 `"3.4"`。
---
## 架构
```
MCP 客户端(Claude / VS Code / Cursor)
│
│ MCP 协议(stdio)
▼
server.py ──── FastMCP 工具注册
│
▼
tools/ ──────── 域函数(sdtm、adam、cdash、术语、搜索)
│
▼
client.py ───── CDISCClient(异步 HTTP · TTL 缓存 · 重试)
│
│ HTTPS
▼
library.cdisc.org/api ──── CDISC 库 REST API
```
**关键设计决策:**
- `CDISCClient` 是具有 1 小时 TTL 内存缓存的单例异步 HTTP 客户端
- 仅重试 `429` 和 `5xx` 响应;`4xx` 立即引发
- 工具函数是纯异步的 — 无需修补即可独立测试
- `format_response()` 删除 HAL `_links` 元数据,提取结构化数据以供 LLM 使用
---
## 开发
**开发工作流程(devel-first,分支和合并 SOP):** [贡献指南](TRIBUTING.md 运行测试
# 具有的全套测试(80%)
pytest定模块
/test_tools.py tests.py -v
个测试
/test_tools.py::test_list_products -v
代码质量
``` check src/ # 静态代码检查
mypy # 类型检查### GitHub 分(必需检查) `main` 分以要求:
- `CI Tests / tests`
- `CI Lint / lint`
- `CI Types / types`
### 项目结构
```
src/cdisc_mcp/
├── server.py # FastMCP 服务器 + 工具注册
├── client.py # 异步 HTTP 客户端(缓存、重试)
├── config.py # 配置数据类 + 环境加载器
├── errors.py # 身份验证资源未找到速率限制错误
_formatter.py #响应规范化
tools/
├── # list产品目录)
├── sdtm.py # SDTM 域/变量工具
├── adam.py # ADaM 数据结构/变量工具
├── cdash.py # CDASH 域/字段工具
├── terminology.py # CT 包/代码列表工具
└── _validators.py # 路径遍历保护
web/
├── app FastAPI 桥接服务器
└.html # 单文件浏览器资源管理器
test_config.py
├── test_client.py
├── test_response_formatter.py_tools.py
.py
└_server.py
许可证
许可证。
---
<div">
为使用 标准工作的临床而建。
用户手册](docs/user-manual.md)** · **[示例](docs/examples · **[CDISChttps://library.org)** · **[API 文档](https://www.cdisc.org/cdisc-library/api-documentation)**
</div>