prosemeter
pnpm add prosemeter

Deterministic scoring for prose.

Agents close the loop on code with compilers, linters, and tests. Prose has no such signal.

prosemeter is one. Give it a document and a named profile. It returns a score, 15 per-dimension scores, and findings with line numbers and fix hints — enough to revise, measure, and know when to stop.

Score a document ↓Use it

chat-jargon.md
$ prosemeter score chat-jargon.md --profile chat

chat-jargon.md  49/100  (profile: chat)

Dimensions
  grade-band             2  median grade 25.8 vs band 7–12 (FK 25…
  sentence-simplicity   26  7 hard sentences / 194 words
  clarity               45  4 wordy phrase(s) / 194 words
  directness            71  2 weasel/hedge word(s) / 194 words
  active-voice         100  0 passive construction(s) / 194 words
  … 10 more dimensions

Findings
    chat-jargon.md:1:1  warn  Sentence reads at ~grade 23, above…
      → 26 words, grade ~23 — split or simplify.
    … 12 more
15scored dimensions
7built-in profiles
0model calls
0network requests

The same answer, two registers

Both documents answer the same question with the same fix. One scores 92 on the chatprofile. The other scores 49. Toggle between them and watch which dimensions move.

A correct answer nobody wants to read. Every idea is right; the register buries all of them.

49/100·floor 75below·194 words·v0.4.4

Dimension scores, worst first
grade-band2median grade 25.8 vs band 7–12 (FK 25.8, Fog 30.5, SMOG 24.1, CL 25.1, ARI 26.0); Flesch Reading Ease -40.2
sentence-simplicity267 hard sentences / 194 words
clarity454 wordy phrase(s) / 194 words
lexical-diversity31MTLD 195.1 vs band 50–120
directness712 weasel/hedge word(s) / 194 words
sentence-variety80sentence-length variation 0.22 vs band 0.4–0.9
5 dimensions at 100
active-voice1000 passive construction(s) / 194 words
concision1000 concision issues (repeats, redundant acronyms, clichés) / 194 words
paragraph-length1005 paragraph(s) vs band 1–6 sentences
terminology-consistency1000 inconsistent term use(s) / 194 words
spelling-consistency1000 mixed-spelling occurrence(s) / 194 words
heading-hierarchydisabled by profile
section-lengthdisabled by profile
document-balancedisabled by profile
acronym-definitiondisabled by profile

Findings

sentence-simplicity

clarity

directness

Try another document

Scored in your browser. Nothing was uploaded, and there is no model in the loop.

A score is not enough

A linter says what is wrong. It does not say whether the rewrite helped, or when to stop rewriting.

Those are the two questions that make a revision loop terminate, and prosemeter answers both.compareBaseline diffs a result against the previous one and reports which findings resolved and which are new. checkConvergence reads a score history and returns one of five verdicts.

const result  = score(draft, { profile: "readme" })
const delta   = compareBaseline(current, previous)
const verdict = checkConvergence([62, 71, 74, 74.5], { threshold: 80 })
// "improving" | "plateaued" | "oscillating" | "regressing" | "converged"

The distinct stop reasons let a harness attach policy. regressing means revert to the highest-scoring earlier draft rather than push the latest one further.

You cannot buy the score by shortening sentences

The obvious way to game a readability metric is to chop every sentence. Here is what that gets you.

The cat sat. The cat is big. The cat is red. It ran. It ran fast.

Perfect on 100 for sentence-simplicity, 100 for clarity, and 100 for concision. It still scores 71 and falls below the chat floor of 75.

grade-band is the reason. It is a band, not a goal — full marks inside the target range, falling off on either side. This reads at grade -2.1 against a floor of 7, so the dimension carrying the profile's largest weight scores 5.

The design generalizes. Targets are ranges, so there is no single number to run away with, and anything gamed by chopping sentences is counterweighted by something that punishes it.

choppy-simplistic.md
$ prosemeter score choppy-simplistic.md --profile chat

choppy-simplistic.md  71/100  (profile: chat)

Dimensions
  grade-band             5  median grade -2.1 vs band 7–12 (FK -2…
  sentence-simplicity  100  0 hard sentences / 90 words
  clarity              100  0 wordy phrase(s) / 90 words
  concision            100  0 concision issues (repeats, redundan…
  … 11 more dimensions

Findings
    choppy-simplistic.md:4:1  warn  Unexpected weasel (vague or a…
      → If the claim holds only under a condition, name the condi…
    … 4 more

Measured, not asserted

236 scored answers across three runs on claude-opus-5, plus a Sonnet transfer check.

32% shorter

A style instruction against a no-instruction control on the same six tasks: 438 → 298 words, jargon 10.7% → 8.7%, sentence-simplicity 50.2 → 69.9.

n=90 · 2026-08-03

Naming the swap is what works

“Be concise. Avoid jargon. Write clearly.” reaches 350 words and 10.3% jargon. Telling a model which words to prefer moved jargon; telling it to avoid jargon did not.

Wording does not reach accuracy

Two runs and one targeted mechanism test, no effect. The instruction written to fix an observed error failed on that exact error in 4 of 5 replicates.

Read dimensions, not the composite

Across seven variants the composite spanned 79.5–86.6 while the spread within one variant was about 15 points. The dimensions moved 2–3x over the same data.

The method and the caveats →

One engine, four ways in

The library is the whole thing. The rest are thin wrappers so an agent or a CI job does not have to be one.

library

TypeScript

ESM, typed, returns an Either so errors stay explicit.

pnpm add prosemeter
cli

Command line

Exits non-zero below a threshold, so CI can gate on it.

prosemeter score README.md
mcp

MCP server

Five tools over stdio. Each description teaches the loop.

npx @prosemeter/mcp
plugin

Claude Code

The server plus a skill that says when to stop revising.

/plugin install prosemeter@prosemeter

What it is not

A deterministic prose metric is a proxy, and any agent optimizing a proxy will find its seams.

The bands blunt the worst of that. The honest framing matters more than the guardrail: prosemeter is a floor and a loop terminator, not a quality oracle. It tells an agent whether a draft cleared the objective bar and when to stop iterating. It does not tell you the prose is good.

It also cannot check facts. Two eval runs and one targeted mechanism test found that style instructions move length and vocabulary by 2–3x and move factual accuracy not at all. A high score is not a correctness signal.

And it measures how a document reads, not whether it makes sense to a particular reader — a gap we have measured and not yet closed →

prosemeter 0.4.4. Every score on this page was computed at build time.