umbryn-mcp について
umbryn-mcpは、LLMに送る前のテキストからPII/PHIを検出し、復元可能な形式で置き換えるセルフホスト可能なMCPサーバーです。検出に確信がない場合やエラー時には処理を拒否するため、規制対象データのパイプラインに利用できます。
主な機能
- 01テキスト内のPII/PHIを検出・マスキング
- 02プレースホルダーから原文を復元
- 03低い信頼度や検出エラー時に処理を拒否
- 04HIPAA関連識別子を検出
- 05PresidioとspaCyのNERに対応
活用シーン
- 01第三者のLLM APIへ送る前に医療テキストをマスキング
- 02エージェントの処理でユーザーデータを保護
- 03モデル出力のプレースホルダーを元に戻す
MCP 対応
stdio経由で、redact、restore、detectの3つのツールをMCPクライアントに提供します。テキストをマスキングしてから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
LLM にデータが届く前に、テキストから PII/PHI をマスキングする MCP サーバーです。セルフホスト可能で、フェイルクローズ設計、HIPAA に配慮しています。
規制対象の分野で LLM やエージェントのパイプラインを構築するチームには、ペイロードがモデルプロバイダーのインフラに渡る前に、そこから PHI/PII を取り除ける、すぐに導入できる手段がありません。umbryn-mcp はその境界を担います。3 つの 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] エクストラ) |
開発の背景: MCP は急速に普及し、今では Claude、Cursor、ChatGPT で数千のサーバーにわたり、標準機能として利用されています。しかし、PHI/PII マスキングの分野は、保守されていない少数のラッパーに任されたままでした。これを補うため、信頼性を重視し、監査可能で、フェイルクローズな境界を 1 つ提供します。依存するマスキングロジックをブラックボックスにせず、完全に検査できるよう、オープンソースとして公開しています。
特長
- 3つのツール、1つの境界 —
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/LOCATIONの NER を利用できます。 - 可逆かつ決定論的 — 衝突しない型付きプレースホルダーにより、任意の入力に対して
restore(redact(x)) == xが成り立ちます。同じ入力と設定なら、常に同じ出力になります。
使用する場面(および使用しない場面)
次の場合は umbryn-mcp を使用してください。
- 医療、臨床、金融、またはユーザー生成のテキストをサードパーティの LLM API に送信する際に、そのプロバイダーのインフラストラクチャやログに PHI/PII が残らないようにする必要がある場合。
- 規制対象の分野でエージェントまたは MCP パイプラインを構築しており、ツールを1回呼び出すだけで組み込めるスクラブ境界が必要な場合。
- 後続の処理が引き続き機能するよう、可逆的な編集が必要な場合:
redact→ モデルに送信 →restore。 - 1行ずつ監査できる、セルフホスト可能でエグレスのない検出器が必要な場合。
- 名前やメールアドレスだけでなく、HIPAA 固有の識別子(NPI、DEA、Medicare MBI、MRN、CLIA)が必要な場合。
次の場合は別のものを使用してください。
- 不可逆的な非識別化/匿名化(トークン化、k-匿名性)が必要な場合 — このツールの編集は設計上、可逆です。
- テキスト以外のデータ(画像、音声、PDF、データベースの行)を編集する必要がある場合 — 対象はテキストです。
- 認定済みのコンプライアンス製品が必要な場合 — これは技術的な対策の1つであり、コンプライアンスプログラムではありません(対象範囲と正直な制限事項を参照)。
- リクエスト経路上のすべてを自動でスクラブする透過型プロキシが必要な場合 — 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 を設定し、ML エンジンを必須にするには =presidio を設定してください。)
仕組み
ツール呼び出しは 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)を呼び出します。LLM にはredacted_textのみを送信します。token_mapはプロセス内に保持し、元の入力と同じように慎重に扱い、決してモデルに渡さないでください。 - プレースホルダーを使ってモデルに処理させます。 モデルには
[NPI_1]、[US_SSN_1]などの、意味的に中立で推論やそのままの出力が可能なトークンが表示されます。 - 処理後に元の値を復元します。
restore(model_output, token_map)を呼び出し、モデルの応答がユーザーやデータベースに届く前に、実際の値へ置き換えます。 - エラーを処理します。
redactが[LOW_CONFIDENCE]または[DETECTION_ERROR]のツールエラーを返した場合、情報漏洩を防ぐために処理が拒否されています。エラーを通知するか、入力を調整するか、リスクを下げてください。元のテキストをそのまま先へ送信してはいけません。
パイプラインで信頼して使用する前に、代表的な(合成)データに対して detect(sample_text) を呼び出し、何が検出され、何が検出されないかを正確に確認してから、リスク許容度に合わせてしきい値(以下)を調整してください。
正確なフェイルクローズ動作
すべての redact 呼び出しは、2 つのしきい値によって制御されます。
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件の誤検出は、たまたまLuhn/80840チェックディジットを通過する、類似した10桁の数値です。過剰な墨消しを優先する、意図的なフェイルセーフの設計です。)
これらは、書式が整っていて近くにコンテキストを示す単語がある、合成データによる最良の条件下での結果です。実際のテキストはもっと複雑です。これは回帰を防ぐためのガードレールおよび妥当性確認として扱い、保証とは見なさないでください。必ず、ご自身の代表的なデータで評価してください。
対象範囲と正直な制約
**このツールは、ある境界でのPHI/PIIの露出を低減します。システムを「HIPAA準拠」にするものではありません。**準拠性はシステムおよび組織全体の特性です。方針、契約、アクセス制御、監査体制、人員によって決まるものであり、単一のライブラリによって決まるものではありません。umbryn-mcpの実行は準拠した設計の一部にはなり得ますが、認証でも保証でもなく、業務提携契約、リスク評価、法的助言の代わりにもなりません。
具体的には、このプロジェクトは、検出率100%の保証(そのような検出器はありません)、元に戻せる墨消しを超える匿名化、テキスト以外のデータへの対応、v1での透過的なプロキシとしての動作を行いません(墨消しは、明示的なツール呼び出しを組み込んで行います)。完璧な検出器はありません。依存する前に、ご自身の代表的なデータで評価してください。境界、前提、残存リスクの詳細についてはdocs/THREAT_MODEL.mdを、問題の報告についてはSECURITY.mdをご覧ください。
貢献方法
貢献は大歓迎です。ここは初めてオープンソースに PR を送る方にも意図的に親しみやすい場で、メンテナーも迅速な対応を心がけています。
**最も手軽で価値の高い貢献:**新しい識別子の検出リコグナイザーを追加することです(正規表現+任意のチェックディジット検証機能+テスト)。リコグナイザー追加用の Issue フォームは仕様書も兼ねており、CONTRIBUTING.mdでは6つの手順を説明しています。
その他の貢献方法として、ドキュメントの改善、テストケースやクライアント設定例の追加、ロードマップからの項目への着手などがあります。初めての方向けの Issueを確認するか、提案するための Issue を作成してください。
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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。