phi-redact-mcp
{"type": "text"}
umbryn-mcp
Ein MCP-Server, der PII/PHI aus Text entfernt, bevor dieser jemals ein LLM erreicht — selbst gehostet, fail-closed und HIPAA-bewusst.
Teams, die LLM- und Agent-Pipelines in regulierten Bereichen bauen, haben keine saubere, sofort einsetzbare Möglichkeit, PHI/PII aus einer Nutzlast zu entfernen, bevor sie die Infrastruktur eines Modellanbieters überquert. umbryn-mcp ist diese Grenze: drei MCP-Tools — redact, restore, detect — die sensible Werte in reversible Platzhalter umwandeln, vollständig in der Infrastruktur laufen, die Sie kontrollieren, und die Anfrage blockieren, wenn die Erkennung unsicher ist, anstatt Daten durchsickern zu lassen.
redact("Patient MRN: 1234567, provider NPI 1234567893, ssn 078-05-1120, john.doe@example.com")
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] → john.doe@example.comSenden Sie den redigierten Text an das Modell; bewahren Sie die token_map lokal auf; rufen Sie anschließend restore auf, um das Ergebnis wiederherzustellen. Round-Trips sind byte-exakt und durch eigenschaftsbasierte Tests belegt.
Warum es das gibt
Die PHI/PII-Redaktions-Nische im MCP-Bereich ist real, aber unterversorgt — die bestehenden Optionen sind dünne Presidio-Wrapper ohne HIPAA-spezifische Erkennung und, entscheidend, ohne Garantie, dass ein Erkennungsfehler die Anfrage blockiert, anstatt Rohdaten stillschweigend durchzureichen. Also bauen Teams entweder ihre eigene Grenze oder senden sensible Daten an einen Anbieter und verlassen sich auf eine BAA, um das abzudecken — der Designfehler, der echte Compliance-Vorfälle verursacht.
Naiver Presidio-Wrapper | Regex in Ihrer App | Cloud-DLP-API | umbryn-mcp | |
Sofort einsetzbare MCP-Tools | manchmal | ❌ | ❌ | ✅ |
Fail-closed bei unsicherer Erkennung | ❌ | ❌ | ❌ | ✅ |
HIPAA-Identifikatoren (NPI, DEA, MBI, MRN, CLIA) | ❌ | teilweise | teilweise | ✅ |
Reversibel (Original wiederherstellen) | selten | DIY | einige | ✅ |
Selbst gehostet, null Egress | ✅ | ✅ | ❌ (sendet Daten nach außen) | ✅ |
Funktioniert mit null schweren Abhängigkeiten | ❌ (braucht spaCy) | ✅ | n/a | ✅ (Regex-Engine) |
Optionale ML-NER (Namen, Adressen) | ✅ | ❌ | ✅ | ✅ ( |
Warum es gebaut wurde: MCP wurde schnell zum Mainstream — es ist jetzt erstklassig in Claude, Cursor und ChatGPT vertreten, über Tausende von Servern — aber die PHI/PII-Redaktions-Ecke blieb ein paar ungepflegten Wrappern überlassen. Dies füllt diese Lücke mit einer einzigen ehrlichen, prüfbaren, fail-closed Grenze, die Open Source bleibt, damit die Redaktionslogik, von der Sie abhängen, vollständig einsehbar ist und keine Black Box darstellt.
Related MCP server: MCP Presidio
Funktionen
Drei Tools, eine Grenze —
redact(→ redigierter Text + reversible Token-Map),restore(→ Original),detect(→ gefundene Entitäten, keine Veränderung).Konstruktionsbedingt fail-closed — wenn die Erkennung einen Fehler wirft oder eine Erkennung unter die Konfidenzschwelle fällt, gibt der Aufruf einen typisierten Fehler zurück. Unsicherheit blockiert; es wird nie nur das redigiert, was erkannt wurde, und der Rest durchgereicht.
HIPAA-bewusste Erkennung — prüfsummenvalidierte NPI und DEA, positionstypisierte Medicare-MBI, kontextverankerte MRN, CLIA-Laborkennungen, plus Standard-PII (E-Mail, Telefon, SSN, Kreditkarte, IBAN, IP, URL).
Null-Egress, selbst gehostet — die Standard-Engine ist reines Regex + Prüfsummen mit keinen Netzwerkaufrufen und keinen schweren Abhängigkeiten. Sie installiert sich überall, wo Python läuft.
Optionaler ML-Ausbau —
pip install "umbryn-mcp[presidio]"fügt Microsoft Presidio + spaCy fürPERSON/LOCATION-NER hinzu, transparent.Reversibel & deterministisch — kollisionssichere typisierte Platzhalter machen
restore(redact(x)) == xfür beliebige Eingaben; gleiche Eingabe + Konfiguration ergeben immer dieselbe Ausgabe.
Wann Sie es verwenden sollten (und wann nicht)
Greifen Sie zu umbryn-mcp, wenn:
Sie Gesundheits-, klinische, Finanz- oder nutzergenerierte Texte an eine Drittanbieter-LLM-API senden und PHI/PII aus der Infrastruktur und den Protokollen dieses Anbieters heraushalten müssen.
Sie eine Agent- oder MCP-Pipeline in einem regulierten Bereich bauen und eine sofort einsetzbare Redaktionsgrenze möchten, die Sie mit einem Tool-Aufruf einbinden.
Sie reversible Redaktion benötigen, damit nachgelagerte Schritte weiter funktionieren:
redact→ an das Modell senden →restore.Sie einen selbst gehosteten, Null-Egress-Detektor möchten, den Sie Zeile für Zeile prüfen können.
Sie HIPAA-spezifische Identifikatoren (NPI, DEA, Medicare-MBI, MRN, CLIA) benötigen, nicht nur Namen und E-Mails.
Greifen Sie zu etwas anderem, wenn:
Sie irreversible De-Identifikation / Anonymisierung benötigen (Tokenisierung, k-Anonymität) — die Redaktion hier ist von Design her reversibel.
Sie Nicht-Text-Daten redigieren müssen (Bilder, Audio, PDFs, Datenbankzeilen) — der Umfang ist Text.
Sie ein zertifiziertes Compliance-Produkt möchten — dies ist eine technische Kontrolle, kein Compliance-Programm (siehe Umfang & ehrliche Einschränkungen).
Sie einen transparenten Proxy möchten, der automatisch alles im Anforderungspfad bereinigt — v1 sind explizite Tool-Aufrufe; Proxy-Modus ist auf der Roadmap.
Sie garantiert 100 % Recall benötigen — kein Detektor, auch dieser nicht, kann das versprechen.
Schnellstart (< 60 Sekunden)
pip install umbryn-mcp # zero heavy deps; runs immediatelyDann registrieren Sie es bei Ihrem MCP-Client.
Claude Desktop / Claude Code (claude_desktop_config.json, oder claude mcp add umbryn-mcp -- umbryn-mcp):
{
"mcpServers": {
"umbryn-mcp": {
"command": "umbryn-mcp"
}
}
}Cursor (.cursor/mcp.json) und VS Code verwenden dieselbe Form — siehe examples/ für kopierfertige Konfigurationen.
Möchten Sie auch Namens-/Adresserkennung?
pip install "umbryn-mcp[presidio]"
python -m spacy download en_core_web_lgDer Server erkennt Presidio automatisch und führt das Upgrade durch — keine Konfigurationsänderung nötig. (Setzen Sie UMBRYN_ENGINE=regex, um die abhängigkeitsfreie Engine zu erzwingen, oder =presidio, um die ML-Engine zu verlangen.)
So funktioniert es
Ein Tool-Aufruf kommt über stdio herein; der Redactor-Kern führt die konfigurierte Erkennungs-Engine aus, löst Überlappungen deterministisch auf, wendet die Fail-closed-Schwellenprüfung an und ersetzt erkannte Bereiche durch reversible typisierte Platzhalter. Nur redigierter Text soll die Grenze verlassen, die Sie betreiben.
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)]Der Redactor-Kern hängt nur von einem kleinen DetectionEngine-Interface ab — nie direkt von Presidio oder MCP. Rohdaten und die Erkennungs-Engine bleiben innerhalb der Grenze, die Sie betreiben; nur redigierter Text verlässt sie. Siehe docs/ARCHITECTURE.md und docs/THREAT_MODEL.md.
Die Tools
redact(text) → { redacted_text, token_map, entities }
Ersetzt erkannte PHI/PII durch typisierte Platzhalter wie [NPI_1]. token_map bildet jeden Platzhalter auf seinen ursprünglichen Wert ab — bewahren Sie sie lokal auf; senden Sie sie niemals an das Modell. entities listet auf, was redigiert wurde (Typ/Bereich/Score) für die Prüfung.
restore(redacted_text, token_map) → { text }
Kehrt eine Redaktion um und stellt den Originaltext exakt wieder her. Sicher auf Modellausgaben anwendbar, die die Platzhalter noch enthalten.
detect(text) → { entities, count }
Meldet die gefundenen Entitäten — Typ, Bereich, Konfidenz — ohne den Text zu verändern. Im Gegensatz zu redact zeigt es Treffer mit niedriger Konfidenz an, anstatt zu blockieren, damit Sie die Abdeckung prüfen können, bevor Sie der Grenze in einer Pipeline vertrauen.
So verwenden Sie es (eine echte Pipeline)
Das Muster ist redact → Modell → restore, wobei die Token-Map Ihre Seite nie verlässt:
Vor dem Modell bereinigen. Rufen Sie
redact(user_text)auf. Senden Sie nurredacted_textan das LLM. Bewahren Sietoken_mapin Ihrem Prozess auf — behandeln Sie sie so sensibel wie die Rohdaten und übergeben Sie sie niemals an das Modell.Lassen Sie das Modell mit Platzhaltern arbeiten. Es sieht
[NPI_1],[US_SSN_1]usw. — semantisch neutrale Tokens, über die es nachdenken und die es zurückspiegeln kann.Danach wiederherstellen. Rufen Sie
restore(model_output, token_map)auf, um die echten Werte zurück in die Modellantwort einzufügen, bevor sie Ihren Benutzer oder Ihre Datenbank erreicht.Den Block behandeln. Wenn
redacteinen[LOW_CONFIDENCE]- oder[DETECTION_ERROR]-Toolfehler zurückgibt, hat die Grenze sich geweigert, Daten durchsickern zu lassen — melden Sie das, verschärfen Sie die Eingabe oder senken Sie das Risiko, aber senden Sie den Rohtext nicht weiter.
Bevor Sie ihr in einer Pipeline vertrauen, rufen Sie detect(sample_text) auf repräsentativen (synthetischen) Daten auf, um genau zu sehen, was erkannt wird und was nicht, und passen Sie die Schwellenwerte (unten) an Ihre Risikotoleranz an.
Fail-closed, präzise
Zwei Schwellenwerte steuern jeden redact-Aufruf:
detection_floor(Standard0.35) — die Empfindlichkeitsgrenze. Signale darunter werden als Rauschen behandelt.min_confidence(Standard0.5) — die Vertrauensschwelle.
Jeder Kandidat, der die Schwelle übersteht, aber unter min_confidence liegt, versetzt den Aufruf in den Fail-closed-Modus: Er gibt einen [LOW_CONFIDENCE]-Fehler zurück, anstatt die sicheren Bereiche zu redigieren und den unsicheren durchzureichen. Engine-Fehler geben [DETECTION_ERROR] zurück. Bei jedem Fehler wird kein redigierter Text zurückgegeben. Beide Schwellenwerte sind konfigurierbar (siehe unten).
Konfiguration
Alle optional; sinnvolle Standardwerte bedeuten, dass es ohne Konfiguration läuft. Über den env-Block des Clients setzen.
Variable | Standard | Bedeutung |
|
|
|
|
| Vertrauensschwelle; Erkennungen darunter blockieren (fail closed) |
|
| Darunter wird ein Signal als Rauschen behandelt |
|
| Größere Eingaben mit einem typisierten Fehler ablehnen |
|
| spaCy-Modell für die Presidio-Engine |
|
| Strukturierten Audit-Datensatz pro |
| (nicht gesetzt) | Pfad zu einer JSON-Konfigurationsdatei (unten) |
Konfigurationsdatei
Für Einstellungen, die nicht in eine flache Umgebungsvariable passen, zeigen Sie mit UMBRYN_CONFIG auf eine JSON-Datei. Umgebungsvariablen gewinnen für die Skalarwerte oben weiterhin gegenüber der Datei, sodass Sie eine Datei ausliefern und pro Start anpassen können. Eine fehlerhafte Datei (schlechtes JSON, unbekannte Schwelle, nicht kompilierbares Regex) schlägt fail-closed beim Start fehl, anstatt stillschweigend zu degradieren.
{
// 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
}Ein kopierfertiges Beispiel liegt unter examples/umbryn_config.json.
Entitätsabdeckung
Entität | Regex-Engine (Standard) | Presidio-Engine ( |
E-Mail, Telefon, SSN, Kreditkarte, IP, URL | ✅ | ✅ |
NPI (Luhn + 80840-Prüfziffer) | ✅ | ✅ |
DEA (Prüfziffer) | ✅ | ✅ |
Medicare MBI (positionsbasiert) | ✅ | ✅ |
MRN (kontextverankert) | ✅ | ✅ |
Medicare HICN (SSN + Begünstigtencode) | ✅ | ✅ |
CLIA-Labornummer | ✅ | ✅ |
US ITIN (9XX-Bereichsstruktur) | ✅ | ✅ |
UK-NHS-Nummer (Mod-11-Prüfung) | ✅ | ✅ |
Kanadische SIN (Luhn-Prüfung) | ✅ | ✅ |
US-Führerschein (kontextverankert) | ✅ | ✅ |
IBAN (Mod-97 / ISO-7064-Prüfung) | ✅ | ✅ |
Personennamen | ❌ | ✅ (spaCy NER) |
Adressen / Orte | ❌ | ✅ (spaCy NER) |
Benutzerdefinierte Recognizer (deine Regex + Prüfziffer, per Konfiguration) | ✅ | ✅ |
Benchmark
Die Erkennungsqualität ist gemessen, nicht behauptet. Die Zahlen unten stammen von der Standard-Engine (ohne Abhängigkeiten), die gegen den synthetischen Evaluierungskorpus ausgewertet wurde — 200 generierte Dokumente, ~1.800 annotierte Textabschnitte, mit Attrappen, die die Prüfsumme nicht bestehen, als Distraktoren eingewoben, um die Präzision ehrlich zu halten. Reproduziere sie mit python eval/run_eval.py --markdown.
Entität | Precision | Recall | F1 | TP | FP | FN |
| 1.00 | 1.00 | 1.00 | 87 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 105 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 72 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 119 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 144 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 87 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 62 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 200 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 126 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 78 | 0 | 0 |
| 0.94 | 1.00 | 0.97 | 200 | 12 | 0 |
| 1.00 | 1.00 | 1.00 | 144 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 95 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 81 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 97 | 0 | 0 |
| 1.00 | 1.00 | 1.00 | 136 | 0 | 0 |
\* = HIPAA-relevante Kennung, unterliegt der CI-Qualitätsgrenze. Aggregiert über die von der Qualitätsgrenze abgedeckte Menge: Präzision 0,99, Recall 1,00. Diese Grenze lässt den Build fehlschlagen, wenn der Recall unter 0,90 oder die Präzision unter 0,80 fällt. (Die 12 False Positives von NPI sind ähnlich aussehende 10-stellige Zahlen, die zufällig die Luhn/80840-Prüfziffer bestehen — eine bewusste, ausfallsichere Tendenz zur Über-Schwärzung.)
Dies sind synthetische Idealbedingungen mit sauberer Formatierung und passenden Kontextwörtern; echte Texte sind unordentlicher. Behandle das als Absicherung gegen Regressionen und als Plausibilitätsprüfung, nicht als Garantie — bewerte stets anhand deiner eigenen repräsentativen Daten.
Umfang & ehrliche Einschränkungen
Dieses Tool reduziert die PHI/PII-Exposition an einer Grenze. Es macht ein System nicht „HIPAA-konform“. Compliance ist eine Eigenschaft eines gesamten Systems und einer gesamten Organisation — ihrer Richtlinien, Verträge, Zugriffskontrollen, Audit-Haltung und Menschen — nicht einer einzelnen Bibliothek. Das Ausführen von umbryn-mcp kann Teil eines konformen Designs sein, ist aber keine Zertifizierung, keine Garantie und kein Ersatz für einen Business Associate Agreement, eine Risikobewertung oder einen Rechtsbeistand.
Konkret leistet dieses Projekt Folgendes nicht: Es garantiert keine 100%ige Erkennung (kein Detektor tut das), de-identifiziert nicht über eine reversible Schwärzung hinaus, deckt keine Nicht-Text-Daten ab und fungiert in v1 nicht als transparenter Proxy (die Schwärzung erfolgt über explizite Tool-Aufrufe, die du einbindest). Kein Detektor ist perfekt — bewerte ihn anhand deiner eigenen repräsentativen Daten, bevor du dich darauf verlässt. Siehe docs/THREAT_MODEL.md für den vollständigen Geltungsbereich, die Annahmen und die Restrisiken sowie SECURITY.md, um Probleme zu melden.
Wie du beitragen kannst
Beiträge sind sehr willkommen — dies ist ein bewusst freundlicher Ort für deinen ersten Open-Source-PR, und der Maintainer bemüht sich, schnell zu antworten.
Der einfachste Beitrag mit hohem Mehrwert: Füge einen Erkennungs-Recognizer für eine neue Kennung hinzu (eine Regex + optional einen Prüfziffer-Validator + einen Test). Das Issue-Formular „add-a-recognizer“ dient zugleich als Spezifikation, und CONTRIBUTING.md führt dich durch die sechs Schritte.
Andere gute Möglichkeiten, wie du helfen kannst: verbessere die Dokumentation, füge Testfälle oder Beispiel-Client-Konfigurationen hinzu oder greife etwas von der Roadmap auf. Stöbere in den Good-First-Issues oder eröffne ein Issue, um etwas vorzuschlagen.
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.pyDer vollständige Leitfaden — Entwicklungs-Setup, Konventionen und die No-Real-PHI-Regel für Test-Fixtures — steht in CONTRIBUTING.md. Mit deinem Beitrag stimmst du zu, dass deine Arbeit unter der MIT-Lizenz steht.
Lizenz
MIT — entspricht Presidio und maximiert die Wiederverwendung. Erstellt mit Microsoft Presidio (optional) und dem MCP Python SDK.
umbryn-mcp wird vom Team hinter Kenda entwickelt.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP proxy that pseudo-anonymizes PII before data reaches external AI providers like Claude, ChatGPT, or Gemini.18MIT
- AlicenseAqualityDmaintenanceAn MCP server that enables LLMs to detect and anonymize over 25 types of Personally Identifiable Information (PII) using Microsoft Presidio. It supports various redaction strategies and can process both plain text and structured data to help ensure data privacy.10MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for automatic detection and redaction of PII in text, with anonymization and deanonymization capabilities, all local processing.1
- AlicenseAqualityBmaintenanceMCP server and CLI for detecting, redacting, and auditing PHI in medical text before it is sent to AI agents, with tools for scan, redact, audit, and validate operations.4MIT
Related MCP Connectors
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
An MCP server for Arcjet - the runtime security platform that ships with your AI code.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Rinava/umbryn-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server