PluginWorld
Wa

watermarks-remover

Claude Code✓ SPEC VERIFIED

Purge multi-vendor AI watermarks: clean Unicode text, apply statistical rewrite hooks, and clear C2PA plus metadata from PNG, JPEG, SVG, PDF, DOCX, HTML, and MD.

@ShadowAqueduct · v0.5.0 · MIT · updated 2d ago

SECURITY

A

SCORE

94

STARS

776

PLUG IN

/plugin marketplace add ShadowAqueduct/watermark-remover
/plugin install watermarks-remover

README

_ _ _ ____ ___ ____ ____ _  _ ____ ____ _  _ ____    ____ ____ _  _ ____ _  _ ____ ____
| | | |__|  |  |___ |__/ |\/| |__| |__/ |_/  [__  __ |__/ |___ |\/| |  | |  | |___ |__/
|_|_| |  |  |  |___ |  \ |  | |  | |  \ | \_ ___]    |  \ |___ |  | |__|  \/  |___ |  \

watermarks-remover

CI Release Stars

Agent skill + stdlib Python service that strips multi-vendor AI provenance marks from text and files. For privacy and hygiene on content you own.

The skill is a thin HTTP client — the agent host needs no Python. All work runs in the service.

Author: ShadowAqueduct

Latest release: v0.5.0

Layer Target Method
A Invisible Unicode, exotic spaces, bidi, tag chars Deterministic Python
B Statistical (token-sampling) text watermarks Agent rewrite + optional rewrite_text.py
Files C2PA / EXIF / XMP / doc props PNG, JPEG, WebP, AVIF, HEIC, BMP, GIF, TIFF, SVG, PDF, DOCX, XLSX, PPTX, EPUB, ODT, HTML, Markdown, MP4/MOV/M4A/M4V, WAV, MP3, FLAC

Covers class-level marks from Claude, Gemini/SynthID-Text, OpenAI provenance surfaces, and open-LLM schemes (Kirchenbauer green-list, keyed-Gumbel / Aaronson EXP).


Install

Skill ships no code — it calls the service over HTTP. Install the skill, start the service, set WATERMARKS_SERVICE_URL if it is not http://127.0.0.1:8765.

One installer (Python 3.10+, stdlib only):

python3 install_skill.py --skill remove-ai-marks --target claude-code
Host Target Lands in
Claude Code (personal) --target claude-code ~/.claude/skills/<skill>
Claude Code (project) --target claude-project --project-dir PATH PATH/.claude/skills/<skill>
Cowork / claude.ai / cloud --target cowork dist/<skill>.zip (upload under Customize → Skills)
Cursor --target cursor ~/.cursor/skills/<skill>

Shipped skills: remove-ai-marks (full, service-backed) and clean-user-facing-text (text only, self-contained). Use --list to see them. Existing installs are kept as backups unless you pass --force. --link symlinks the checkout for live edits.

Claude Code plugin (marketplace)

/plugin marketplace add guillaumemeyer/watermarks-remover
/plugin install watermarks-remover@watermarks-remover

Skills load as /watermarks-remover:remove-ai-marks and /watermarks-remover:clean-user-facing-text. Update with /plugin marketplace update watermarks-remover.

Grok

mkdir -p ~/.grok/skills
ln -sfn "$(pwd)/skills/remove-ai-marks" ~/.grok/skills/remove-ai-marks

Start the service

make serve                 # http://127.0.0.1:8765
# or:
python3 service/scripts/server.py --host 127.0.0.1 --port 8765

Optional system tools (used when present): c2patool, exiftool, qpdf. Core scripts need only Python 3.10+ stdlib.


Automatic cleaning via hook

A skill is an instruction — the model decides whether to run it. A hook runs on every matching tool call and does not need model cooperation.

The plugin registers a PostToolUse hook on Write|Edit|MultiEdit|NotebookEdit that runs service/scripts/hook_written_file.py:

Mode Behaviour
check (default) Reports marks, leaves the file alone
clean Strips marks in place, notifies the model

Set mode via plugin settings (Hook mode) or WATERMARKS_HOOK_MODE=clean. Without the plugin, add the hook yourself in ~/.claude/settings.json.

Hooks cover files the agent writes and the pre-commit gate. Chat transcript text still depends on the skill (best-effort).


Quick use

SCRIPTS=service/scripts

python3 "$SCRIPTS/inspect_file.py" draft.md
python3 "$SCRIPTS/clean_file.py" draft.md -o draft.cleaned.md
python3 "$SCRIPTS/clean_file.py" photo.png -o photo.cleaned.png
python3 "$SCRIPTS/clean_file.py" notes.docx -o notes.cleaned.docx

# Text Layer A
python3 "$SCRIPTS/inspect_text.py" draft.md
python3 "$SCRIPTS/clean_text.py" draft.md -o draft.cleaned.md --stats

# Layer B rewrite (default: print prompt only)
python3 "$SCRIPTS/rewrite_text.py" draft.md --backend print-prompt --strength paraphrase

Text tools refuse binary input (DOCX, PDF, images) and point you at inspect_file.py / clean_file.py. Unrecognized formats are never auto-cleaned.


HTTP service

Same machinery as a stdlib HTTP server (service/scripts/server.py):

Method Path Returns
GET /health {"ok": true, "version": ...}
GET /capabilities optional tools / backends
GET /openapi.json OpenAPI 3.0.3 spec
POST /inspect kind, suspicious, report
POST /detect detections
POST /clean cleaned base64 + report
POST /inspect/batch, /clean/batch per-file results (max 50)
WM="http://127.0.0.1:8765"
curl -s "$WM/health"
curl -s -X POST "$WM/clean" -H 'Content-Type: application/json' \
  -d "{\"file\": \"$(base64 < notes.md | tr -d '\n')\", \"name\": \"notes.md\"}"

Set WATERMARKS_SERVER_API_KEY to require bearer auth. Binds loopback by default.

Detection is separate from cleaning. Text detectors (MarkLLM, keyed-Gumbel, Claude seam) and image SynthID scoring are opt-in and fail-soft.


Docker

make docker-core-build
docker run --rm -p 127.0.0.1:8765:8765 --read-only --tmpfs /tmp watermarks-remover

docker compose up -d                         # core only
docker compose --profile harness up -d       # + markllm / markdiffusion
docker compose --profile heavy up -d         # + ctrlregen / synthid (local builds)

Published images on GHCR: core, markllm, markdiffusion. CtrlRegen and SynthID scorer stay local-only (upstream licensing). Copy .env.example.env for optional config; nothing is required for basic text cleaning.


File formats

Format Clean
PNG / JPEG / WebP Drop C2PA / XMP / EXIF segments
AVIF / HEIC Drop ISOBMFF boxes
BMP / GIF / TIFF Truncate trailing meta / drop extensions & tags
SVG Strip <metadata>, XMP
PDF exiftool → qpdf (structural) → optional Ghostscript deep image pass
DOCX / XLSX / PPTX / ODT / EPUB Scrub props, customXml, OPF, embedded media
HTML / Markdown Strip meta / JSON-LD / AI frontmatter keys + Layer A
MP4 / MOV / M4A / M4V / WAV / MP3 / FLAC Drop C2PA / ID3 / LIST chunks

PDF needs qpdf for a real strip (exiftool alone is incremental and leaves recoverable bytes). Ghostscript handles metadata inside embedded images. Soft-bound C2PA and pure pixel/audio/video watermarks remain out of scope for the core path.


Optional backends

Backend Role Notes
reverse-SynthID Image SynthID score External checkout; detection only
CtrlRegen Pixel-domain removal External; heavy; conservative strength default
MarkLLM Text watermark verify (KGW / SynthID) Same-config only, not a vendor oracle
MarkDiffusion Image watermark harness + DiffusionPurification Same-config only
keyed-Gumbel (detect_gumbel.py) Model-free same-key replay Stdlib; needs the generation key

Bootstrap scripts live under service/scripts/ (setup_synthid.sh, setup_ctrlregen.sh, setup_markllm.sh, setup_markdiffusion.sh). Layer B rewrite is iterative and can be driven by these detectors when configured.


How text marking works

  • Layer A removes edit-based Unicode carriers (testable, lossless).
  • Layer B attacks sampling watermarks via heavy rewrite (best-effort; costs style and voice).
  • File cleaners strip C2PA / XMP / props from supported containers.

No tool can certify that a vendor detector will fail. Prefer a non-origin model for Layer B so you do not re-stamp the text.

Skip Layer B when quality matters more than hygiene: use Layer A + file cleaners and keep the original prose.


Pre-commit

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/guillaumemeyer/watermarks-remover
    rev: v0.5.0
    hooks:
      - id: watermarks-remover-check   # fail on marks
      # - id: watermarks-remover-clean # opt-in: clean in place

Ethics

For privacy and research on content you own or are authorized to process. Not for academic fraud or false “human-written” claims. Users must follow local law. The authors disclaim liability for misuse.

See skills/remove-ai-marks/references/ethics.md.


License

MIT — see LICENSE.

Bibliography (selected)

  • How Claude marks AI-generated content
  • Dathathri et al., Scalable watermarking for identifying large language model outputs (SynthID-Text, Nature 2024)
  • Kirchenbauer et al., A Watermark for Large Language Models (arXiv:2301.10226)
  • C2PA / c2patool
  • Liu et al., Image Watermarks are Removable Using Controllable Regeneration from Clean Noise (CtrlRegen, ICLR 2025)
  • THU-BPM/MarkLLM, MarkDiffusion

SIMILAR PLUGINS