关于 umbryn-mcp
umbryn-mcp 是一个可自托管的 MCP 服务,用于在文本发送给 LLM 前检测并可逆地替换 PII/PHI。它采用故障关闭策略,检测不确定或出错时会阻止返回文本,适用于受监管的数据处理流程。
主要功能
- 01检测并脱敏 PII/PHI 文本
- 02通过占位符可逆恢复原文
- 03低置信度或检测错误时阻断
- 04识别 HIPAA 相关标识符
- 05支持可选 Presidio 与 spaCy NER
适用场景
- 01向第三方 LLM API 发送医疗文本前脱敏
- 02在 Agent 流程中保护敏感用户文本
- 03处理模型输出后恢复占位符对应内容
MCP 相关
它通过 stdio 向 MCP 客户端提供 redact、restore 和 detect 三个工具。客户端可先脱敏文本,再将脱敏结果交给 LLM,并在后续恢复原值。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx umbryn-mcpUMBRYN_ENGINEDetection engine: auto (default), regex, or presidioUMBRYN_MIN_CONFIDENCETrust threshold (0-1); detections below it fail closed. Default 0.5UMBRYN_DETECTION_FLOORSensitivity floor (0-1); below this a signal is noise. Default 0.35本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
3收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| text | string | 是 | 要清理的文本 |
详细介绍
umbryn-mcp
一个 MCP 服务,可在文本到达大模型之前对其中的 PII/PHI 进行脱敏——可自托管、故障时默认阻断,并充分考虑 HIPAA 要求。
在受监管领域构建大模型和 Agent 工作流的团队,缺少一种简洁、即插即用的方式,能在负载进入模型提供商的基础设施之前清除其中的 PHI/PII。umbryn-mcp 就是这道边界:它提供三个 MCP 工具——redact、restore、detect——将敏感值替换为可逆占位符,完全在你控制的基础设施内运行,并且检测结果不确定时会阻止请求,而不是泄露数据。
redact("Patient MRN: 1234567, provider NPI 1234567893, ssn 078-05-1120, [email protected]")
redacted_text (safe to send to the model):
"Patient MRN: [MEDICAL_RECORD_NUMBER_1], provider NPI [NPI_1], ssn [US_SSN_1], [EMAIL_ADDRESS_1]"
token_map (kept local, never sent to the model):
[MEDICAL_RECORD_NUMBER_1] → 1234567
[NPI_1] → 1234567893
[US_SSN_1] → 078-05-1120
[EMAIL_ADDRESS_1] → [email protected]
将脱敏后的文本发送给模型;在本地保留 token_map;随后调用 restore 还原结果。往返还原可实现逐字节精确,并通过基于属性的测试加以验证。
为什么要开发它
PHI/PII 脱敏 MCP 领域确实有需求,但服务不足——现有方案不过是简单封装 Presidio,既不具备 HIPAA 专项检测能力,更关键的是,无法保证检测失败时会阻止请求,而不是悄无声息地放行原始数据。因此,团队要么自行构建这道边界,要么将敏感数据发送给服务提供商,并依赖 BAA 提供保障——这正是会导致真实合规事故的设计阶段失误。
| 简单的 Presidio 封装 | 在应用中使用正则表达式 | 云端 DLP API | umbryn-mcp | |
|---|---|---|---|---|
| 即插即用的 MCP 工具 | 有时支持 | ❌ | ❌ | ✅ |
| 检测结果不确定时默认阻断 | ❌ | ❌ | ❌ | ✅ |
| HIPAA 标识符(NPI、DEA、MBI、MRN、CLIA) | ❌ | 部分支持 | 部分支持 | ✅ |
| 可逆(还原原文) | 很少 | 自行实现 | 部分支持 | ✅ |
| 可自托管,零数据外传 | ✅ | ✅ | ❌(会向外发送数据) | ✅ |
| 无需繁重依赖即可运行 | ❌(需要 spaCy) | ✅ | 不适用 | ✅(正则表达式引擎) |
| 可选 ML NER(姓名、地址) | ✅ | ❌ | ✅ | ✅([presidio] extra) |
**开发初衷:**MCP 迅速成为主流——如今已在 Claude、Cursor 和 ChatGPT 中成为一等功能,拥有数千个服务端——但 PHI/PII 脱敏领域却只剩下少数无人维护的封装。本项目填补了这一空白,提供一道诚实、可审计、故障时默认阻断的单一边界,并以开源方式发布,让你所依赖的脱敏逻辑完全可供检查,而不是一个黑箱。
功能
- 三种工具,一个边界 —
redact(→ 脱敏文本 + 可逆令牌映射)、restore(→ 原文)、detect(→ 找到的实体,不做修改)。 - 从设计上确保失败时关闭 — 如果检测出错,或任何一项检测结果低于置信度阈值,调用就会返回带类型的错误。存在不确定性时会阻止操作;绝不会只脱敏能检测到的内容,再放行其余部分。
- 支持 HIPAA 的检测 — 通过校验和验证的 NPI 和 DEA、按位置类型判定的 Medicare MBI、由上下文锚定的 MRN、CLIA 实验室 ID,以及标准 PII(电子邮件、电话、SSN、信用卡、IBAN、IP、URL)。
- 零外传、可自托管 — 默认引擎仅使用纯正则表达式和校验和,不会进行网络调用,也没有重型依赖项。任何支持 Python 的环境都能安装。
- 可选的 ML 升级 —
pip install "umbryn-mcp[presidio]"会透明地添加 Microsoft Presidio + spaCy,用于PERSON/LOCATIONNER。 - 可逆且确定 — 防碰撞的类型化占位符确保对任意输入都有
restore(redact(x)) == x;相同输入 + 配置始终产生相同输出。
适用场景(以及不适用场景)
以下情况适合使用 umbryn-mcp:
- 你要将医疗、临床、金融或用户生成的文本发送到第三方大模型 API,并且需要避免 PHI/PII 进入该服务提供商的基础设施和日志。
- 你正在受监管领域构建 Agent 或 MCP 流水线,希望通过一次工具调用接入一个即插即用的脱敏边界。
- 你需要可逆脱敏,让下游步骤仍能正常运行:
redact→ 发送给模型 →restore。 - 你想要一个可自托管、不外传数据的检测器,并能逐行审计。
- 你需要 HIPAA 专用标识符(NPI、DEA、Medicare MBI、MRN、CLIA),而不只是姓名和电子邮件。
以下情况适合选择其他方案:
- 你需要不可逆的去标识化 / 匿名化(令牌化、k-匿名)——这里的脱敏按设计是可逆的。
- 你需要脱敏非文本数据(图像、音频、PDF、数据库行)——本项目仅处理文本。
- 你想要经过认证的合规产品——这只是一个技术控制措施,并非完整的合规计划(参见范围与客观限制)。
- 你想要一个透明代理,自动脱敏请求路径中的所有内容——v1 需要显式调用工具;代理模式已列入路线图。
- 你要求保证 100% 召回率——任何检测器都无法做到这一点,包括本项目的检测器。
快速入门(不到 60 秒)
pip install umbryn-mcp # zero heavy deps; runs immediately
然后将其注册到你的 MCP 客户端。
Claude Desktop / Claude Code(claude_desktop_config.json,或 claude mcp add umbryn-mcp -- umbryn-mcp):
{
"mcpServers": {
"umbryn-mcp": {
"command": "umbryn-mcp"
}
}
}
Cursor(.cursor/mcp.json)和 VS Code 使用相同的配置格式——可在 examples/ 中查看可直接粘贴的配置。
还需要检测姓名/地址?
pip install "umbryn-mcp[presidio]"
python -m spacy download en_core_web_lg
服务会自动检测 Presidio 并升级,无需更改配置。(设置 UMBRYN_ENGINE=regex 可强制使用无依赖项引擎,设置 =presidio 则要求使用 ML 引擎。)
工作原理
工具调用通过 stdio 传入;Redactor 核心会运行配置的检测引擎,以确定性方式处理重叠项,执行失败时关闭的阈值检查,并将检测到的文本片段替换为可逆的类型化占位符。只有脱敏后的文本才应该离开你运行的边界。
flowchart LR
A[MCP client<br/>Claude · Cursor · agent] -- redact / restore / detect --> B[umbryn-mcp<br/>stdio server]
B --> C[Redactor core<br/>fail-closed · reversible]
C --> D{Detection engine}
D -->|default, zero deps| E[Regex + checksums]
D -->|optional| F[Presidio + spaCy NER]
C -. scrubbed text .-> A
A -- scrubbed text only --> G[(LLM / downstream)]
Redactor 核心只依赖一个精简的 DetectionEngine 接口——不直接依赖 Presidio 或 MCP。原始数据和检测引擎都留在你运行的边界内;只有脱敏后的文本会离开该边界。参见 docs/ARCHITECTURE.md 和 docs/THREAT_MODEL.md。
工具
redact(text) → { redacted_text, token_map, entities }
将检测到的 PHI/PII 替换为 [NPI_1] 这类类型化占位符。token_map 会将每个占位符映射回其原始值——请将它保留在本地;绝不要发送给模型。 entities 列出已脱敏的内容(类型/范围/分数),供审计使用。
restore(redacted_text, token_map) → { text }
撤销脱敏,精确还原原始文本。即使模型输出中仍包含占位符,也可以安全调用。
detect(text) → { entities, count }
报告找到的实体,包括类型、跨度和置信度,但不会修改文本。与 redact 不同,它会显示低置信度命中,而不是阻止处理,因此你可以在信任管道中的边界之前检查覆盖情况。
如何使用(真实管道)
模式为 脱敏 → 模型 → 还原,且令牌映射绝不会离开你这边:
- 在交给模型之前清理文本。 调用
redact(user_text)。只将redacted_text发送给大模型。将token_map保留在你的进程中——像对待原始输入一样谨慎处理,绝不要传给模型。 - 让模型处理占位符。 模型会看到
[NPI_1]、[US_SSN_1]等——这些在语义上中立的令牌,模型可以对其进行推理并在回复中原样输出。 - 之后还原。 调用
restore(model_output, token_map),在模型的回复传给用户或数据库之前,将真实值替换回去。 - 处理阻止情况。 如果
redact返回[LOW_CONFIDENCE]或[DETECTION_ERROR]工具错误,说明边界拒绝了信息泄露——请显示错误、收紧输入或降低风险,但不要继续发送原始文本。
在管道中信任它之前,请对有代表性的(合成)数据调用 detect(sample_text),准确查看能检测到和检测不到的内容,并根据你的风险承受度调整阈值(见下文)。
精确的失败关闭机制
每次 redact 调用都受两个阈值控制:
detection_floor(默认值为0.35)——灵敏度边界。低于此值的信号会被视为噪声。min_confidence(默认值为0.5)——信任阈值。
任何通过灵敏度边界、但得分低于 min_confidence 的候选项,都会使调用进入失败关闭模式:它会返回 [LOW_CONFIDENCE] 错误,而不会只脱敏高置信度跨度并放行不确定的部分。引擎错误会返回 [DETECTION_ERROR]。发生任何错误时,都不会返回脱敏文本。 两个阈值都可配置(见下文)。
配置
所有配置项均为可选;合理的默认值意味着无需任何配置即可运行。通过客户端的 env 块设置。
| 变量 | 默认值 | 含义 |
|---|---|---|
UMBRYN_ENGINE | auto | auto(如果已安装 Presidio,则使用 Presidio,否则使用 regex)、regex 或 presidio |
UMBRYN_MIN_CONFIDENCE | 0.5 | 信任阈值;低于此值的检测结果会触发失败关闭 |
UMBRYN_DETECTION_FLOOR | 0.35 | 低于此值的信号会被视为噪声 |
UMBRYN_MAX_INPUT_CHARS | 100000 | 输入过大时,以带类型的错误拒绝 |
UMBRYN_SPACY_MODEL | en_core_web_lg | Presidio 引擎使用的 spaCy 模型 |
UMBRYN_AUDIT_LOG | false | 每次 redact 调用时生成结构化审计记录(仅包含数量和类型) |
UMBRYN_CONFIG | (未设置) | JSON 配置文件的路径(见下文) |
配置文件
对于不适合用扁平环境变量表示的设置,可将 UMBRYN_CONFIG 指向一个 JSON 文件。对于上述标量值,环境变量的优先级仍高于文件,因此你可以分发一个文件,并在每次启动时进行调整。格式错误的文件(无效 JSON、未知阈值、无法编译的正则表达式)会在启动时失败关闭,而不是静默降级。
{
// Per-entity trust thresholds override min_confidence for that type.
"entity_thresholds": { "PHONE_NUMBER": 0.7, "IP_ADDRESS": 0.9 },
// Entity types to drop entirely — never detected, never redacted.
// (A privacy trade-off you're opting into: a disabled type can leak.)
"disabled_entities": ["URL"],
// Your own recognizers, no fork required. `validator` names a built-in
// check-digit function (luhn, npi, dea, iban, nhs) — config supplies data,
// never code.
"recognizers": [
{
"entity_type": "EMPLOYEE_ID",
"regex": "\\bEMP-\\d{6}\\b",
"base_score": 0.85,
"context": ["employee", "badge"],
"context_required": false
}
],
"audit_log": true
}
可直接复制的示例位于 examples/umbryn_config.json。
实体覆盖范围
| 实体 | 正则引擎(默认) | Presidio 引擎([presidio]) |
|---|---|---|
| 电子邮件、电话、SSN、信用卡、IP、URL | ✅ | ✅ |
| NPI(Luhn + 80840 校验位) | ✅ | ✅ |
| DEA(校验位) | ✅ | ✅ |
| Medicare MBI(按位置类型校验) | ✅ | ✅ |
| MRN(由上下文锚定) | ✅ | ✅ |
| Medicare HICN(SSN + 受益人代码) | ✅ | ✅ |
| CLIA 实验室编号 | ✅ | ✅ |
| 美国 ITIN(9XX 范围结构) | ✅ | ✅ |
| 英国 NHS 编号(mod-11 校验) | ✅ | ✅ |
| 加拿大 SIN(Luhn 校验) | ✅ | ✅ |
| 美国驾照(由上下文锚定) | ✅ | ✅ |
| IBAN(mod-97 / ISO 7064 校验) | ✅ | ✅ |
| 个人姓名 | ❌ | ✅(spaCy NER) |
| 地址 / 位置 | ❌ | ✅(spaCy NER) |
| 自定义识别器(通过配置设置你的正则表达式 + 校验位) | ✅ | ✅ |
基准测试
检测质量是通过测量得出的,而非预先断言的。以下数据是默认的(零依赖)引擎在合成评估语料库上的评分结果——200 份生成的文档、约 1,800 个标注片段,其中穿插了校验和失败的相似值作为干扰项,以确保精确率真实可靠。运行 python eval/run_eval.py --markdown 可复现这些数据。
| 实体 | 精确率 | 召回率 | F1 | TP | FP | FN |
|---|---|---|---|---|---|---|
CANADA_SIN | 1.00 | 1.00 | 1.00 | 87 | 0 | 0 |
CLIA_NUMBER * | 1.00 | 1.00 | 1.00 | 105 | 0 | 0 |
CREDIT_CARD | 1.00 | 1.00 | 1.00 | 72 | 0 | 0 |
DEA_NUMBER * | 1.00 | 1.00 | 1.00 | 119 | 0 | 0 |
EMAIL_ADDRESS | 1.00 | 1.00 | 1.00 | 144 | 0 | 0 |
IBAN_CODE | 1.00 | 1.00 | 1.00 | 87 | 0 | 0 |
IP_ADDRESS | 1.00 | 1.00 | 1.00 | 62 | 0 | 0 |
MEDICAL_RECORD_NUMBER * | 1.00 | 1.00 | 1.00 | 200 | 0 | 0 |
MEDICARE_BENEFICIARY_ID * | 1.00 | 1.00 | 1.00 | 126 | 0 | 0 |
MEDICARE_HICN * | 1.00 | 1.00 | 1.00 | 78 | 0 | 0 |
NPI * | 0.94 | 1.00 | 0.97 | 200 | 12 | 0 |
PHONE_NUMBER | 1.00 | 1.00 | 1.00 | 144 | 0 | 0 |
UK_NHS_NUMBER | 1.00 | 1.00 | 1.00 | 95 | 0 | 0 |
US_DRIVERS_LICENSE * | 1.00 | 1.00 | 1.00 | 81 | 0 | 0 |
US_ITIN | 1.00 | 1.00 | 1.00 | 97 | 0 | 0 |
US_SSN * | 1.00 | 1.00 | 1.00 | 136 | 0 | 0 |
\* = 与 HIPAA 相关的标识符,受 CI 质量门禁约束。**门禁范围内的汇总值:精确率 0.99,召回率 1.00。**如果召回率低于 0.90 或精确率低于 0.80,门禁会导致构建失败。(NPI 的 12 个误报是外观相似的 10 位数字,它们恰好通过了 Luhn/80840 校验位检查——这是有意采用的故障安全策略,倾向于过度遮盖。)
这些数据是在格式规范、附近有上下文词语的合成理想条件下得出的;现实中的文本更杂乱。请将其视为回归防护和合理性检查,而非保证——务必使用你自己的代表性数据进行评估。
范围与明确的局限性
**此工具仅降低一个边界上的 PHI/PII 暴露风险。它不会让系统“符合 HIPAA”。**合规性取决于整个系统和组织,包括其政策、合同、访问控制、审计状况和人员,而非任何单个库。运行 umbryn-mcp 可以成为合规设计的一部分,但它不是认证、保证,也不能替代业务伙伴协议、风险评估或法律顾问。
具体而言,本项目不会:保证 100% 检测率(没有检测器能做到)、执行超出可逆遮盖范围的去标识化、覆盖非文本数据,或在 v1 中充当透明代理(遮盖通过你接入的显式工具调用完成)。没有任何检测器是完美的——依赖它之前,请使用你自己的代表性数据进行评估。完整的边界、假设和剩余风险请参阅 docs/THREAT_MODEL.md,报告问题请参阅 SECURITY.md。
如何贡献
欢迎踊跃贡献——这里有意营造友好的氛围,适合提交你的第一个开源 PR,维护者也会尽量快速回复。
**最容易带来高价值的贡献:**为新的标识符添加检测识别器(正则表达式 + 可选的校验位验证器 + 测试)。添加识别器问题表单也可作为规范,CONTRIBUTING.md介绍了六个步骤。
其他有帮助的方式:改进文档、添加测试用例或客户端配置示例,或从路线图中挑选一项工作。浏览适合新手的问题,或提出问题来建议改进。
git clone https://github.com/Rinava/umbryn-mcp && cd umbryn-mcp
pip install -e ".[dev]"
pytest # fast invariant suite (Presidio faked, sub-second)
ruff check . && mypy src/umbryn_mcp
python eval/run_eval.py
完整指南——包括开发环境设置、规范,以及夹具中不得包含真实 PHI 的规则——详见 CONTRIBUTING.md。贡献即表示你同意以 MIT 许可证授权你的作品。
许可证
MIT — 与 Presidio 保持一致,并最大限度地促进复用。使用 Microsoft Presidio(可选)和 MCP Python SDK 构建。
umbryn-mcp 由 Kenda 背后的团队构建。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。