Permanent local PDF redaction: text is removed and verified gone, not covered. No uploads.
Blackout finds Social Security numbers, emails, phone numbers and card numbers in a PDF, lets you search custom terms or draw boxes by hand, and exports a flattened PDF where the redacted text is actually gone — not hidden under a rectangle.
It runs in three places, all on the same engine: the browser app, a CLI, and an MCP server.
npx @thrain/blackout redact filing.pdf --detect ssn,email --out clean.pdf
npm install
npm install
npm run dev # local dev server
npm run build # type-check + production build to dist/
npm run build:agent # type-check + bundle the CLI and MCP server to packages/
npm run smoke # headless browser end-to-end test
npm run smoke:cli # CLI end-to-end test
npm run smoke:mcp # MCP server end-to-end test
npm run smoke:agent-dist # the same two, against the built bundles
node scripts/make-test-pdf.mjs out.pdf 12 # fixture with fake PII
node scripts/test-worker.mjs # license worker tests
node scripts/visual-check.mjs [test.pdf] [outdir] # screenshot spot-check
The browser smoke script needs a Chrome/Chromium binary; set CHROME_BIN if
yours isn't in the default Playwright cache location. Every smoke test makes
the same central assertion — that the exported PDF contains zero extractable
text — because that assertion is the entire product, and it has to hold on
every path that ships, not just the one that is easy to check.
src/pdf/) — detection, mark ordering, and the rasterise-and-burn
export. Platform-agnostic: its only contact with the outside world is
src/pdf/platform.ts, which supplies a canvas. src/platform/browser.ts
backs it with a DOM canvas, src/platform/node.ts with Skia. There is exactly
one redaction implementation, so the browser and the CLI cannot drift..github/workflows/deploy.yml on every push to main.src/agent/) — thin non-interactive wrappers over the
engine, bundled into packages/blackout and packages/blackout-mcp.worker/) — a Cloudflare Worker that verifies Stripe
checkout sessions and mints signed license tokens; the app verifies them
with an embedded public key. Deployed by
.github/workflows/deploy-worker.yml.An agent asked to redact a PDF will otherwise write a script that draws a black rectangle over text that stays selectable underneath. Two form factors exist so that "redact this PDF" can resolve to a tool that does it correctly:
packages/blackout · npx @thrain/blackout redact in.pdfpackages/blackout-mcp · tools redact_pdf, check_pdfBoth verify their own output before returning: they re-extract text from the file they just wrote and fail rather than hand back a document that still has a text layer. Neither makes a network call, including the licence check — so nothing leaves the machine at all.
Apache-2.0 © Thrain LLC. The "Blackout" name and logo are trademarks of Thrain LLC (see NOTICE) — fork freely, but ship your fork under your own name.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @thrain/blackout-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"ai-thrain-blackout": {
"command": "npx",
"args": [
"-y",
"@thrain/blackout-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup reference@thrain/blackout-mcpnpmai.thrain/blackout works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.