articulate
Articulate checks prose on your computer. It names each writing pattern it finds and the line it sits on, and a profile for each kind of writing decides which findings block.
python -m pip install articulate-writing
articulate check README.md --profile readme --gate
Python 3.9 or newer. The checker uses only the standard library and needs no model, account or API key.
$ articulate check post.md --profile readme --gate
[articulate] post.md [readme]: 4 high, 2 medium (blocked) texture 100/100
L3 [HIGH antithesis] it's not just X, it's Y: This release is not just a bug fix; it is a new foundation. ...
L3 [HIGH corporate-verb] leverage / underscore / reflect (as corporate verb): ...
L4 [HIGH filler-intensifier] genuinely / really / truly / actually: ...
With --gate the command exits 1 when a high finding blocks under the chosen profile, so it drops into CI or a pre-commit hook.
Use it on documentation, READMEs, release notes, essays and commit messages. It flags stacked hedges, marketing words, corporate verbs, contrast framing, rule-of-three lists, em dashes and the rhetorical habits common in model-written text.
Articulate is a style checker and is not an authorship detector. On 183 texts of known origin it flagged all 84 AI texts and 57 of 75 human texts (76%, 95% interval 65% to 84%), including 10 of 18 essays by English learners (results.json). Do not use a finding to decide who wrote a text or to grade a student.
What it does
- Check. Flags rhetorical devices (antithesis, corrective negation, rule-of-three, em dashes, filler intensifiers, corporate verbs), marketing and email register, and plain-style signals such as expletive openers, nominalization density, passive voice, adverb density and uniform cadence. Each run gives a 0 to 100 texture score and a pass or block result.
- Profiles.
procedure,commit,research,readme,essay,narrativeand more set which findings block. Procedures gate strictly and fiction gates nothing. A profile comes from--profile, awriting-profile:tag in the file, or the file path. - Modes and genres. A mode pairs a register with a purpose, such as
memo/argueortechnical-docs/explain. Genres (literary-fiction,genre-fiction,ya-fiction,memoir,screenplay,poetry) read narrative prose by their own conventions, and quoted speech stays out of the device checks.articulate modeslists them all. - Edit.
judgereads problems a pattern rule cannot see, such as a vague claim or a weak verb.fixrewrites to the standard and rechecks the result.polishloops until the draft clears a quality bar. These use a model you configure, the calling model in an MCP host, or mechanical fixes with no model. - Receipts.
articulate receiptrecords a check, andarticulate verifyreplays it against the file later.articulate auditqueries a folder of committed receipts. - House voice.
articulate house ongives an AI model a published, versioned voice: answer first, numbers with denominators.articulate house offturns it off. - Your own voice.
articulate voice learn --minebuilds a profile from files you name. Compare drafts with it, or shape your own draft toward it. - A voice from intent.
articulate voice intendtakes a goal, an audience and a stance and writes a spec with a plan.articulate voice check draft.md --intent spec.jsonscores the draft against it and names, by line, the template shapes a line-by-line check misses: one-line paragraphs, anaphora runs, closing maxims, "It is not X. It is Y." See a voice built from intent. - Series review.
articulate corpusreads several documents together and reports repeated title formulas, shared paragraph scaffolds and even rhythm, with locations. - Dialogue.
articulate dialoguechecks game and stage scripts and builds character voice sheets.
Use it from anywhere
# command line
articulate check path/to/doc.md --gate
articulate check essay.md --profile essay --verbose
echo "some prose" | articulate score
# Python
python -c "import articulate; print(articulate.check_text('...', profile=articulate.profiles.load('research'))['gate'])"
# receipts
articulate receipt doc.md --profile research > doc.receipt.json
articulate verify doc.receipt.json doc.md # exit 0 match, 1 drift, 2 unverifiable
articulate receipt doc.md --redact drop > receipts/doc.json # keeps no matched text
# CI: SARIF for GitHub Code Scanning, Azure or reviewdog
articulate check docs/*.md --sarif > articulate.sarif
# editors and AI clients
python -m articulate.lsp_server # LSP over stdio
python -m articulate.mcp_server # MCP server
Every command also runs as python -m articulate.cli. The CLI reference lists each command, flag and exit code.
Editor setup
The LSP server speaks standard LSP over stdio. A minimal Neovim registration:
vim.lsp.start({ name = "articulate", cmd = { "python", "-m", "articulate.lsp_server" },
filetypes = { "markdown", "text", "tex" } })
In VS Code, any LanguageClient that launches the same command works.
Editing with a model
In an MCP host, fix, judge and polish use sampling when the client offers it. Otherwise they return an edit plan: the host writes the rewrite with its own model and calls edit_submit, and Articulate checks protected spans and returns the accepted text. No second model account is needed.
articulate plan notes.md --goal fix > plan.json
articulate submit notes.md rewrite.md --plan PLAN_ID --model HOST_MODEL
articulate fix notes.md --backend none --out edited.md
articulate polish notes.md --backend ollama --json
From the command line, --backend auto tries a configured Anthropic key, the Claude CLI, OpenAI-compatible endpoints, Ollama and mechanical editing, in that order. See the backend configuration. A rewrite can change meaning, so read each one before you accept it.
On a .tex file the editor masks every math span before a rewrite and restores it byte for byte. The proof mode academic/prove routes to judge by default and rewrites only with --fix. Articulate checks the prose of a proof and leaves the mathematics alone.
Where text goes
The checker and --backend none make no network call. The Anthropic and Claude CLI backends send text to Anthropic. An OpenAI-compatible endpoint or an Ollama server receives text at the address you configure. In an MCP host, edits go through that host and its model. Set ARTICULATE_LOCAL_ONLY=1 to allow only loopback Ollama and mechanical editing.
A receipt made with --redact drop keeps the rule, tier and line of each finding and no matched text. --redact hash keeps a sha256 of the match, which can be reversed for rules with a small fixed word list. A voice profile holds aggregate statistics and stays on your computer until articulate voice delete --all.
How it compares
- Vale enforces a style guide you write as YAML rules. Articulate ships its own rule set and register profiles, plus receipts and a texture score.
- proselint and write-good flag usage problems and weak phrasing. Articulate covers hedges and weak phrasing too, and adds contrast framing, rule-of-three lists and corporate verbs, with a profile deciding which ones block.
- LanguageTool and Grammarly check grammar and spelling, and their main products send text to a server. Articulate does not check grammar or spelling.
- Hemingway Editor scores readability in an editor window. Articulate runs from the command line and in CI, and names the rule and line for each finding.
Install options
Version 0.16.0 is on PyPI as articulate-writing. The changelog lists what each release added.
- Windows x64 native ZIP and MCPB packages bundle a Python runtime.
- The Claude plugin runs local checks and host editing in Claude Code, Codex and other MCP hosts that have Python installed.
Documentation
- Getting started: install, a first check and an editor squiggle.
- Walkthrough: one document from check to rewrite to a committed receipt.
- Features: every capability and how to reach it.
- CLI reference: each command and flag, with exit codes.
- Boundaries: what a result and a receipt mean.
- House voice, series and your own voice, a voice built from intent, dialogue.
- Animated explainer: one draft through the checker, profiles, texture score and receipts.
Metadata
Release files for articulate-writing 0.16.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| articulate_writing-0.16.0.tar.gz | 2.1 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| articulate_writing-0.16.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / articulate_writing-0.16.0.tar.gz
| Download URL | articulate_writing-0.16.0.tar.gz |
|---|---|
| Size | 2.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
249c3ad1df2120327ad067a2a7b1eda36ae1d873569213bd8f932f212eb4352e
|
|
BLAKE2b-256 checksum How to use checksums |
c1dbd819bdf1d53ba402a9f8d2e2f5dbd02b47b75c03c225f8fd4df58077a1e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / articulate_writing-0.16.0-py3-none-any.whl
| Download URL | articulate_writing-0.16.0-py3-none-any.whl |
|---|---|
| Size | 345.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f1d6daa8255870c7ce84623bae2121dd92bd716ee22cdfc498578c858365515
|
|
BLAKE2b-256 checksum How to use checksums |
dbf2aa2ca81c08ca8190c3779de91fbbf0b190fb30d8de5e0e109a1148a42280
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logSecurity for articulate-writing 0.16.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for articulate_writing-0.16.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.