Skip to main content
Glama
Rinava

phi-redact-mcp

by Rinava

umbryn-mcp

Un servidor MCP que redacta PII/PHI del texto antes de que llegue a un LLM: autohospedado, con bloqueo ante incertidumbre y compatible con HIPAA.

PyPI version Tests Python versions License: MIT Ruff PRs welcome

Los equipos que construyen canalizaciones de LLM y agentes en sectores regulados no tienen una forma limpia e integrable de eliminar PHI/PII de una carga útil antes de que cruce a la infraestructura del proveedor del modelo. umbryn-mcp es ese límite: tres herramientas MCP — redact, restore, detect — que convierten valores sensibles en marcadores de posición reversibles, se ejecutan íntegramente dentro de la infraestructura que controlas y bloquean la solicitud si la detección es incierta, en lugar de filtrar datos.

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.com

Envía el texto redactado al modelo; mantén el token_map local; llama a restore después para rehidratar el resultado. Los viajes de ida y vuelta son exactos a nivel de byte y están demostrados con pruebas basadas en propiedades.


Por qué existe

El nicho de MCP para redacción de PHI/PII es real pero está poco atendido: las opciones existentes son envoltorios básicos de Presidio sin detección específica de HIPAA y, lo que es crítico, sin garantía de que un fallo de detección bloquee la solicitud en lugar de pasar silenciosamente los datos sin procesar. Así que los equipos o construyen su propio límite o envían datos sensibles a un proveedor y se apoyan en un BAA para cubrirlo: el error de diseño que provoca incidentes de cumplimiento reales.

Envoltorio básico de Presidio

Regex en tu app

Cloud DLP API

umbryn-mcp

Herramientas MCP de integración directa

a veces

Bloqueo ante detección incierta

Identificadores HIPAA (NPI, DEA, MBI, MRN, CLIA)

parcial

parcial

Reversible (restaurar original)

raramente

por cuenta propia

algunos

Autohospedado, cero tráfico de salida

❌ (envía datos al exterior)

Funciona con cero dependencias pesadas

❌ (requiere spaCy)

n/a

✅ (motor de regex)

NER de ML opcional (nombres, direcciones)

✅ (extra [presidio])

Por qué se creó: MCP se generalizó rápidamente: ahora es de primera clase en Claude, Cursor y ChatGPT, en miles de servidores; pero el ámbito de la redacción de PHI/PII quedó en manos de unos pocos envoltorios sin mantenimiento. Esto llena ese vacío con un único límite honesto, auditable y con bloqueo ante incertidumbre, mantenido como código abierto para que la lógica de redacción de la que dependes sea totalmente inspeccionable en lugar de una caja negra.

Related MCP server: MCP Presidio

Features

  • Tres herramientas, un solo límiteredact (→ texto depurado + mapa de tokens reversible), restore (→ original), detect (→ entidades encontradas, sin mutación).

  • Bloqueo ante incertidumbre por construcción — si la detección da error o cualquier detección cae por debajo del umbral de confianza, la llamada devuelve un error tipado. La incertidumbre bloquea; nunca redacta lo que puede y deja pasar el resto.

  • Detección preparada para HIPAA — NPI y DEA validados por suma de verificación, MBI de Medicare con tipo posicional, MRN anclado al contexto, IDs de laboratorio CLIA, además de PII estándar (correo electrónico, teléfono, SSN, tarjeta de crédito, IBAN, IP, URL).

  • Cero tráfico de salida, autohospedado — el motor por defecto es regex puro + sumas de verificación, sin llamadas de red ni dependencias pesadas. Se instala en cualquier lugar donde se instale Python.

  • Mejora de ML opcionalpip install "umbryn-mcp[presidio]" añade Microsoft Presidio + spaCy para NER de PERSON/LOCATION, de forma transparente.

  • Reversible y determinista — los marcadores de posición tipados a prueba de colisiones hacen que restore(redact(x)) == x para cualquier entrada; la misma entrada + configuración siempre produce la misma salida.

Cuándo usarlo (y cuándo no)

Recurre a umbryn-mcp cuando:

  • Envías texto sanitario, clínico, financiero o generado por el usuario a una API de LLM de terceros y necesitas que la PHI/PII no llegue a la infraestructura ni a los registros de ese proveedor.

  • Estás construyendo una canalización de agente o MCP en un sector regulado y quieres un límite de depuración integrable que se conecte con una sola llamada a una herramienta.

  • Necesitas redacción reversible para que los pasos posteriores sigan funcionando: redact → enviar al modelo → restore.

  • Quieres un detector autohospedado y sin tráfico de salida que puedas auditar línea por línea.

  • Necesitas identificadores específicos de HIPAA (NPI, DEA, MBI de Medicare, MRN, CLIA), no solo nombres y correos electrónicos.

Recurre a otra opción cuando:

  • Necesitas desidentificación/anonimización irreversible (tokenización, k-anonimato) — aquí la redacción es reversible por diseño.

  • Necesitas redactar datos no textuales (imágenes, audio, PDF, filas de bases de datos) — el alcance es el texto.

  • Quieres un producto con cumplimiento certificado — esto es un control técnico, no un programa de cumplimiento (consulta Alcance y limitaciones honestas).

  • Quieres un proxy transparente que depure automáticamente todo en la ruta de solicitudes — la v1 es llamadas explícitas a herramientas; el modo proxy está en la hoja de ruta.

  • Exiges una recuperación del 100 % garantizada — ningún detector, incluido este, puede prometerlo.

Inicio rápido (< 60 segundos)

pip install umbryn-mcp        # zero heavy deps; runs immediately

Luego regístralo en tu cliente MCP.

Claude Desktop / Claude Code (claude_desktop_config.json, o claude mcp add umbryn-mcp -- umbryn-mcp):

{
  "mcpServers": {
    "umbryn-mcp": {
      "command": "umbryn-mcp"
    }
  }
}

Cursor (.cursor/mcp.json) y VS Code usan la misma estructura: consulta examples/ para ver configuraciones listas para copiar y pegar.

¿También quieres detección de nombres y direcciones?

pip install "umbryn-mcp[presidio]"
python -m spacy download en_core_web_lg

El servidor detecta automáticamente Presidio y se actualiza: no hace falta cambiar la configuración. (Establece UMBRYN_ENGINE=regex para forzar el motor sin dependencias, o =presidio para exigir el de ML).

Cómo funciona

Una llamada a herramienta entra por stdio; el núcleo Redactor ejecuta el motor de detección configurado, resuelve las superposiciones de forma determinista, aplica la comprobación del umbral de bloqueo y sustituye los segmentos detectados por marcadores de posición tipados reversibles. Solo el texto depurado debe salir del límite que ejecutas.

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)]

El núcleo Redactor depende solo de una pequeña interfaz DetectionEngine: nunca de Presidio o MCP directamente. Los datos sin procesar y el motor de detección permanecen dentro del límite que ejecutas; solo el texto depurado sale de él. Consulta docs/ARCHITECTURE.md y docs/THREAT_MODEL.md.

Las herramientas

redact(text) → { redacted_text, token_map, entities }

Reemplaza la PHI/PII detectada por marcadores de posición tipados como [NPI_1]. token_map asocia cada marcador de posición con su valor original — mantenlo local; nunca lo envíes al modelo. entities enumera lo redactado (tipo/segmento/puntuación) para auditoría.

restore(redacted_text, token_map) → { text }

Revierte una redacción y recupera el texto original exactamente. Es seguro llamarla sobre la salida del modelo que aún contenga los marcadores.

detect(text) → { entities, count }

Informa de las entidades encontradas — tipo, segmento, confianza — sin modificar el texto. A diferencia de redact, muestra los aciertos de baja confianza en lugar de bloquear, para que puedas inspeccionar la cobertura antes de confiar en el límite en una canalización.

Cómo usarlo (una canalización real)

El patrón es redact → modelo → restore, con el mapa de tokens sin salir nunca de tu lado:

  1. Depura antes del modelo. Llama a redact(user_text). Envía solo redacted_text al LLM. Mantén token_map en tu proceso: trátalo con la misma sensibilidad que la entrada sin procesar y nunca se lo pases al modelo.

  2. Deja que el modelo trabaje con los marcadores. Ve [NPI_1], [US_SSN_1], etc.: tokens semánticamente neutros sobre los que puede razonar y que puede repetir.

  3. Rehidrata después. Llama a restore(model_output, token_map) para devolver los valores reales a la respuesta del modelo antes de que llegue a tu usuario o a tu base de datos.

  4. Gestiona el bloqueo. Si redact devuelve un error de herramienta [LOW_CONFIDENCE] o [DETECTION_ERROR], el límite se ha negado a filtrar: hazlo visible, refuerza la entrada o reduce el riesgo, pero no envíes el texto sin procesar.

Antes de confiar en él en una canalización, llama a detect(sample_text) sobre datos representativos (sintéticos) para ver exactamente qué se detecta y qué no, y ajusta los umbrales (abajo) a tu tolerancia al riesgo.

Bloqueo ante incertidumbre, con precisión

Dos umbrales gobiernan cada llamada a redact:

  • detection_floor (por defecto 0.35) — el límite de sensibilidad. Las señales por debajo se tratan como ruido.

  • min_confidence (por defecto 0.5) — el umbral de confianza.

Cualquier candidato que supere el límite pero puntúe por debajo de min_confidence pone la llamada en modo de bloqueo: devuelve un error [LOW_CONFIDENCE] en lugar de redactar los segmentos con confianza y dejar pasar el incierto. Los errores del motor devuelven [DETECTION_ERROR]. Ante cualquier error, no se devuelve texto redactado. Ambos umbrales son configurables (ver más abajo).

Configuración

Todo es opcional; los valores predeterminados razonables hacen que se ejecute sin configuración. Se configura mediante el bloque env del cliente.

Variable

Default

Significado

UMBRYN_ENGINE

auto

auto (Presidio si está instalado, si no, regex), regex o presidio

UMBRYN_MIN_CONFIDENCE

0.5

Umbral de confianza; las detecciones por debajo bloquean la llamada

UMBRYN_DETECTION_FLOOR

0.35

Por debajo de este valor, una señal se trata como ruido

UMBRYN_MAX_INPUT_CHARS

100000

Rechaza una entrada mayor con un error tipado

UMBRYN_SPACY_MODEL

en_core_web_lg

Modelo de spaCy para el motor de Presidio

UMBRYN_AUDIT_LOG

false

Emite un registro de auditoría estructurado por cada llamada a redact (solo recuentos y tipos)

UMBRYN_CONFIG

(sin definir)

Ruta a un archivo de configuración JSON (abajo)

Archivo de configuración

Para ajustes que no encajan en una variable de entorno plana, apunta UMBRYN_CONFIG a un archivo JSON. Las variables de entorno siguen teniendo prioridad sobre el archivo para los valores escalares anteriores, así que puedes distribuir un solo archivo y ajustarlo en cada lanzamiento. Un archivo mal formado (JSON inválido, umbral desconocido, regex no compilable) falla en modo bloqueado al inicio en lugar de degradarse silenciosamente.

{
  // 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
}

Hay un ejemplo listo para copiar en examples/umbryn_config.json.

Cobertura de entidades

Entidad

Motor de regex (predeterminado)

Motor de Presidio ([presidio])

Correo electrónico, Teléfono, SSN, Tarjeta de crédito, IP, URL

NPI (dígito de control Luhn + 80840)

DEA (dígito de control)

Medicare MBI (tipado por posición)

MRN (con anclaje contextual)

Medicare HICN (SSN + código de beneficiario)

CLIA número de laboratorio

ITIN de EE. UU. (estructura de rango 9XX)

Número NHS del Reino Unido (verificación mod-11)

SIN canadiense (verificación Luhn)

Licencia de conducir de EE. UU. (con anclaje contextual)

IBAN (verificación mod-97 / ISO 7064)

Nombres de personas

✅ (spaCy NER)

Direcciones / ubicaciones

✅ (spaCy NER)

Reconocedores personalizados (tu regex + dígito de control, mediante configuración)

Evaluación comparativa

La calidad de detección se mide, no se asume. Los números siguientes corresponden al motor predeterminado (sin dependencias) evaluado sobre el corpus de evaluación sintético — 200 documentos generados, ~1.800 spans etiquetados, con imitaciones que fallan el checksum entretejidas como distractores para mantener la precisión honesta. Reprodúcelos con python eval/run_eval.py --markdown.

Entity

Precisión

Exhaustividad

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

\* = identificador relevante para HIPAA, sujeto al control de calidad del CI. Agregado sobre el conjunto evaluado: precisión 0.99, exhaustividad 1.00. El control hace fallar la compilación si la exhaustividad cae por debajo de 0.90 o la precisión por debajo de 0.80. (Los 12 falsos positivos de NPI son números de 10 dígitos parecidos a los reales que pasan el dígito de control Luhn/80840: un sesgo deliberado y a prueba de fallos hacia el enmascaramiento excesivo).

Son condiciones sintéticas de mejor caso, con formato limpio y palabras de contexto cercanas; el texto del mundo real es más desordenado. Trata esto como una barrera de regresión y una comprobación de cordura, no como una garantía: evalúa siempre con tus propios datos representativos.

Alcance y limitaciones honestas

**Esta herramienta reduce la exposición de PHI/PII en un único punto de un sistema. No hace que un sistema «cumpla la HIPAA». Volver a cumplimiento normativo a todo un sistema y organización: sus políticas, contratos, controles de acceso, postura de auditoría y personas. No es propiedad de una única librería. Ejecutar umbryn-mcp pueden ser parte de un diseño conforme, pero la herramienta no es una certificación ni una garantía, ni un sustituto de un Acuerdo de Asociado Comercial, ni de una evaluación de riesgos, ni de legal counsel.

Concretamente, este proyecto no:

  • garantiza el 100 % de la detección (ningún detector es perfecto);

  • an describe beyond a reversible redaction;

  • ocupa datos no textuales;

  • actúa como proxy transparente en v1 (redar must call via explicit methods you integrate).

Ningún detector es perfecto: evalúa con tus propios datos representativos. Evalúa before confide in itición: more on a case by case. Consult docs/THREAT_MODEL.md para understanding the full scope and assumptions, and SECURITY.md to report incidents.

Cómo contribuir

Las contribuciones son muy bienvenidas: this place is intentionally friendly for a first open source PR, and maintainers try to respond quickly.

The easiest and high-value contribution: add a detection risible for a new identifier (a regex + an optional validator of check digit + a test). The add-a-recognizer issue form doubles as a spec, and CONTRIBUTING.md walks you through the six steps in detail.

Other good ways to help: improve documentation, add test cases or example client configurations, or tackle something from the posible roadmap. Explore good first issues or open an issue to propose something.

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

The full guide — development setup, conventions, and the rule of no real PHI on fixtures — is in CONTRIBUTING.md. By contributing you agree that your work is MIT-licensed.

License

License MIT-licensed — matches Presidio and maximizes reuse. Built with Microsoft Presidio (optional) and the MCP Python SDK.

umbryn-mcp is built by the team behind Kenda.

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
3dResponse time
0dRelease cycle
4Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP proxy that pseudo-anonymizes PII before data reaches external AI providers like Claude, ChatGPT, or Gemini.
    18
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    An 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.
    10
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for automatic detection and redaction of PII in text, with anonymization and deanonymization capabilities, all local processing.
    1
  • A
    license
    A
    quality
    B
    maintenance
    MCP 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.
    4
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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