About Patina
Patina is an offline writing checker for people refining AI-generated or self-written drafts. It marks lines that may read as machine-written and explains why, without changing the file.
Key features
- 01Flags machine-like phrases and sentence patterns
- 02Ranks predictable sentences
- 03Compares sentence traits with human ranges
- 04Checks short headlines and taglines
- 05Offers profiles for different writing contexts
- 06Runs as a CLI and MCP server
Use cases
- 01Review an AI draft before sharing it
- 02Find stylistic habits in personal writing
- 03Check headlines before publication
- 04Add writing checks to CI or pre-commit
MCP support
Patina runs locally as an MCP server and exposes four tools: patina_check, patina_explain, patina_rules and patina_profiles, plus the rewrite_with_patina prompt.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEPatina
Write with AI. Still sound like you. Patina marks the lines in your draft that read as machine-written, and tells you why.
An AI draft saves time. It also tends to leave a few sentences behind that nobody you know would say. Patina finds those lines and explains what gives each one away. It never touches your file, so the rewriting, and the voice, stay yours.
It works on writing you did yourself too. If people keep telling you your work sounds like ChatGPT, Patina shows which habits they are hearing, and you decide which to keep.
What it checks
- Tells: the stock phrases and sentence shapes readers have learned to spot.
- Predictability: the sentences a language model would have written first, ranked, so you know where to start.
- The Copybook: each sentence measured against two published novels for its grammar, its words, how it opens and where its commas fall. Lines outside the human range get marked.
- Short lines: a brief, a filter and a cold read for headlines and taglines, so you can see if a stranger understands a line before it goes live.
Before and after
The opening of a short story: the first AI draft, and the same scene after rewriting with Patina.

Every draft is different, so the best test is your own. It's free: run it on something you wrote.
Quick start
You need Node 18 or later. Nothing else to install.
npx github:taxmanhaven/patina-showcase check my-draft.md
Each mark comes back with its line and column, how serious it is, and why it reads as machine-written:
my-draft.md:3:1 warning connector-open "Moreover," Let the ideas join by their own logic.
my-draft.md:3:14 warning style-words "delve" Use the plain word a person would say.
Not sure what a mark means? patina explain style-words.
Pick the profile that fits the reader with --profile: fiction, web (the default), email, pro-email, technical, playful, captions, spoken, headline, testimonial or ui. If you clone the repo, node tools/cli.mjs does the same without npx.
Inside your AI app
Patina also runs as an MCP server, so Claude, Cursor or any app that speaks MCP can check its own draft before it hands it to you. It runs on your machine, offline, and never changes your text. The app sees four tools (patina_check, patina_explain, patina_rules, patina_profiles) and one prompt, rewrite_with_patina: check, rewrite only the marked lines, check again.
Claude Code:
claude mcp add patina -- npx -y github:taxmanhaven/patina-showcase mcp
Claude Desktop, Cursor and others take the same command in their MCP settings:
{
"mcpServers": {
"patina": { "command": "npx", "args": ["-y", "github:taxmanhaven/patina-showcase", "mcp"] }
}
}
Then ask: "Write the launch email, and run it past Patina before you show me."
In CI, or before a commit
The exit code is 0 on a pass and 1 when the draft fails its profile, so a pull request can't merge a page that reads as boilerplate. --format github puts the marks inline on the pull request:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npx -y github:taxmanhaven/patina-showcase check docs/*.md --format github
--format json gives the same marks to your own scripts. --fail-on any fails on any mark; --fail-on never only reports.
Settings
patina init writes a .patinarc.json. Patina looks for one in the file's folder and every folder above it:
{
"profile": "web",
"profiles": { ".md": "web", ".txt": "email" },
"disable": ["em-dash"],
"protect": ["A line you wrote on purpose"],
"failOn": "gate"
}
disable takes a rule (style-words), a family (triplet) or a measure (rhythm, specificity). patina rules lists them all.
More tools
For lots of short app strings, use batch:
node tools/patina.mjs batch strings.json --report report.md
For a headline or tagline, fill in templates/headline-brief.txt, then:
node tools/patina.mjs brief brief.txt
node tools/patina.mjs lines --brief brief.txt --candidates candidates.txt
Write each candidate as technique | line / subline. The techniques are in craft/headlines.md.
Optional extras
- The predictability map and the cold reader call a language model through an OpenAI-compatible API (Prima Labs by default). Put your key in the
PRIMALABS_API_KEYenvironment variable. Patina reads it in the process and never prints it.node tools/predict.mjs my-draft.md --out predict.md - The Copybook's grammar layer needs Python 3.12 with spaCy and wordfreq, which you install yourself:
To place a whole draft against the human ranges:pip install "spacy>=3.8,<3.9" wordfreq python -m spacy download en_core_web_md python tools/intro_commas.py check my-draft.mdnode tools/sentences.mjs label my-draft.md --out draft.lab.jsonl(needs the key), thenpython tools/anatomy.py draft.lab.jsonl draft.an.jsonl, thennode tools/copybook.mjs --draft draft.an.jsonl --panel.
The Copybook ships with norms/norms.json, the human ranges, so it works without the books. The norms are numbers only. No book text is included.
What is in here
| Folder | What |
|---|---|
tools/ | the command line (cli.mjs), the MCP server (mcp.mjs), the checker, the predictability map, the Copybook and the tests (npm test) |
craft/ | the headline craft guide and the sentence codebook |
norms/ | human ranges measured on two published novels, with their sources |
templates/ | the headline brief |
glossaries/ | an example list of a product's design words, for the design-leak check |
examples/ | the before and after picture above |
corpus/ | one public-domain chapter (Willa Cather, My Antonia) used as a human anchor |
Honest limits
- Patina points; it does not promise that any detector will pass your text. Expert readers see through word swaps, so the fix is your own rewrite.
- The norms come from fiction. On a README or a sales page, read them as a guide.
- The scan is the floor. Your own ear, and a reader you trust, decide.
Licence
MIT. Use it, change it, build on it. The story excerpt in examples/before-after.png is the exception: it stays the author's. Details in LICENSE and NOTICE.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.