Fresh drop on r/PromptEngineering. Someone built a tool that flags generic AI writing, and the twist is that it never guesses.
What’s new
u/adrnptcl open-sourced grai, a local MCP server that checks a draft for the structural habits that give LLM writing away. It runs inside Claude Desktop, Cursor and Windsurf, so you don’t leave your editor to use it. Because it’s local, your draft stays on your machine. That’s a real plus if you’re checking client work, unpublished posts or anything under NDA.
It looks at 8 patterns. The post names these:
- Flat sentence variance (low burstiness). Every sentence lands at about the same length, so the text reads like a metronome.
- Contrastive negation (“It is not X, it is Y”). The model loves setting up a strawman just to knock it down.
- Symmetrical parallelism (“Less talking, more doing”). Two halves that mirror each other a little too neatly.
- Epiphany openers. The “Here’s the thing” and “Let me tell you something” family of dramatic entrances.
- Triadic padding. Three items in a row because three feels complete, even when two would do.
- Predictable transition glue. The “Moreover” and “Furthermore” connectors that hold paragraphs together without adding anything.
The post doesn’t spell out all 8 in the version I read, so I’m only listing the six it names. Check the repo for the rest.
None of these is wrong on its own. Humans write triads and contrasts too. What gives the game away is how often they show up and how evenly they’re spaced. A draft with one “not X, it’s Y” is fine. A draft with six of them in 800 words has an accent.
The twist
Most AI detectors hand you a percentage. Tweak one word in your prompt and the number jumps around, so you can’t tell whether your edit helped. You end up chasing a score that behaves more like weather than feedback.
grai skips the probability game. It’s built on editing mechanics: either a sentence has the pattern or it doesn’t. Same text in, same answer out, every time. One commenter put it well: the model writes, a script judges, and the script never changes its mind.
That matters because you can finally tell if a rewrite made things better. A score that moves for no reason is noise. A fixed rule is something you can work against. It also makes the tool easy to trust in a team setting. If two people run the same draft, they get the same flags, so you can argue about the writing instead of arguing about the tool.
There’s a second benefit people tend to miss. Because the output is a list of specific patterns and not a verdict, it tells you what to change. A detector that says “78% likely AI” gives you nothing to act on. A checker that says “this sentence is a contrastive negation” gives you a sentence to go fix.
Mini-workflow (my take on how I’d use it)
- 🧪 Paste a draft into the live test at grai.page/#test. No signup needed. Use something real, like a blog post or a cold email you already wrote with an LLM, so the result means something.
- 🔍 Read which patterns it flags. Look for the “not X, it’s Y” lines and the neat three-item lists first, since those are the easiest to spot and the quickest to fix. Note how many flags you get per pattern, not just the total.
- ✂️ Rewrite only the flagged spots. Break the rhythm, vary the sentence length, cut the glue words. Try one very short sentence next to one long one. Swap a tidy list of three for a list of two, or four.
- 🔁 Run it again. Because the checker is deterministic, a clean result means you actually fixed something. If a new flag appears, you’ve introduced a different habit, so fix that one too.
- ⚙️ Like it? Install the MCP server from the GitHub repo (adrianpeticila/grai) and run it where you write. Once it’s inside Claude Desktop, Cursor or Windsurf, you can ask your assistant to run the check on the file you have open and apply fixes in the same session.
Pro tips
- Use it on the draft you’re about to send to a client. Catching the AI accent before they do is the whole point.
- Don’t just delete flagged lines. Rewrite them with a concrete detail, since vague text is often what made the pattern show up. “Our tool is not slow, it’s thoughtful” becomes “The report takes four minutes because it checks every row twice.”
- Keep it as a final pass, not a writing guide. If you write to please the checker, you’ll make a new pattern.
- Run it on your old, pre-AI writing once. Seeing which flags your own human drafts trigger tells you how much weight to give each one.
- Save a before and after of a few drafts. Over a couple of weeks you’ll see which habits your prompts keep producing, and you can fix them at the source by adjusting the prompt itself.
One honest note
This is a young project with a small following so far, and I haven’t stress-tested it on long documents. The author is asking what edge cases people hit, so that tells you it’s still being shaped. Expect rough edges with things like quoted text, code blocks and non-English drafts, and treat any flag as a suggestion to look, not an order to obey. Reporting what breaks is probably the most useful thing you can do for it.
Call to action
Grab a draft you already suspect sounds a bit robotic and run it through grai.page/#test. Then tell me which pattern caught you most often. Mine would be the triads. ☠
Frequently Asked Questions
Q: Why use a fixed script instead of an AI detector’s percentage?
The model writes and a plain script judges, so the same draft gets the same score every time. That means you can edit a draft, rerun the check, and see exactly which pattern moved. A number that shifts with every prompt tweak is hard to act on.
Q: Why did one paragraph score 80, then 100, after only moving punctuation?
A commenter ran the public gate.py on an 86-word paragraph. Moving sentence boundaries (commas where full stops were) changed the CV score from 80 to 100, so some readers think the metric rewards punctuation habits more than real voice. Until that’s fixed, treat a low score as a reason to reread the sentences, not as a verdict.
Q: Does it catch AI writing in languages other than English?
Not reliably yet. A commenter found that a German AI-style text full of filler passed without a flag, and the public rules are English-only. If you draft in another language, do a manual read-through and lean on the score less.
Q: How do you know the checker’s tests would catch a bug?
One commenter’s team runs mutation tests. A script makes tiny changes to the checker’s code, like swapping a less-than sign for a less-than-or-equal sign, and the test suite should fail every time. Their goal is to catch 80 percent of those changes, and a surviving change points to a missing test.
Q: Is there a quick way to find friction in the tool?
Hand the tool to a fresh agent with no context and ask it to run the whole thing end to end. Commenters said this surfaced rough spots the builders had missed. It’s cheap and easy to repeat after every change.
I built a deterministic cadence checker that flags generic AI writing before clients do
by u/adrnptcl in PromptEngineering