{
  "markdown": "# Redacta\n\n[![CI](https://github.com/nickjlamb/redacta/actions/workflows/ci.yaml/badge.svg)](https://github.com/nickjlamb/redacta/actions/workflows/ci.yaml)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21115605.svg)](https://doi.org/10.5281/zenodo.21115605)\n[![engine](https://img.shields.io/npm/v/%40pharmatools%2Fredacta?label=engine&logo=npm&color=cb3837)](https://www.npmjs.com/package/@pharmatools/redacta)\n[![npm downloads](https://img.shields.io/npm/dm/%40pharmatools%2Fredacta?color=cb3837)](https://www.npmjs.com/package/@pharmatools/redacta)\n[![redacta-mcp](https://img.shields.io/npm/v/redacta-mcp?label=redacta-mcp&logo=npm&color=cb3837)](https://www.npmjs.com/package/redacta-mcp)\n[![PyPI](https://img.shields.io/pypi/v/redacta?logo=pypi&logoColor=white&color=3775A9)](https://pypi.org/project/redacta/)\n[![App Store](https://img.shields.io/itunes/v/6784591850?label=App%20Store&logo=apple&color=0D96F6)](https://apps.apple.com/app/redacta-redact-for-ai/id6784591850)\n[![Anthropic MCP Directory](https://img.shields.io/badge/Anthropic_MCP_Directory-listed-d97757?logo=anthropic&logoColor=white)](https://claude.ai/directory/connectors/ant.dir.gh.nickjlamb.redacta)\n[![self-hosted](https://img.shields.io/badge/self--hosted-Kubernetes-326CE5?logo=kubernetes&logoColor=white)](gateway-service/k8s/README.md)\n\nPseudonymise medical and clinical documents before they're processed by AI or\nshared. Redacta replaces patient identifiers with labelled tokens —\n`[PATIENT_NAME_1]`, `[NHS_NUMBER_1]`, `[DATE_OF_BIRTH_1]`, … — while leaving the\nclinical meaning intact, and returns a redaction report alongside the cleaned\ntext.\n\nIt started as an [Agent Skill](https://agentskills.io) and is now one engine\nshipped across eight surfaces — an iOS app, agent skill, MCP server, a\nself-hosted HTTP service with a Kubernetes deployment, two libraries, a CLI,\nand a FigJam whiteboard plugin.\n\n> **Running this in production?** Redacta offers a small number of fixed-price\n> design-partner integrations for teams shipping AI agents on clinical or patient\n> data — deployment in your environment, one real workflow integrated, and a\n> data-flow document written for your DPO.\n> [Details →](https://www.pharmatools.ai/redacta#partners)\n\n## One engine, many surfaces\n\n<p align=\"center\">\n  <img src=\"ios-app/docs/architecture.svg\" width=\"100%\" alt=\"One detection engine feeds eight surfaces: the iOS app, Share Extension and widget run it on-device via JavaScriptCore; the MCP server, CLI, TypeScript library and FigJam plugin consume it directly; a Python package mirrors it; and the agent skill adds LLM reasoning.\" />\n</p>\n\n| Surface | Folder | Get it |\n|---------|--------|--------|\n| iOS app — iPhone (app, Share Extension, widget) | [`ios-app/`](ios-app/) | Build with Xcode — see [`ios-app/README.md`](ios-app/README.md) |\n| Agent skill (Claude Code / apps / API) | `SKILL.md`, `scripts/` | `openclaw skills install redacta` ([ClawHub](https://clawhub.ai/nickjlamb/redacta)) |\n| MCP server (Claude Desktop, Cursor, …) | `mcp-server/` | `npx -y redacta-mcp` ([npm](https://www.npmjs.com/package/redacta-mcp) · [MCP Registry](https://registry.modelcontextprotocol.io) · [Anthropic MCP Directory](https://claude.ai/directory/connectors/ant.dir.gh.nickjlamb.redacta)) |\n| TypeScript library | `npm-package/` | `npm i @pharmatools/redacta` ([npm](https://www.npmjs.com/package/@pharmatools/redacta)) |\n| Python library | `python-package/` | `pip install redacta` ([PyPI](https://pypi.org/project/redacta/)) |\n| Command-line tool | `cli-package/` | `npx redacta-cli` ([npm](https://www.npmjs.com/package/redacta-cli)) |\n| Self-hosted HTTP service + Kubernetes | [`gateway-service/`](gateway-service/) | `docker build` — see [`gateway-service/README.md`](gateway-service/README.md) |\n| FigJam plugin | `figjam-plugin/` | [Figma Community](https://www.figma.com/community/plugin/1647311189828426124) |\n\nThe detection logic lives in one place — the TypeScript engine\n(`@pharmatools/redacta`, in `npm-package/`), which the MCP server and the\nFigJam plugin consume, and which the iOS app runs on-device via JavaScriptCore.\nThe Python package mirrors it for `pip` users; the agent skill adds LLM reasoning\nfor free-text names on top of the deterministic patterns.\n\n## How it works\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"docs/boundary-dark.svg\">\n  <img src=\"docs/boundary-light.svg\" alt=\"The Redacta privacy boundary: a clinical document is redacted inside your boundary — deterministic patterns plus reasoning plus a self-check — producing tokenised text and a token map. Only the tokenised text crosses to the AI tool; the token map never leaves. The processed output comes back and reinstate restores the original identifiers locally. Raw identifiers never cross the boundary.\" width=\"100%\">\n</picture>\n\nTwo layers:\n\n- **Patterns (deterministic).** A bundled script (`scripts/redact_structured.py`,\n  Python standard library only, no network) matches fixed-format identifiers:\n  NHS numbers (Modulus-11 validated), UK National Insurance numbers, dates of\n  birth, UK postcodes, phone numbers, emails, and hospital/MRN numbers. US SSN\n  and ZIP codes are also handled.\n- **Reasoning (judgement).** The skill then has the agent handle what patterns\n  can't: patient names (told apart from the clinicians treating them), relatives\n  and carers, postal addresses, and identifying ages.\n- **Self-check.** A final pass re-reads the output for any identifier that slipped\n  through before the report is written.\n\nIt also works in reverse. **Re-identification** (`scripts/reinstate.py`) takes the\ntoken map from an earlier redaction and restores the original values — so you can\nredact a document, run it through another AI tool, and put the real details back\nlocally. Redact → process → re-identify is a complete round trip, and identifiers\nonly ever exist on your machine.\n\n**Safe Harbor mode.** Ask for HIPAA Safe Harbor (or \"US de-identification\") and\nRedacta applies a stricter pass: *all* dates (not just the date of birth), all\nspecific ages, and the remaining HIPAA identifiers — fax, certificate/licence,\ndevice serial, VIN, and health-plan beneficiary numbers.\n\n## Self-hosting on Kubernetes\n\nOrganisations that can't let identifiable text leave their environment can\nrun Redacta inside their own infrastructure: a small HTTP service\n([`gateway-service/`](gateway-service/)) deployable into an existing\nKubernetes cluster with plain YAML — two stateless replicas behind a\nService for redact/reinstate, an optional single-replica session boundary\nfor the protect → release loop, health probes, resource limits, restrictive\nsecurity defaults, and no-PHI logging. Text is pseudonymised before it\nreaches any external AI service, and the processing boundary stays under\nyour control. Walkthrough (local `kind` cluster included):\n[`gateway-service/k8s/README.md`](gateway-service/k8s/README.md) ·\nconcepts: [`docs/KUBERNETES.md`](docs/KUBERNETES.md).\nDeploying somewhere a DPO will ask questions? There's a one-page security &\ndata-protection summary at\n[pharmatools.ai/redacta-security](https://www.pharmatools.ai/redacta-security).\n\n## Install\n\n**Claude Code**\n\n```bash\ngit clone https://github.com/nickjlamb/redacta ~/.claude/skills/redacta\n```\n\nThen invoke it with `/redacta`, or let it trigger automatically when you ask to\nredact or de-identify clinical text.\n\n**Claude apps / API**\n\nZip the repository folder and upload it as a skill.\n\n## Contents\n\n| Path | What it is |\n|------|------------|\n| `SKILL.md` | The skill — instructions plus metadata |\n| `reference.md` | Pattern specs, the Modulus-11 algorithm, NI prefix rules, the date-of-birth vs clinical-date rule, token vocabulary, limitations |\n| `scripts/redact_structured.py` | The deterministic pattern layer |\n| `scripts/reinstate.py` | The re-identification layer (restore originals from a token map) |\n| `scripts/test_redact_structured.py` | Tests for the pattern layer |\n| `scripts/test_reinstate.py` | Tests for the re-identification layer |\n| `evaluations.json` | Example evaluation scenarios |\n\nRun the tests:\n\n```bash\npython3 scripts/test_redact_structured.py\npython3 scripts/test_reinstate.py\n```\n\n## A note on limits\n\nRedacta is a strong first line of defence, not a guarantee. It won't catch every\npossible identifier and isn't a substitute for formal data-protection processes.\nAlways review the redaction report before sharing text.\n\n## License\n\n[MIT-0](LICENSE) (MIT No Attribution). Built by\n[PharmaTools.AI](https://www.pharmatools.ai/redacta).\n",
  "bytes": 8545,
  "sha": "11e81948580fdf95ed825d1c0c6d1f1618a4282d382d83255c7da48b6b649848",
  "repo_slug": "nickjlamb/redacta",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_nickjlamb_redacta_mcp_b3c57d0f/readme"
}