watermarks-remover Is Trending, and Its Own README Argues Against Half of It
The MIT tool that strips AI provenance marks from text and files, what actually comes off, and why the most useful section is the disclaimer
Somewhere in the middle of a tool built to remove AI watermarks, under a heading called "what removing a text watermark costs," the maintainer asks the reader a question that undercuts the feature:
If the plan is to rewrite the text with a cheaper model anyway, why pay for a premium model in the first place? Generating directly with the cheaper model is simpler, cheaper, and produces the same, or better, end result.
That is not a caveat buried in a footnote. It is a section of the watermarks-remover README, sitting inside the repo that ships the rewrite. A project climbing the trending boards this week spends several hundred words explaining why you probably should not use one of its two headline capabilities.
I went in expecting a hype cycle. I came out thinking this is the most honest document published about AI watermarking in the two weeks since Anthropic started marking everything Claude writes.
What it is, mechanically
Guillaume Meyer's MIT-licensed project is an agent skill plus a Python service that strips AI provenance marks from text and files. The skill ships no code at all. It is a thin HTTP client that drives the service, so the agent host never needs Python. The service itself needs Python 3.10 and nothing else from PyPI for the core path, which is a real design choice and not a small one.
Three layers do the work, and they are not equally good:
Layer A removes edit-based Unicode carriers. Zero-width spaces, bidi controls, tag characters, exotic spaces. Deterministic scripts, countable results, testable.
Layer B attacks statistical token-sampling watermarks by rewriting the text. Best-effort, and the README says so in bold.
File cleaners strip C2PA, EXIF, XMP, and document properties from PNG, JPEG, WebP, SVG, PDF, DOCX, ODT, HTML, and Markdown.
The split matters because those three things have completely different truth values. Layer A and the file cleaners produce verifiable removals: you can count the codepoints that came out and diff the metadata blocks that disappeared. Layer B produces a rewritten document and a shrug.
The line the README draws is exact: "Until vendors ship public detectors and keys, no tool can honestly certify 'this fails the official check.'" Reports from the tool separate verifiable work from best-effort work for that reason.
The PDF detail that tells you the maintainer is serious
Most repos in this genre are a regex and a star count. Here is the paragraph that changed my read.
ExifTool writes PDFs incrementally. Run exiftool -all= on a PDF and it appends a %BeginExifToolUpdate block, frees the Info object, and drops /Info from the trailer. The command exits 0. Every viewer shows no metadata. The original metadata bytes are still sitting in the file verbatim, and exiftool itself can undo the edit with -PDF-update:all=.
The file also gets larger, which is the tell.
For a tool whose entire job is removing provenance, that is a silent leak, so clean_pdf follows the exiftool pass with qpdf --linearize, which re-serializes the document from its object graph and drops the now-unreferenced objects. Without qpdf installed, the clean still runs and prints a warning saying the original bytes remain recoverable.
Somebody read the output of their own tool, noticed a file got bigger when it should have gotten smaller, and chased it. That is the difference between a project and a weekend.
The same instinct shows up elsewhere. The text tools used to accept a .docx, decode the compressed bytes, report whatever codepoints fell out of the compression noise, then write the mangled bytes back and destroy the file. They now refuse binary input by magic number plus a control-byte ratio, and name the tool that handles it. There is a --force-text escape hatch for anyone who really wants the old behavior.
Why the disclaimer is the actual contribution
Text watermarks live in the wording. The signal is spread across token choices, so nearly every sentence carries a little of it. Two consequences follow, and the README states both without softening.
Removal means rewording, not restructuring. Shuffling paragraphs, changing headings, and light touch-ups barely move the signal. Stripping a statistical mark means rewriting a substantial fraction of the text sentence by sentence.
And rewording degrades the copy. Any rewrite swaps the original word choices for the rewriting model's, which flattens tone and precision. The README puts a ceiling on it: "the result cannot exceed the rewrite model's ceiling."
There is one more operational note that reads like it came from a real failure: prefer a non-origin model for Layer B. Do not rewrite Claude text with Claude if you are trying to avoid re-stamping it. That is a small sentence with a large implication, which is that a rewrite performed by a marked model produces marked output.
Put those together and you have the honest description of what watermarking currently buys anyone. Layer A and the metadata strip clear the marks that were easy to add and are easy to remove. Layer B degrades your writing in exchange for a probability nobody can measure. Anthropic's own help documentation concedes the mark "may persist through some editing," which is the same claim from the other side of the table: a signal strong enough to tag ordinary AI-assisted editing, weak enough that a determined evader gets around it. The transparency obligation under EU AI Act Article 50 gets satisfied. Deception does not get meaningfully harder.
That is a real finding, and I have not seen it stated more plainly anywhere else, including by the labs shipping the watermarks.
Put this into practice
The useful path here is the boring one, and it takes about ten minutes.
1. Start the service locally. No Docker, no dependencies:
make serve # or: python3 service/scripts/server.py --host 127.0.0.1 --port 8765
It binds to loopback by default and stays there unless you pass --host. Leave it there.
2. Inspect before you clean. Point it at something you wrote and see what is actually in it:
python3 service/scripts/inspect_file.py draft.md
Running inspect on your own published work is the single most informative five minutes in this whole exercise. Most people have never looked.
3. Install qpdf if you touch PDFs at all. Without it the PDF clean is cosmetic, and the tool will tell you so in a warning most people will scroll past.
4. Stop at Layer A plus the file cleaners for anything you care about. The README calls this the lossless path, and it is right. You clear the invisible carriers and the container metadata, and you keep your prose exactly as written.
5. Skip Layer B on production copy. Marketing pages, client work, anything where voice is the product. If you do run it, use a non-origin model, and set WATERMARKS_REWRITE_REASONING_EFFORT deliberately. The default is none for a specific reason: reasoning models were burning 9,894 completion tokens on a rewrite that needed 12.
6. Set an API key if it leaves your laptop. WATERMARKS_SERVER_API_KEY requires a bearer token on every request. The service is built for a trusted network, not the internet.
If you want the whole thing as one unit, the core Docker image ships with exiftool, qpdf, and c2patool preinstalled, and there is a compose stack with profiles for the optional harnesses.
Honest limitations
The star count is a mess and worth naming. GitHub's repo page served roughly 10,000 stars and 1,000 forks when I checked, against 87 commits, 54 watchers, and a latest release of v0.5.0. The trend board that surfaced it reported around 835 stars gained in a day. Those numbers are not contradictory (one is a total, one is a delta) but they are also not the same claim, and neither one tells you the code is good. Eighty-seven commits is a young project by any measure.
The impressive-sounding image capabilities are mostly external and mostly encumbered. Pixel-domain removal runs through CtrlRegen, whose backend ships no LICENSE file at all, so the project treats it as all rights reserved, clones it at a pinned commit, and never publishes the Docker image. The reverse-SynthID scorer is under a non-commercial research license and is also never published. Expect roughly 10 GB of model downloads and plan on a GPU. CtrlRegen is a 512x512 Stable Diffusion 1.5 ControlNet, so large images get tiled and every pass regenerates content. Higher removal strength means more of your image is no longer your image.
C2PA soft binding is out of scope. That is the in-content watermark that can re-link a remote Content Credentials manifest after metadata is stripped, and clearing hard-bound C2PA does nothing to it. If your threat model includes soft binding, this tool does not address it and says so.
The MarkLLM and MarkDiffusion harnesses are verification tools, not oracles. Detection is only valid against the same scheme config and keys used at generation. Proving a mark cleared in your test harness proves nothing about a vendor detector you have never seen.
And the dual-use question does not go away because the README addresses it. The stated scope is privacy and research on content you own, not academic fraud or false claims of human authorship. That is the right line. It is also a line the software cannot enforce, and the third-party ecosystem section already lists an independent desktop GUI that makes drag-and-drop cleaning available to anyone.
The part I keep turning over
The strongest argument against text watermarking is not that a tool can defeat it. It is that the cheapest defeat is also the cheapest workflow.
You do not need Layer B to produce unmarked text. You need an open-weight model running locally, which the README lists in its own removal-options table as an "operational alternative." Anyone motivated enough to evade a watermark will get there long before they install a Python service. The people who end up marked are the ones using a hosted frontier model in good faith to edit their own writing.
So the mark reliably identifies the compliant and reliably misses the motivated. Anthropic's documentation already concedes the second half of that, noting the watermark does not prove Claude wrote the content because people use Claude to edit and translate their own work.
If provenance is worth having, and I think it might be, the version worth building probably looks less like a hidden signal in the output and more like a signed claim the author chooses to attach. Run inspect_file.py on something you published last month and decide for yourself which of those two you would rather have.
Sources: guillaumemeyer/watermarks-remover README, remove-ai-marks skill, Euronews on Anthropic's global watermarking, The Next Web on EU AI Act Article 50.