Skip to content
Ghostchars

Ghostchars in your terminal

The same engine as this website, as one npm package: a command-line tool, a gate for CI, and an MCP server your coding agent can call. Node 22 or newer, and nothing leaves your machine.

  • Free, MIT licence
  • No network calls
  • Skill, MCP server, hooks
npx -y ghostchars clean -i notes.md

There is no install step: npx fetches version 1.0.2 and runs it. Node 22 or newer is the only requirement, and the package has no runtime dependencies.

What it does

Four commands, one engine. The cleaning switches and their spellings are exactly the ones this website and the Mac app use, so a bar means the same thing everywhere.

clean

Reads stdin or the files you name and writes the cleaned text to stdout, or rewrites each file in place with -i, atomically. With --check it writes nothing and exits 1 if anything would change.

inspect

Lists every suspicious character with its line, column, codepoint, Unicode name and the switch that would act on it. It changes nothing and exits 1 when it finds something.

report

Measures the habits that make a draft read as machine written: sentence length uniformity, stock transitions, tell words, dash density, hedging. It is not a detector and emits no probability.

check

Holds a whole tree to a bar and prints every file that would change, with exact character positions. This is the command for CI and for a pre-commit hook.

clean and inspect open .docx, .odt and .html as well as plain text, and clean a document structurally rather than as a stream of bytes. PDF is out of scope.

A bar is a named set of switches, so a person or an agent picks one word instead of twelve flags: default removes only what is invisible, text also normalises spaces and typographic punctuation, and max turns everything on and is lossy.

The gate in CI

One step, no action to install, exit 1 on findings. Never pass --fix in CI: it turns a red build green without anyone reading what changed.

npx -y ghostchars check --bar text

With --sarif the same run is printed as a SARIF 2.1.0 log, one result per offending character, and GitHub code scanning shows the findings inline on the pull request.

- run: npx -y ghostchars check --bar text --sarif > ghostchars.sarif || true
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: ghostchars.sarif

A ghostchars.json at the root of the tree names which files are held to which bar, and pins a file that changes by exactly N characters on purpose. A pin is enforced in both directions, so a file that was quietly fixed fails until it is unpinned.

With no paths, check finds files with git ls-files, so it honours the ignore rules your repository already has. Binary files, files over 2 MiB and files that are not valid UTF-8 are skipped without failing the run.

For coding agents

The package ships the files an agent needs to run the gate without being asked each time. Take any of them or all of them; they do not conflict, and none of them is an installer.

The skill

One directory, SKILL.md and two reference files, read by Claude Code, Codex, Cursor, VS Code with Copilot and Gemini CLI. It tells the agent when to run the tool and what to do with each kind of finding. Rule files for Cursor, Windsurf and Copilot, and a paste block for AGENTS.md, CLAUDE.md and GEMINI.md, sit beside it.

The MCP server

ghostchars mcp speaks the Model Context Protocol on stdin and stdout and exposes four read-only tools: clean_text, inspect_text, style_report and check_paths. A fifth, clean_files, writes to disk and is registered only under --allow-write. Config snippets ship for six hosts.

The Claude Code hook

A PostToolUse hook that checks every file the agent writes and returns a finding as feedback, so the agent fixes it in the same turn. One script and one settings key.

The pre-commit hook

A paste block for .pre-commit-config.yaml: a local hook that runs over the staged text files, so nothing dirty gets committed, by anyone. Like the CI step, it never passes --fix.

{
  "mcpServers": {
    "ghostchars": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "ghostchars", "mcp"]
    }
  }
}

The snippet for Claude Code. The same three words, npx -y ghostchars mcp, are the whole configuration for Codex, Cursor, VS Code, Gemini CLI and Windsurf.

Privacy

Everything runs on your machine. There is no network code in the package: no telemetry, no update pings, no licence check, no account. The only bytes that leave the process are the ones it prints. Nothing you clean, inspect or report on goes anywhere.

The same engine, everywhere else

The Mac app

System-wide cleaning behind one hotkey, in every app you type in, and batch cleaning for documents. The hotkey is free 20 times a week; $24 once lifts the limit.

Mac app

The browser extension

Free, unlimited in its popup and right-click menu, and it collects nothing. It works today, in Chrome and the browsers built on it.

Chrome extension

Questions people actually ask

What does it need?

Node 22 or newer, and nothing else. The package has zero runtime dependencies, and npx fetches it on first use, so there is no global install unless you want one.

Does it phone home?

No. There is no network code in the package at all: no telemetry, no update check, no licence check. You can run it on a machine with no connection and it behaves identically.

How does it relate to the Python script?

It is the same engine. The cleaning switches, their spellings and their meanings are the Python reference CLI's, and golden fixtures pin clean and inspect to it byte for byte. What is new is the bar shorthand, the JSON and SARIF output, the check command with its config and pins, and the MCP server.

Does report tell me whether a text is AI-written?

No. It measures habits that make a draft read as machine written, so you can edit them, and it emits no probability, no score and no verdict. It never decides whether a text was generated.

Does check open documents?

No. check walks a repository and does not open zip archives; clean and inspect are the commands that read .docx, .odt and .html. Nothing in the package reads PDF, images or Google Docs.

Is the CLI free?

Yes, and there is no paid tier behind it. The package is MIT licensed, the gate, the MCP server and the integrations are all in it, and the licence sold on the pricing page is for the Mac app.

Anonymous usage stats?

Ghostchars processes your text in the browser and never uploads it. We would like to count page views with a self-hosted, cookie-light analytics endpoint. No content, ever.