Best for
- Reach for deidentify when you need to transform text — replace, mask, remove, hash, or date-shift the identifiers. If you only need to locate PHI spans without changing the text, use extractpii (see extracting-pii-entit…
maziyarpanahi/openmed/skills/deidentifying-clinical-text/SKILL.md
Remove, mask, or replace PHI/PII in clinical free text on-device with OpenMed's deidentify(). Use when the user needs to de-identify medical notes, strip patient identifiers, redact PHI before sharing or analysis, anonymize discharge summaries, or pick a de-id method (mask vs remove vs replace vs hash vs shift_dates). Covers confidence_threshold for safety, consistent+seed for stable surrogates, keep_mapping for reversible de-id, policy= profiles, and the DeidentificationResult fields. Pairs wit
Decision brief
openmed.deidentify detects PHI/PII and rewrites the text so it can be shared, stored, or analyzed without exposing patients. It runs fully on-device after a one-time model download — no network calls, no telemetry, no raw PHI leaving the process. This is the single most importan…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/maziyarpanahi/openmed --skill "skills/deidentifying-clinical-text"Inspect the Agent Skill "deidentifying-clinical-text" from https://github.com/maziyarpanahi/openmed/blob/c5fd81fef4c144624ba691f7cb81f95bf77db85a/skills/deidentifying-clinical-text/SKILL.md at commit c5fd81fef4c144624ba691f7cb81f95bf77db85a. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
note = ( "Patient John Doe (MRN 1234567) was seen on 2024-03-02 by Dr. Alice Reed. " "Contact: [email protected], 617-555-0142." )
1. Pick a method and a policy. Start from a bundled policy= profile (hipaasafeharbor, gdprpseudonymization, researchlimiteddataset, …) so per-label actions are set for you. See configuring-privacy-policies. 2. Set confidencethreshold deliberately. Default is 0.7. For de-id, pref…
Reach for deidentify when you need to transform text — replace, mask, remove, hash, or date-shift the identifiers. If you only need to locate PHI spans without changing the text, use extractpii (see extracting-pii-entities). To restore masked text later, use reidentify (see reid…
for e in result.piientities: NEVER log e.text / e.originaltext — those are raw PHI. Use offsets + label. print(e.canonicallabel, e.start, e.end, round(e.confidence, 3)) python
Review the “The five methods” section in the pinned source before continuing.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 5,161 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
openmed.deidentify detects PHI/PII and rewrites the text so it can be shared,
stored, or analyzed without exposing patients. It runs fully on-device after
a one-time model download — no network calls, no telemetry, no raw PHI leaving
the process. This is the single most important OpenMed entry point for privacy
work; everything else (policies, audit, multilingual, date-shifting) layers on
top of it.
Reach for deidentify when you need to transform text — replace, mask, remove,
hash, or date-shift the identifiers. If you only need to locate PHI spans
without changing the text, use extract_pii (see extracting-pii-entities). To
restore masked text later, use reidentify (see reidentifying-text).
import openmed
note = (
"Patient John Doe (MRN 1234567) was seen on 2024-03-02 by Dr. Alice Reed. "
"Contact: [email protected], 617-555-0142."
)
result = openmed.deidentify(
note,
method="mask", # mask | remove | replace | hash | shift_dates
confidence_threshold=0.7, # safety default; raise to reduce false negatives' impact
policy="hipaa_safe_harbor", # optional bundled profile (see below)
)
print(result.deidentified_text)
# Patient [NAME] (MRN [ID_NUM]) was seen on [DATE] by Dr. [NAME]. ...
for e in result.pii_entities:
# NEVER log e.text / e.original_text — those are raw PHI. Use offsets + label.
print(e.canonical_label, e.start, e.end, round(e.confidence, 3))
deidentify returns a DeidentificationResult with these fields (note the
exact names):
| Field | What it holds |
|---|---|
.deidentified_text | the rewritten, PHI-safe string (your output) |
.pii_entities | list[PIIEntity] — each has start, end, canonical_label, confidence, action, surrogate; original_text/text hold raw PHI |
.mapping | redacted→original dict, only when keep_mapping=True (secret) |
.method | the method actually applied |
.metadata | run metadata (model, policy, counts) |
method= | Effect | Reversible? | Use when |
|---|---|---|---|
"mask" | John Doe → [NAME] | with keep_mapping=True | default; clear that redaction happened |
"remove" | deletes the span entirely | no | minimal-footprint output |
"replace" | type-matched fake value (John Doe→Mark Lee) | with keep_mapping=True | keep notes readable/parseable (see generating-synthetic-surrogates) |
"hash" | stable hash per value, links repeats | no (one-way) | cohort linkage without revealing identity |
"shift_dates" | moves dates, preserves intervals | n/a | research needing temporal structure (see shifting-clinical-dates) |
policy= profile
(hipaa_safe_harbor, gdpr_pseudonymization, research_limited_dataset, …)
so per-label actions are set for you. See configuring-privacy-policies.confidence_threshold deliberately. Default is 0.7. For de-id,
prefer over-redaction: a missed identifier is a breach, an over-redacted
token is just noise. The bundled safety sweep catches structured IDs
(SSN, MRN-like, emails) even below threshold.deidentify. Inspect result.pii_entities by offset and label,
not raw text, to confirm coverage.consistent=True, seed=<int> so the same
input maps to the same fake value every run (reproducible pipelines).keep_mapping=True and store result.mapping
in a secured vault — never alongside the de-identified output.audit=True
(auditing-deidentification-runs) and the 18-identifier checklist
(auditing-safe-harbor-checklist).# Same fake identity for every mention of the same person, reproducibly:
r = openmed.deidentify(note, method="replace", consistent=True, seed=42)
# Reversible de-id (keep the mapping secret and separate from output):
r = openmed.deidentify(note, method="mask", keep_mapping=True)
restored = openmed.reidentify(r.deidentified_text, r.mapping)
assert restored == note
openmed.extract_pii(text) → PredictionResult with
.entities (spans, no rewrite). Use it to preview coverage first.openmed.reidentify(deidentified_text, mapping) — requires
keep_mapping=True at de-id time and proper authorization.configuring-privacy-policies to choose/customize a policy=.deidentify(..., audit=True) → AuditReport with offsets, hashes,
detector provenance, and residual-risk — never plaintext.openmed_deidentify; REST
POST /pii/deidentify. There is no CLI de-id command.result.deidentified_text and
result.pii_entities — not .text/.entities. (extract_pii returns a
PredictionResult whose spans are at .entities.)PIIEntity.text and
.original_text contain real identifiers. Do not print, log, or cache them.
Audit and logs use offsets, canonical_label, and hashes only.shift_dates is for dates only; combine with keep_year/date_shift_days
(see shifting-clinical-dates). It does not touch names or IDs.keep_mapping output is sensitive as PHI. The mapping re-identifies
everyone — store it encrypted, access-controlled, and apart from the output.lang= (and locale= for surrogates) for non-English
notes; see deidentifying-multilingual-text. Do not run English models on
other languages.auditing-safe-harbor-checklist.openmed/core/pii.py (deidentify, extract_pii,
reidentify, DeidentificationResult, PIIEntity).Frequently asked questions
openmed.deidentify detects PHI/PII and rewrites the text so it can be shared, stored, or analyzed without exposing patients. It runs fully on-device after a one-time model download — no network calls, no telemetry, no raw PHI leaving the process. This is the single most importan…
The source record exposes this install command: npx skills add https://github.com/maziyarpanahi/openmed --skill "skills/deidentifying-clinical-text". Inspect the command and pinned source before running it.
Alternatives
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
wanshuiyin/Auto-claude-code-research-in-sleep
Use it for operations and research tasks; the detail page covers purpose, installation, and practical steps.
prowler-cloud/prowler
PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance
brucesongs/kali-claw
Insecure Design (OWASP A06:2025) focuses on security flaws in system architecture and design phases, rather than code implementation-level bugs.