Skip to main content
Glama

redactpdf

Sharing a PDF usually means trusting that whatever you blacked out on screen is actually gone. Often it is not: the text is still sitting in the file, ready to be copied out. redactpdf takes the opposite approach. It looks for sensitive text in a local PDF's text layer, writes a copy in which every matched character has been physically replaced, and then re-reads its own output to prove that nothing it was asked to remove can still be extracted. If the proof fails, you get an error instead of a file.

Four kinds of sensitive text are detected. Social Security numbers must satisfy the SSA's own validity rules (area 001-899 except 666, group 01-99, serial 0001-9999), so random digit groups in that shape are not flagged. Payment-card numbers are digit runs of 13 to 19 digits, allowing single spaces or dashes between digits, and must pass the Luhn check. Email addresses and North-American phone numbers — (ddd) ddd-dddd, ddd-ddd-dddd, ddd.ddd.dddd, or ddd ddd dddd, with an optional +1 prefix — round out the built-in categories. On top of those, terms lets you name literal strings of your own, matched case-insensitively and counted under their own key. Omit detect to run all four categories.

Detection runs per extracted string — the string operands of Tj and TJ show operators, in plain or FlateDecode content streams — so a match that is split across two string operands is not seen. That is a stated limitation of the text-layer model this tool uses, not a silent one.

check_pdf reports what would be removed without writing anything. redact_pdf writes the redacted copy — the input file is never modified — replacing each matched character with # while preserving string lengths, then verifies the result. Documents run to 10 pages free; past that, both tools ask for a licence. The licence check in this build is a format check — a token of 16 to 512 characters from [A-Za-z0-9_-] plus . separators counts as well-formed, supplied via the license argument or the BLACKOUT_LICENSE environment variable — and the over-limit error distinguishes a missing licence (LICENSE_REQUIRED) from a malformed one (LICENSE_INVALID). Encrypted PDFs, PDFs built on xref or object streams, and malformed files are reported as unsupported rather than passed over in silence.

Both tools answer with a one-line summary, a blank line, and a fenced JSON block carrying path, outputPath (null for check_pdf), pages, counts, extractableChars — for check_pdf, the characters that fall inside a detected match in the input; for a successful redact_pdf, 0 by construction — and licenseState.

CLI

npx @reneturcios/redactpdf check_pdf '{"path":"/abs/path/report.pdf"}'
npx @reneturcios/redactpdf redact_pdf '{"path":"/abs/path/report.pdf","terms":["falcon"]}'
npx @reneturcios/redactpdf --version

redact_pdf writes <input>-redacted.pdf (the input path with its .pdf suffix replaced) unless output_path says otherwise; the output may not be the input itself, and an existing output is only replaced when overwrite is true.

Exit codes: 0 on success, 1 on a runtime error (the tool's error text is printed), 2 on a usage error.

Related MCP server: PDF Redaction MCP Server

MCP server

npx -y @reneturcios/redactpdf mcp

MCP client config:

{
  "mcpServers": {
    "redactpdf": {
      "command": "npx",
      "args": ["-y", "@reneturcios/redactpdf", "mcp"]
    }
  }
}

Tools

  • check_pdf — Report what would be redacted from a local PDF — per-category match counts — without writing anything.

    • path (string, required) — absolute path to a PDF on this machine

    • detect (string array, optional) — any of ssn, card, email, phone; omit for all

    • terms (string array, optional) — literal strings to match, case-insensitive

  • redact_pdf — Write a redacted copy of a local PDF with detected sensitive text permanently removed and verified gone. Never modifies the input.

    • path (string, required) — absolute path to a PDF on this machine

    • output_path (string, optional) — defaults to <input>-redacted.pdf; must not be the input

    • detect (string array, optional) — any of ssn, card, email, phone; omit for all

    • terms (string array, optional) — literal strings to match, case-insensitive

    • overwrite (boolean, optional, default false) — allow replacing an existing output

    • license (string, optional) — Pro licence token; falls back to BLACKOUT_LICENSE

Docker

docker run -i ghcr.io/cloudcorprecords/redactpdf
docker run --rm -v "$PWD:/w" ghcr.io/cloudcorprecords/redactpdf check_pdf '{"path":"/w/report.pdf"}'

Development

npm install
npm run build   # tsc -> dist/
npm test        # tsx --test test/*.test.ts (pure local, no network)
npm run dev     # run the CLI from source

License

MIT — Copyright (c) 2026 Rene Turcios

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      A comprehensive tool server for reading, merging, and extracting content from PDF files via local paths or direct URLs. It enables metadata retrieval, regex searching, and page-specific text extraction with built-in caching and workspace-restricted security.
      9
      5,840 PyPI
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      A Model Context Protocol (MCP) server that provides comprehensive PDF redaction capabilities, including text and image redaction, search, and session-based in-memory operations using FastMCP and pymupdf.
      11
      MIT
    • F
      license
      A
      quality
      B
      maintenance
      MCP server for local, verifiable PDF redaction. Enables AI agents to find sensitive regions, locate text, redact PDFs on-device, verify redaction and tamper-evidence seals, and generate PDFs—without uploading confidential documents.
      8
      602 npm
      -