关于 healthclaw-guardrails
HealthClaw Guardrails 是开源参考实现,在 AI Agent 与 FHIR 服务之间提供医疗数据防护层,面向构建健康数据应用的开发者与实施者。它组合 PHI 脱敏、审计、逐步授权和租户隔离,并支持需人工批准的现实操作。
主要功能
- 01读取前脱敏 PHI
- 02记录不可变审计轨迹
- 03写入需要逐步授权
- 04按租户隔离查询
- 05现实操作需独立人工批准
适用场景
- 01在 Agent 访问前隐藏患者标识信息
- 02审计临床数据的读取与写入
- 03要求人工批准电话、短信或表单操作
MCP 相关
该项目作为 MCP 服务及 FHIR 代理,在 AI Agent 与 FHIR 服务之间提供 29 个 MCP 工具,并应用访问防护。它向 MCP 客户端提供经过租户隔离、脱敏和审计的数据访问。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp-server-production-5112.up.railway.app/mcpclaude mcp add --transport http aks129-healthclaw-guardrails https://mcp-server-production-5112.up.railway.app/mcp{"mcpServers":{"aks129-healthclaw-guardrails":{"type":"http","url":"https://mcp-server-production-5112.up.railway.app/mcp"}}}在 Cursor 中打开{"servers":{"aks129-healthclaw-guardrails":{"type":"http","url":"https://mcp-server-production-5112.up.railway.app/mcp"}}}在 VS Code 中打开{"mcpServers":{"aks129-healthclaw-guardrails":{"type":"http","url":"https://mcp-server-production-5112.up.railway.app/mcp"}}}{"mcpServers":{"aks129-healthclaw-guardrails":{"serverUrl":"https://mcp-server-production-5112.up.railway.app/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://mcp-server-production-5112.up.railway.app/mcp需要授权工具
详细介绍
HealthClaw Guardrails
AI Agent 与临床数据之间的开源安全层。
FHIR 标准化了健康数据的结构。MCP 标准化了 AI 连接工具的方式。 但两者之间的防护措施无人制定标准。本项目填补了这一空白。
▶ 观看 90 秒演示
所有记录均为合成数据。对话使用第三方模型运行,是四次尝试中效果最好的一次。尚未获得任何临床医生的认可。制作过程。
快速开始 · MCP 工具 · 示例方案 · 路线图 · Claude 插件 · 架构 · healthclaw.io · 贡献指南 · 开发指南
项目简介: 一个开源参考实现,展示 FHIR × MCP 防护层——包括 PHI 脱敏、 不可篡改审计、逐步升级认证和租户隔离——如何部署在任意 AI Agent 与任意 FHIR 服务之间。本项目以社区项目的形式公开开发,采用 MIT 许可证。它不是产品,也不是推销:如果这个模式有用,就拿去用;如果有问题,请告诉我们或直接修复。
这是一个社区项目。 实施者、临床工作者和标准领域人士提出质疑,能让它发挥最大价值。欢迎提交 Issue、PR,以及“你们的 SDC 提取有误”等批评——请先阅读 CONTRIBUTING.md 和 行为准则。
概览: v2.1.0,包含 29 个 MCP 工具,配有 4,000 多项 Python 测试和 200 多项 Node 测试。
CareAgents 是托管版用户应用:可在网页上使用通行密钥登录、咨询顾问并聊天。提供 iMessage 的地区可以使用;测试版尚未开放 Telegram。
两条端到端流程——真实世界操作需经过可验证的带外关卡,以及表单($populate → 人工审核 → 溯源 PDF)。
标准:FHIR R4 US Core v9 和 R6 v6.0.0-ballot3、HL7 SDC 表单、NQF 0018。
运维功能:实验室结果解读工具($interpret)、护理缺口提醒($care-gaps,内嵌 MCP-App 视图),以及 ChatGPT 连接器的 search/fetch。
连接器:Fasten TEFCA、HealthEx、HBO、Flexpa、Epic、MEDENT、Open Wearables、SMART Health Links。
此外还提供 Claude Code 插件以及 OpenAI/Gemini 适配器。
60 秒快速试用——无需克隆,无需密钥
托管演示会在完整防护层保护下运行合成数据:
# Watch the deployment grade its own guardrails (PHI redaction, audit, step-up, ...):
curl "https://app.healthclaw.io/r6/fhir/\$conformance?format=text"
将任意 MCP 客户端指向公共演示服务——URL 为 https://mcp-demo-production-ee2c.up.railway.app/mcp,
无需密钥——然后提问:“搜索我的健康记录中的实验室结果,并用通俗易懂的语言解释。” 演示服务无需身份验证,但已固定连接到合成演示租户,因此始终只能提供虚假数据。独立的生产环境端点(mcp-server-production-5112)需要部署专属的 Authorization: Bearer <token>——真实记录始终受身份验证保护。托管连接器无法附加此请求头,因此请粘贴上方的演示 URL。
一键安装:
gemini extensions install https://github.com/aks129/HealthClawGuardrails ·
claude plugin marketplace add aks129/HealthClawGuardrails ·
技能见 ClawHub
非开发者? Claude(网页/桌面/手机)、Perplexity、 ChatGPT、Grok、Meta Muse 和 Telegram 的分步指南,以及 10 分钟演示脚本,见 docs/quickstarts/。
已收录于: 官方 MCP Registry(io.github.aks129/healthclaw-guardrails)·
Glama(托管连接器)·
ClawHub(14 项技能)·
Gemini CLI Extensions · agent-skills 发现入口:/.well-known/agent-skills/
版本亮点
完整说明见 Releases。
| 版本 | 亮点 |
|---|---|
| v2.1.0 | 签到版本(说明):checkin 导出会使用 US Core 记录响应 SMART 健康签到请求,且只能通过一次性、绑定受众和约定项目的升级验证令牌访问 · 获得同意后,该导出才包含保险成员、团体和计划 ID · 只有允许列表中的 US Core 和 C4DIC 配置文件声明会离开引擎 · 超出范围或受众的升级验证令牌会被拒绝 · 每条记录都带有仅含代码的来源标签 · “无已知过敏”会作为已记录条目引用,绝不推断 · CareAgents:仅限受邀者参与的 Beta 版、患者连接流程、每人一位助手、通过 iMessage 发短信,以及设有功能标志的签到网页钱包 |
| v2.0.0 | 合成数据 Beta 版本(说明):默认启用防护措施,Grade A 保持不变,文档只声称 main 上确实具备的内容。该版本不包含的内容列于此处:#214 标头门控、MCP OAuth 连接器(关闭)、Curatr 修复轨道(未启用)、仅限受邀者访问的真实记录 · 操作轨道:审批会绑定用户所见负载的摘要,每种操作都有审批页面,拒绝也会作为一条记录保存 · 脱敏清理:移除标识符值,对写入响应进行脱敏,并清除保留的自由文本 · 可部署在真实 FHIR 服务前。 代理现在使用自己的客户端凭证向上游 FHIR 服务进行身份验证,因此 Agent 无需持有凭证 — 提供可运行的 Aidbox 示例,将防护措施部署在 Aidbox 前,并逐项断言属性,而不是只描述它们 · 访问内核 — r6.access 成为唯一的租户读取器、升级验证门控、审计调用和 FHIR 出口,并按蓝图逐一采用 · 安全性:调用方提供的种子包会经过导入门控,而非签发门控(发现并关闭了一条未经身份验证的写入路径) · MCP:会话过期时返回 404,让客户端重新初始化,而不是失败 · 演示数据:多年合成血压历史记录和服务端渲染的趋势图,分别建模家庭和诊所读数 · 将缺陷目录接入 PR 门控,并通过漂移防护措施,将已发布示例自身的声明与运行中的应用进行重放核验 |
| v1.9.0 | CareAgents — 托管式消费者体验:使用通行密钥注册,通过可插拔连接器市场(Fasten、通过 Open Wearables 接入的 Apple Health、示例数据)连接记录,并启动一个可通过网页、Telegram 和 iMessage 访问、带有防护措施的健康 Agent · 顾问注册表 — 将 SmartHealthConnect 的专科领域(健康习惯、完成护理、药物续配、饮食运动)移植为基于受防护工具集的提示词区块,并如实标注延后提供的项目 · 在连接任何真实记录前,由服务端强制执行有版本控制的知情同意(HTTP 428) · 表单轨道端到端上线 — $populate → 逐项人工审核(绝不推断 NKA)→ 带来源戳记的 PDF → 签名的限时链接 · 错误保真度是第七项一致性属性(Grade A = 7/7),通过 Python↔TypeScript 漂移防护措施,在两种 MCP 传输上均得到强化 · MCP Apps — 护理缺口结果会嵌入由引擎提供的 UI(text/html; profile=mcp-app),其唯一的抓取目标是受防护的操作 · 安全加固:生产配置失败时关闭、经身份验证的租户读取、MCP 传输身份验证、Alembic · SmartHealthConnect 已归档(技能冻结于 v1.2.0;顾问是当前的后续版本) |
| v1.8.0 | 真实操作基础 — Agent 可以提议现实世界中的操作(电话、短信、表单),但 commit 只会提交操作(HTTP 202);实际执行要通过单独的审批,该审批需要一次性升级验证凭证和带过期保护的原子认领,因此 Agent 自身的工具链永远无法批准自己的操作(操作轨道不再接受可伪造的 X-Human-Confirmed 标头;直接 FHIR 写入仍接受,这是一个已知缺口,记录在 #214 中) · ActionExecutor 插件注册表 — 约 50 行代码即可在完整防护轨道下添加现实世界能力,无需修改核心代码(扩展该功能) · 强制红旗紧急情况筛查;失败时明确报错的轨道(不进行静默模拟) · 持久化执行 — 尝试账本、提供方协调、外部时钟触发的清理器、只追加的操作事件日志 · 可靠性底线 — 配置预检(GET /r6/ops/preflight)、Postgres CI 流程、MCP 抓取超时、轮询器 409 风暴检测、感知来源的资源身份标识 (tenant, type, id)、Fasten 加固和僵尸任务清理器 · 公开的 ROADMAP 和贡献者入门指南 · 修复:上游 FHIR 错误保真度、质量指标默认使用当前年份 |
| v1.7.0 | 预防性护理缺口引擎(Patient/$care-gaps、USPSTF/ACIP/ADA + eCQM 交叉映射) · 患者连接流程:经身份验证的 Fasten 入门流程会签发由 webhook 门控、具有读取范围、有效期为 30 天的 Agent 令牌 · 处方转移请求(rx_transfer_request,拒绝 Schedule II)— 29 个 MCP 工具 · 各 Agent 快速入门指南(Claude/Perplexity/ChatGPT/Telegram) · HBO 导出→FHIR 转换器 + 内嵌 XML PHI 清理器 · 加固:失败时关闭的 webhook 验证、限定范围的令牌、无服务器写入防护、实时路径契约测试 · 临床修复:SNOMED 糖尿病检测、包含边界值的恐慌阈值、单侧范围如实呈现 |
| v1.6.0 | 实验室参考范围解释器(Observation/$interpret) · NQF 0018 质量指标(Measure/$evaluate-measure) · 任意 Agent 框架适配器(OpenAI/Gemini) · Medplum 前置部署方案 · 基于 2025 AHA/ACC 的 SMBP 分诊 · ruff lint 门控 · 已修复所有依赖项安全公告 |
| v1.5.0 | 读取身份验证加固(租户读取经过身份验证,而非仅限定范围) · HL7 SDC 表单 — $populate / $extract |
| v1.4.0 | 六种健康数据连接器(Fasten TEFCA、HealthEx、Health Bank One、Flexpa、Epic、MEDENT)共用一套防护措施 |
| v1.3.0 | 可穿戴设备 → FHIR Observations(8 家提供方、LOINC/UCUM 映射、设备 Provenance) |
| v1.2.0 | 编译后的事实 — 每项资源的当前状态 + 只追加的 Provenance 轨迹 |
功能说明
这是一个厂商中立的防护代理,位于任意 AI Agent 与任意 FHIR 服务之间。每个请求都会经过以下处理:
- PHI 脱敏——姓名截短为首字母,移除标识符值(保留系统和类型),删除地址,出生日期截短至年份
- 不可变审计记录——记录每次读取和写入的租户、Agent 和时间戳
- 升级授权——写入操作需要 HMAC-SHA256 令牌
- 人在回路中——真实世界操作(通话、短信、表单):
commit只会提交。执行操作需要一个可证明地在带外完成的单次审批,并与该操作绑定;Agent 自己的工具链无法满足此条件。直接临床 FHIR 写入会返回 HTTP 428,直到存在X-Human-Confirmed标头。调用方可以设置该标头,因此它并非人工审核关卡:这是一个已知缺口,已在 #214 中跟踪 - 租户隔离——每个查询都限定在租户范围内,并阻止跨租户访问
- 医疗免责声明——读取所有临床资源时都会注入
- 编译后的事实——每个资源的当前状态和仅追加的证据记录
AI Agent ──▶ MCP Server ──▶ Guardrail Proxy ──▶ Any FHIR Server
↓ (HAPI, Epic,
PHI redaction Medplum, etc.)
Audit trail
Step-up auth
Human-in-the-loop
与普通 FHIR MCP 服务的区别
| 典型的 FHIR MCP 服务 | HealthClaw | |
|---|---|---|
| 模型接收数据前的脱敏 | 返回服务端存储的记录 | Agent 查看记录前:姓名截短为首字母,移除标识符值,删除地址,出生日期截短至年份 |
| 每次访问的审计记录 | 交由其后端的 FHIR 服务处理 | 每次读取和写入都会记录一个 AuditEvent,详情不含 PHI |
| 写入操作的升级授权 | 会话凭据涵盖写入操作 | 每次写入都需要与租户绑定的 HMAC 升级令牌 |
| 通话、短信和表单的带外审批 | 不在范围内 | Agent 只提出操作。用户在单独的页面上审批,审批与其所查看的有效负载绑定 |
| 租户隔离 | 一个凭据对应一个服务器视图 | 每个查询都限定在租户范围内;拒绝跨租户访问 |
直接临床 FHIR 写入是审批一项的例外:它们仍受调用方设置的标头控制(#214)。
验证:防护措施符合性
这些防护措施可以验证,并非营销说辞。 可运行的测试工具会使用合成数据探测任何部署,并生成涵盖全部七项属性的评分卡——可在你自己的实例(或我们的实例)上运行:
python scripts/guardrail_conformance.py \
--base-url https://app.healthclaw.io --tenant desktop-demo \
--step-up-token "$(mint a token via POST /r6/fhir/internal/step-up-token)"
HealthClaw Guardrail Conformance — https://app.healthclaw.io [tenant=desktop-demo]
Grade: A (7/7 properties)
[PASS] PHI Redaction [PASS] Human-in-the-Loop
[PASS] Immutable Audit Trail [PASS] Tenant Isolation
[PASS] Step-Up Authorization [PASS] Medical Disclaimers
[PASS] Error Fidelity — A (local-fhir-only)
也可以访问任何运行中部署的单 URL 自测——无需令牌;它会在内部为自身设置租户,并在达到 A 级时返回 200(否则返回 503):
curl "https://app.healthclaw.io/r6/fhir/\$conformance?format=text"
本地 FHIR 配置达到 A 级:根据 Prefer: handling 拒绝或报告不受支持的本地搜索输入,并审计每条失败路径。同一测试工具也会针对 Flask 测试客户端运行,作为 CI 基准(tests/test_guardrail_conformance.py)。--json 会生成机器可读报告;--mcp-url 还会将 MCP tools/call 错误信号作为单独配置进行评级。对于经过身份验证的 MCP 部署,请设置 MCP_AUTH_TOKEN 或传入 --mcp-auth-token。库 API:
from r6.conformance import LiveProbeClient, ProbeContext, run_conformance。
这个评级意味着什么(以及不意味着什么)
此评级仅涵盖 HealthClaw 防护层——针对刚创建的合成数据,对七项属性进行自测。它不是 HIPAA 安全规则评估、第三方审计或对你部署的渗透测试:基础设施、BAA、静态/传输中加密以及访问控制仍由部署者负责(参见已知限制)。由于该测试工具与部署无关,第三方可以将其用于任何实例,作为正式评估的一项依据——但它不能替代正式评估。每种输出格式的报告都会说明这一范围。
安装为 Claude 插件
HealthClaw 以 Claude Code 插件市场的形式提供。现有两个插件:
# Add the marketplace
claude plugin marketplace add aks129/HealthClawGuardrails
# Install the FHIR guardrail plugin (this repo)
claude plugin install healthclaw-guardrails@healthclaw-marketplace
# Install the personal-health companion plugin (frozen — upstream archived)
claude plugin install smarthealthconnect@healthclaw-marketplace
| 插件 | 技能 | 来源 |
|---|---|---|
healthclaw-guardrails | curatr, fasten-connect, fhir-r6-guardrails, fhir-upstream-proxy, healthex-export, phi-redaction | aks129/HealthClawGuardrails |
smarthealthconnect | care-completion, diet-exercise, healthy-habits, kids-health, medication-refills, research-monitor | aks129/SmartHealthConnect (已归档 — 技能冻结在 v1.2.0;后续版本为 CareAgents 顾问) |
每项技能都可自动发现——当你的提示词匹配技能的触发短语时(例如“检查我的护理缺口”“对这个 bundle 进行脱敏”“对我的病情运行 Curatr”),Claude 就会加载该技能。
未使用 Claude/MCP? 相同的 28 个带防护措施的工具,也可以通过 adapters/ 中与框架无关的桥接,在 OpenAI、Gemini、LangChain 或纯 HTTP 上运行——请参阅指南:在任何 Agent 框架上运行 HealthClaw 工具。防护措施保留在服务端,因此任何框架都无法绕过。
快速开始
# Install dependencies
uv sync
# Apply deterministic database migrations
STEP_UP_SECRET=your-secret uv run flask --app main init-db
STEP_UP_SECRET=your-secret uv run flask --app main seed-demo --tenant-id desktop-demo
# Run (local mode with SQLite)
STEP_UP_SECRET=your-secret python main.py
# Run with upstream FHIR server
FHIR_UPSTREAM_URL=https://hapi.fhir.org/baseR4 STEP_UP_SECRET=your-secret python main.py
# Open browser
open http://localhost:5000 # Landing page with live demo
open http://localhost:5000/r6-dashboard # Interactive dashboard
Docker
docker-compose up -d --build
# macOS note: port 5000 conflicts with AirPlay Receiver — remap with:
# HOST_PORT=5050 docker-compose up -d --build
# Services:
# - fhir-mcp-guardrails (Flask, port 5000)
# - agent-orchestrator (MCP server, port 3001)
# - redis (port 6379)
MCP 工具(29 个)
为兼容 Claude Desktop / MCP 客户端,工具名称使用下划线(而非点号)。
读取工具(公共租户无需逐步验证):
| 工具 | 描述 |
|---|---|
context_get | 获取预先构建的上下文封装 |
fhir_read | 读取 FHIR 资源(已脱敏) |
fhir_search | 按患者、代码、状态和日期筛选搜索 |
fhir_validate | 结构验证 |
fhir_stats | 观察结果统计(计数/最小值/最大值/平均值) |
fhir_lastn | 获取每个代码最新的 N 条观察结果 |
fhir_interpret_labs | 检验结果参考范围解读($interpret)——用于决策支持,不用于诊断 |
care_gaps | 预防性护理缺口($care-gaps)——根据患者自己的记录,列出可能到期的筛查/免疫接种 |
guardrail_conformance | 运行防护措施一致性自检——针对全部七项属性生成 A–F 评级计分卡 |
fhir_permission_evaluate | R6 Permission 访问控制评估 |
fhir_subscription_topics | 列出可用的 SubscriptionTopics |
questionnaire_populate | SDC $populate — 为对象预填 Questionnaire |
curatr_evaluate | 评估 FHIR 资源中的数据质量问题 |
action_status | 轮询一项现实世界操作(电话/短信) |
search | 兼容 ChatGPT 连接器的搜索——对 fhir_search 的轻量封装,返回精简的 {id, title, url} 结果 |
fetch | 按 ResourceType/id 获取资源,兼容 ChatGPT 连接器——对 fhir_read 的轻量封装,返回 {id, title, text, url, metadata} |
写入工具(需要逐步验证令牌):
| 工具 | 描述 |
|---|---|
fhir_propose_write | 验证并预览,不提交 |
fhir_commit_write | 通过逐步验证和人工审核后提交 |
questionnaire_extract | SDC $extract — 从已完成的 QuestionnaireResponse 中提取资源 |
curatr_apply_fix | 应用经患者批准的修复,并跟踪 Provenance |
action_propose / action_commit | 提议/提交现实世界的电话或短信 |
rx_transfer_request | 根据当前用药起草药房转接请求电话(拒绝 Schedule II);通过 action_commit 提交 |
shl_generate | 生成加密的 SMART Health Link(QR)。默认关闭:从 tools/list 中隐藏,并在 MCP_ENABLE_SHL_GENERATE=true 之外的情况下拒绝请求 |
实用工具:
| 工具 | 描述 |
|---|---|
fhir_get_token | 签发 5 分钟有效的逐步验证令牌(任何写入操作前调用) |
fhir_seed | 使用示例 Patient + Observations + Condition 为租户填充种子数据 |
fhir_compiled_truth | 当前状态 + Provenance 证据时间线 |
所有工具都会添加 _mcp_summary,其中包含推理、临床背景和限制。
防护栏演示
/r6/fhir/demo/agent-loop 中的 6 步演示展示了完整的防护栏流程:
- PHI 脱敏 — Agent 读取患者数据,接收脱敏后的数据
- $validate 校验门 — Agent 提议创建 Observation,写入前先进行校验
- 权限拒绝 — 不存在 Permission 规则,访问被拒绝并附带原因说明
- 权限允许 — 创建 Permit 规则后,重新评估通过
- 升级验证 + 人机协同 — 写入需要令牌和人工确认
- 提交 + 审计 — 写入成功,并生成完整的审计跟踪
对比
| 功能 | 本项目 | AWS HealthLake MCP | Medplum MCP | 原始 FHIR API |
|---|---|---|---|---|
| 适用于任意 FHIR 服务 | 是 | 仅限 HealthLake | 仅限 Medplum | 不适用 |
| 读取时进行 PHI 脱敏 | 是 | 否 | 否 | 否 |
| 不可变审计跟踪 | 是 | CloudTrail(单独提供) | 部分支持 | 否 |
| 写入时升级验证 | 是 | IAM(单独提供) | Medplum 身份验证 | 否 |
| 人机协同 | 是 | 否 | 否 | 否 |
| Permission $evaluate(R6) | 是 | 否 | 否 | 否 |
| 设置时间 | 10 秒 | 30 分钟以上 | 15 分钟以上 | 不定 |
FHIR 版本支持
| 版本 | 配置文件 | 状态 | 资源 |
|---|---|---|---|
| R4 | US Core v9 | 稳定 | Patient、Condition、AllergyIntolerance、Immunization、MedicationRequest、Procedure、DiagnosticReport、CarePlan、CareTeam、Goal、DocumentReference、Coverage、ServiceRequest、Location、Organization、Practitioner、PractitionerRole、RelatedPerson、Specimen、FamilyMemberHistory |
| R6 | v6.0.0-ballot3 | 实验性 | Permission、SubscriptionTopic、DeviceAlert、NutritionIntake、DeviceAssociation、NutritionProduct、Requirements、ActorDefinition |
R4 和 R6 资源都经过相同的防护栏体系(PHI 脱敏、审计、升级验证、租户隔离)。R6 ballot 资源在最终版本发布前可能会发生变化。
测试
# Python tests (1,490+ across 90+ files; includes action-rail, SDC, quality, labs, ops, CareAgents suites)
uv run python -m pytest tests/ -v
uv run python -m pytest tests/test_r6_routes.py::test_name -v # single test
# MCP server tests
cd services/agent-orchestrator && npm ci && npm test
# Playwright end-to-end tests (UI + API, requires Flask on :5000)
cd e2e && npm ci && npx playwright install --with-deps chromium && npm test
cd e2e && npm run test:headed # headed browser
cd e2e && npm run test:ui # interactive UI mode
API 端点
| 端点 | 方法 | 描述 |
|---|---|---|
/r6/fhir/metadata | GET | CapabilityStatement |
/r6/fhir/health | GET | 存活探针(报告上游状态) |
/r6/fhir/{type} | POST | 创建资源(需要 step-up) |
/r6/fhir/{type} | GET | 搜索资源 |
/r6/fhir/{type}/{id} | GET | 读取资源(已脱敏) |
/r6/fhir/{type}/{id} | PUT | 更新资源(需要 step-up + ETag) |
/r6/fhir/{type}/$validate | POST | 验证资源 |
/r6/fhir/Questionnaire[/{id}]/$populate | POST | SDC — 根据主体预填 QuestionnaireResponse |
/r6/fhir/QuestionnaireResponse/$extract | POST | SDC — 提取事务 Bundle(使用 ?dryRun=true 进行预览) |
/r6/fhir/{type}/{id}/$deidentify | GET | 保守的去标识化预览(需要专家审核) |
/r6/fhir/Observation/$stats | GET | Observation 统计信息 |
/r6/fhir/Observation/$lastn | GET | 最新的观察记录 |
/r6/fhir/Permission/$evaluate | POST | R6 访问控制评估 |
/r6/fhir/SubscriptionTopic/$list | GET | 订阅主题发现 |
/r6/fhir/Bundle/$ingest-context | POST | Bundle 摄取 + 上下文信封 |
/r6/fhir/context/{id} | GET | 获取上下文信封 |
/r6/fhir/AuditEvent | GET | 搜索审计事件 |
/r6/fhir/AuditEvent/$export | GET | 导出审计跟踪(NDJSON/Bundle) |
/r6/fhir/demo/agent-loop | POST | 6 步护栏演示 |
/r6/fhir/oauth/* | * | OAuth 2.1 + PKCE + SMART 发现 |
/r6/fhir/{type}/{id}/$curatr-evaluate | GET | 评估资源数据质量(Curatr) |
/r6/fhir/{type}/{id}/$curatr-apply-fix | POST | 应用患者批准的修复,并附带 Provenance |
本地搜索接受 /r6/fhir/metadata 公布的参数。
未知参数默认采用宽松处理(返回有界的
search.mode="outcome" 警告);Prefer: handling=strict 会返回 400
OperationOutcome。不支持的修饰符和格式错误的受支持值始终会返回 400。_count=0 和 _summary=count 是仅计数搜索。自链接
只包含已应用且经过 URL 编码的参数,审计输出绝不会回显已提交的筛选值或任意参数名称。
上游代理
连接到真实的 FHIR 服务,同时保持所有护栏生效:
FHIR_UPSTREAM_URL=https://hapi.fhir.org/baseR4 python main.py
- 读取:从上游获取,然后进行脱敏、审计并添加免责声明
- 搜索:转发所有查询参数,并对每个结果条目进行脱敏
- 写入:先在本地验证,然后通过 step-up 身份验证检查后转发
- URL 重写:上游 URL 绝不会泄露给客户端
已测试:HAPI FHIR R4/R5、SMART Health IT、Epic Sandbox。
在 FHIR 服务前部署护栏——在 Medplum 前运行脱敏 + 审计 + step-up + 人机协同堆栈的操作指南(同样的模式也适用于 Aidbox、Google Cloud Healthcare 或任何 FHIR R4 服务):docs/recipes/healthclaw-in-front-of-medplum.md。
可重复运行的集成测试(tests/test_medplum_in_front.py)证实,Medplum 返回的 Patient 会经过脱敏和审计,且写入操作在到达 Medplum 前必须通过 step-up 门控。
Curatr — 患者自主掌控的数据质量
Curatr 是一项面向患者的数据质量技能,可评估 FHIR 健康记录中的编码问题, 并由患者决定如何解决。
1. Patient connects data → HealthClaw Guardrails deidentifies and loads it
2. OpenClaw calls curatr.evaluate → checks codes against live terminology APIs
3. Issues presented in plain language with impact and fix suggestions
4. Patient approves fixes → curatr.apply_fix updates resource + creates Provenance
5. Optional: generate a structured correction request for the source provider
Curatr 对 Condition 的检查项:
| 检查项 | 服务 | 示例 |
|---|---|---|
| 已弃用的代码系统 | 本地查询(无需网络) | ICD-9-CM → 严重 |
| ICD-10-CM 代码有效性 | NLM Clinical Tables API | 无效代码 → 警告 |
| SNOMED CT / LOINC 有效性 | tx.fhir.org(HL7 公共服务) | 未知代码 → 警告 |
| RxNorm 药物代码 | RXNAV API(NLM) | 缺少 RXCUI → 警告 |
| 显示名称准确性 | 与规范术语交叉核对 | 不匹配 → 建议 |
| 缺少必填字段 | 结构检查 | 没有 clinicalStatus → 警告 |
每项修复都会创建关联的 Provenance 资源,记录患者意图、字段更改和 Agent 归属。所有更改都会记录在不可变的审计轨迹中。
OpenClaw 技能: skills/curatr/SKILL.md
SMART Health Links(告别剪贴板)
患者可通过 QR 码控制并分享加密记录;该功能基于
jmandel/kill-the-clipboard-skill
(MIT,固定版本 fa0020d)实现 — 致谢 Josh Mandel。HealthClaw 管控哪些内容进入
数据包(升级认证、配置文件、护栏、审计轨迹);KTC 管控分享功能
(零知识服务端存储、SHL STU 1 协议、撤销、浏览器内查看器)。
默认关闭。 shl_generate 不会出现在 tools/list 中,除非操作员设置
MCP_ENABLE_SHL_GENERATE=true,否则调用会被拒绝。患者发起的分享功能正在重新构建,
并将通过同意页面提供。
功能说明: shl_generate MCP 工具(Write 组,需要升级认证)会获取符合患者护栏
要求的 FHIR 数据包,在 MCP 服务端进行客户端加密(SHL 服务永远看不到明文),上传密文,
并返回:
shlink— 用于生成 QR 码的shlink:/URI(加密指针,而非数据)viewer_link— 提供给诊所员工的浏览器 URLmanage_link— 仅供患者使用的撤销和访问日志 URL
安全性: QR 码只包含加密指针。PHI 绝不会出现在 QR 图像中。SHL 服务仅存储密文和
sha256(auth_token)。Persona 硬性规则:参阅 skills/share-health-qr/SKILL.md — 绝不将
PHI 直接编码到 QR 图像中(事件:2026-06-12)。
快速开始(本地)
# Start the SHL storage server (profile `shl`)
docker-compose --profile shl up -d
# Tell the MCP server where the SHL server lives
# Add to services/agent-orchestrator/.env or export:
export SHL_SERVER_URL=http://localhost:8000
如果未设置 SHL_SERVER_URL,shl_generate 会返回明确的模拟占位结果
(simulated: true)——绝不会返回伪造链接。
Railway 部署
# 1. Add the SHL service
railway add --service shl-server
# 2. Attach a persistent volume (SQLite lives here)
railway service shl-server && railway volume add --mount-path /data
# 3. Configure the SHL server
railway variables --service shl-server \
--set BASE_URL=<public-url-of-shl-server> \
--set DB_PATH=/data/db.sqlite
# 4. Expose a public domain
railway domain --service shl-server
# 5. Deploy — MUST run from the shl-server directory
cd services/shl-server && railway up --service shl-server
# 6. Wire the MCP server to the SHL server
railway variables --service mcp-server \
--set SHL_SERVER_URL=<public-url-of-shl-server>
注意 1 — 从正确的目录部署: 仓库根目录的
railway.toml指向 Flask Dockerfile。如果你在仓库根目录运行railway up --service shl-server, Railway 会使用错误的 Dockerfile,导致部署失败。 请务必先运行cd services/shl-server— 该目录下的railway.toml会指向正确的镜像。注意 2 — watchPatterns 跳过部署: 从根目录配置继承了
watchPatterns的服务可能会静默跳过仅涉及 Dockerfile 的部署(未检测到源文件更改)。services/shl-server/中的服务专用railway.toml会在首次成功构建后覆盖此设置。 如果部署被跳过,请在 shl-server 目录中运行railway up --service shl-server强制部署。注意 3 — 模拟模式: 如果 MCP 服务未设置
SHL_SERVER_URL,shl_generate会返回{ simulated: true, note: "SHL_SERVER_URL not configured — returned stub." }。Persona 会原样显示此说明, 绝不会擅自编造替代方案。
OpenClaw 技能: skills/share-health-qr/SKILL.md
R6 特定资源(实验性)
这些资源属于 FHIR R6 ballot3 规范,在正式发布前可能会发生变化。
| 资源 | R6 新增内容 |
|---|---|
| Permission | 访问控制(与 Consent 分开),$evaluate 操作 |
| SubscriptionTopic | 重构后的发布/订阅(R5 引入,R6 逐渐成熟) |
| DeviceAlert | ISO/IEEE 11073 设备警报 |
| NutritionIntake | 膳食摄入跟踪 |
| DeviceAssociation | 设备与患者的关系 |
| NutritionProduct | 营养产品定义 |
| Requirements | 功能需求跟踪 |
| ActorDefinition | 参与者角色定义 |
US Core v9 R4 资源(稳定)
符合 US Core Implementation Guide v9 的标准 FHIR R4 资源。 这些资源已在美国医疗保健领域广泛部署,适用于生产环境。
AllergyIntolerance、Immunization、MedicationRequest、Medication、MedicationDispense、 Procedure、DiagnosticReport、CarePlan、CareTeam、Goal、DocumentReference、 Location、Organization、Practitioner、PractitionerRole、RelatedPerson、 Coverage、ServiceRequest、Specimen、FamilyMemberHistory
环境变量
| 变量 | 必需 | 默认值 | 说明 |
|---|---|---|---|
STEP_UP_SECRET | 生产环境 | — | HMAC-SHA256 签名密钥 |
FHIR_UPSTREAM_URL | 否 | — | 上游 FHIR 服务(启用代理模式) |
SQLALCHEMY_DATABASE_URI | 生产环境 | sqlite:///mcp_server.db | 数据库连接 |
SESSION_SECRET | 否 | (开发密钥) | Flask 会话密钥 |
READ_AUTH_ENABLED | 生产环境 | false | 受保护的读取操作要求凭据绑定租户 |
PUBLIC_TENANTS | 生产环境 | — | 以逗号分隔的合成/演示租户显式允许列表 |
REDIS_URL | 生产环境 | — | 共享 nonce、OAuth、速率限制和工作进程状态 |
MCP_AUTH_TOKEN | HTTP MCP | — | MCP HTTP 传输所需的 Bearer 凭据 |
MCP_PUBLIC_DEMO | 否 | false | 运行一个未经过身份验证、固定绑定到合成演示租户的 MCP 服务(公开的免密演示)。切勿在可访问真实租户的服务上设置此项 |
MCP_DEMO_TENANT | 否 | desktop-demo | 设置 MCP_PUBLIC_DEMO 时,演示服务固定绑定的合成租户 |
FHIR_UPSTREAM_TIMEOUT | 否 | 15 | 上游请求超时时间(秒) |
FHIR_LOCAL_BASE_URL | 否 | — | 用于重写响应 URL 的本地 URL |
WSGI 导入期间绝不会运行数据库 DDL。每次发布前运行 flask --app main init-db
;此命令会应用锁定的 Alembic 修订版。在现有 v1.8.0 Postgres 部署中采用
Alembic 的运维人员,必须遵循数据库迁移操作手册,在升级前验证并
标记兼容性基线。
项目结构
main.py Flask app entry point
app.py Web UI routes (landing, dashboard)
r6/
routes.py R6 FHIR REST Blueprint (1,732 lines)
models.py R6Resource, ContextEnvelope, AuditEventRecord
validator.py FHIR R6 structural validation
redaction.py PHI redaction (names, identifiers, addresses, DOB, telecom)
audit.py Immutable AuditEvent recording
stepup.py HMAC-SHA256 step-up token management
oauth.py OAuth 2.1 + PKCE + SMART-on-FHIR discovery
health_compliance.py Disclaimers, HITL, de-identification preview, audit export
context_builder.py Bundle ingestion + context envelopes
rate_limit.py Per-tenant rate limiting
fhir_proxy.py Upstream FHIR server proxy with URL rewriting
curatr.py Curatr data quality engine (terminology lookups + fix application)
services/agent-orchestrator/
src/index.ts MCP server (Streamable HTTP + SSE)
src/tools.ts 12 tool definitions + executor (incl. curatr.evaluate, curatr.apply_fix)
e2e/ Playwright end-to-end tests
templates/ Jinja2 (landing page, dashboard)
static/ CSS + JS for interactive dashboard
skills/curatr/ Curatr OpenClaw skill definition
tests/ 266 pytest tests (8 files, incl. test_us_core_r4.py)
个人 FHIR 数据存储 — 患者导入流程
本指南介绍如何将原始 HealthEx 导出数据导入,并通过 Claude Code 的 MCP 工具查询 自己的记录。
1. 启动技术栈
uv sync
uv run python main.py # Flask on :5000
cd services/agent-orchestrator && npm ci && npm start # MCP on :3001
2. 导入 HealthEx / Flexpa / 通用 FHIR Bundle
# Dry-run first to preview without writing
python scripts/import_healthex.py \
--bundle-file ~/Downloads/my-records.json \
--dry-run
# Real import — prints context_id on success
python scripts/import_healthex.py \
--bundle-file ~/Downloads/my-records.json \
--tenant-id my-patient \
--step-up-secret "$STEP_UP_SECRET"
3. 通过 MCP 连接 Claude Code
打开项目时,此仓库中的 .mcp.json 会自动配置 Claude Code。
更新 X-Tenant-ID,使其与 --tenant-id 匹配:
{
"mcpServers": {
"healthclaw-local": {
"type": "http",
"url": "http://localhost:3001/mcp",
"headers": { "X-Tenant-ID": "my-patient" }
}
}
}
然后在 Claude Code 中:
Use fhir_search to find all my Conditions
Use context_get with context_id <ctx-id> to get my full context envelope
Use curatr_evaluate on Condition/<id> to check data quality
4. 设置 Fasten Connect(可选)
# .env additions
FASTEN_PUBLIC_KEY=<key>
FASTEN_PRIVATE_KEY=<key>
FASTEN_WEBHOOK_SECRET=<secret>
FASTEN_CURATR_SCAN=true # auto-run Curatr after each import
记录通过 Webhook 到达 /r6/fasten/webhook,并存储在患者的规范租户 ID 下。
5. 去标识化以便共享
# De-identification preview (not a legal Safe Harbor determination)
curl -H "X-Tenant-ID: my-patient" \
http://localhost:5000/r6/fhir/Patient/pt-1/\$deidentify
# Patient-controlled (preserves birthDate, strips institutional identifiers)
curl -H "X-Tenant-ID: my-patient" \
"http://localhost:5000/r6/fhir/Patient/pt-1/\$deidentify?mode=patient-controlled&patient_id=my-patient"
6. Telegram 机器人(可选)
TELEGRAM_BOT_TOKEN=<token> TENANT_ID=my-patient \
FHIR_BASE_URL=http://localhost:5000/r6/fhir \
python openclaw/bot.py
命令:/health、/conditions、/labs、/curatr、/curatr fix、/approve。
也可以通过 Docker Compose:
docker-compose --profile openclaw up -d
7. 使用 Medplum 作为底层 FHIR 存储(可选)
在 .env 中设置(将 FHIR_UPSTREAM_URL 留空):
MEDPLUM_BASE_URL=https://api.medplum.com/fhir/R4
MEDPLUM_CLIENT_ID=<id>
MEDPLUM_CLIENT_SECRET=<secret>
所有防护措施对 Medplum 响应和本地 SQLite 模式完全相同。
访问令牌会缓存在 Redis 中(键 medplum:access_token;Redis 不可用时回退到进程内缓存)。
已知限制
- 一致性等级是对防护层的自测,不是 HIPAA 评估或第三方审计——请参阅 该等级的含义
- 本地模式:JSON blob 存储,使用表扫描搜索(没有索引字段)
- 脱敏采用 HIPAA Safe-Harbor-风格的字段脱敏(人口统计信息),不是专家判定。这是一种补偿性控制,用于移除标识符类别字段(标识符值会被直接移除,不会截断);它不是法律意义上的去标识化判定。生产级去标识化严谨性(特定配置文件的递归允许列表、专家判定路径)已列入路线图(#112)。
- 验证是结构性的,不包括完整的 StructureDefinition/配置文件一致性或术语绑定。这里展示的是防护契约(脱敏 + 审计 + 升级验证 + 人工确认 + 租户隔离 + 错误保真),而非生产级验证深度——相关工作已在 #112 中跟踪。
- 已存储 SubscriptionTopic,但不会分发通知
- 直接写入临床 FHIR 数据没有真正的人工关卡。此类请求会返回 HTTP 428,直到调用方发送
X-Human-Confirmed;但该标头由调用方自行设置,因此无法证明确有人工参与。这是一个已知缺口(#214);请勿基于此构建功能。真正的人工关卡是操作轨道,用于真实世界操作(电话/短信/表单),且不接受该标头。commit只会将操作提交以供带外审批(202awaiting_confirmation)。患者点击 Approve 后,服务端会先使用一次性的ActionConfirmation凭证,再执行任何操作。 - OAuth 端点用于发现和 SMART 广告;路由强制执行依赖升级验证 + 读取授权令牌,自动批准的授权流程仅适用于公共/演示租户(没有逐用户同意屏幕)
- 没有历史版本控制(
version_id会递增,但无法检索旧版本) - 上游代理:不缓存响应,不进行跨版本转换
- 安全性取决于配置——生产环境要求
READ_AUTH_ENABLED=true(对非公共读取进行身份验证)、INTERNAL_TOKEN_MINT_SECRET(为非公共租户设置令牌签发/播种门槛;生产环境未设置时会默认拒绝)、将PUBLIC_TENANTS限定为合成演示租户、使用真实的SESSION_SECRET/STEP_UP_SECRET,以及仅使用 https 上游 - 升级验证令牌在 5 分钟 TTL 内可用于多次写入(不是一次性令牌);不可逆操作依赖状态机幂等性(通过
WHERE status='proposed'条件进行保护性认领),而不是消耗 nonce
贡献——这是社区共同努力的成果
HealthClaw Guardrails 以开源方式开发,作为共享参考,而非商业产品。 只有许多来自不同视角的人对 AI Agent 与临床数据之间的防护层进行压力测试,它才能值得信赖。我们尤其欢迎:
- 实施者:构建 FHIR × MCP 集成——告诉我们这些模式在现实中会在哪里失效。
- 临床医生和合规从业者:审视脱敏配置文件、审计模型和文档中所述的 HIPAA 合规立场。
- 标准领域人士(HL7 / SDC / SMART):告诉我们偏离规范之处,尤其是
$populate/$extract方面。 - 任何人:提出 issue、指出“这里错了”,或提交 PR。
从这里开始:贡献指南 · 路线图 · 开发指南 · 行为准则 · 更新日志 · 安全政策
Issue 跟踪器中标注了适合新手的贡献。贡献须通过 DCO 签署(git commit -s),并遵循 MIT 许可证——有关项目未来的许可立场,请参阅 LICENSING.md。
社区
- GitHub 讨论 — 提问、交流想法、展示成果。
- 适合新手的问题 — 范围明确、约 15 分钟即可开始的贡献。
- 基于 OpenClaw 或 Hermes 构建?这些技能位于 ClawHub;MCP 服务收录于 Hermes 目录。
许可证
MIT — 可免费使用、派生和构建。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。
