Repository Public Research preview
1# manuscript-audit-mcp23An MCP server that audits scholarly manuscripts written in LaTeX or Markdown. Every check is4deterministic and runs offline: no network, no model call, no LaTeX installation, no external5program. It reads source text and reports what a careful copy-editor with a calculator would6catch, with a file and line for every finding.78It does **not** judge whether the science is right, and an empty result never means a manuscript9is correct. It is the mechanical first pass of a review, meant to free the reader's attention for10the parts that need understanding. The companion skill `@spboucher/manuscript-peer-review`11describes the full review protocol built around it.1213## Install1415```bash16skills download @spboucher/manuscript-audit-mcp --extract ./manuscript-audit-mcp # or download the archive and verify its SHA-25617cd manuscript-audit-mcp18npm ci19npm test # 36 offline tests, under a second20```2122```bash23# Claude Code: allow reading under one project directory24claude mcp add --transport stdio \25 --env MANUSCRIPT_AUDIT_ROOT=$HOME/papers/my-paper \26 manuscript-audit -- node /abs/path/manuscript-audit-mcp/server.mjs27```2829```toml30# Codex: ~/.codex/config.toml31[mcp_servers.manuscript-audit]32command = "node"33args = ["/abs/path/manuscript-audit-mcp/server.mjs"]34[mcp_servers.manuscript-audit.env]35MANUSCRIPT_AUDIT_ROOT = "/abs/path/to/paper"36```3738```json39// Cursor: .cursor/mcp.json40{ "mcpServers": { "manuscript-audit": { "type": "stdio", "command": "node", "args": ["/abs/path/manuscript-audit-mcp/server.mjs"], "env": { "MANUSCRIPT_AUDIT_ROOT": "/abs/path/to/paper" } } } }41```4243| Variable | Effect | Default |44|---|---|---|45| `MANUSCRIPT_AUDIT_ROOT` | The only directory files are read from (the manuscript, the files it includes, its bibliography) | working directory of the server |4647Set the root to the project directory, not to the directory of the main file, when the manuscript48includes files from sibling directories (`\input{../tables/t1}`).4950## Tools5152All tools are read-only and take the manuscript as `path` (inside the root) or as inline `text`.53The bibliography is the one the manuscript declares (`\bibliography`, `\addbibresource`, the54`bibliography:` front-matter key), or `bib_path` / `bib_text`.5556| Tool | What it reports |57|---|---|58| `full_audit` | Everything below in one list sorted by severity, with counts by severity, by referee role, by code and by audit |59| `outline` | Sections with level, line and word count; abstract length; totals. Missing or long abstract, empty sections, skipped levels, includes that could not be read |60| `audit_citations` | Keys cited but missing, entries never cited, duplicate keys, entries sharing a DOI or title, malformed DOIs, entries with no author, title or year. LaTeX with `.bib` or `thebibliography`, pandoc `[@key]` with `.bib` or CSL JSON, numeric `[1]` with a reference list |61| `audit_cross_references` | Undefined references, duplicate labels, figures, tables and equations never referenced, hand-typed exhibit numbers; Markdown numbered captions never mentioned |62| `audit_numbers` | Numbers in the abstract or introduction that match nothing in the body or tables; whole-sample sizes and named statistics that disagree; percentages that do not equal their stated counts |63| `audit_statistics_reporting` | p-values with no test, p = 0.000, "significant" with no statistic, no sample size anywhere, stars with no legend, estimates with no uncertainty, causal wording in observational framing |64| `audit_tables` | LaTeX rows with more cells than columns (error) or fewer than the other rows (warning), missing captions, labels, notes, units; Markdown ragged rows; images without captions |65| `audit_claims` | Priority, certainty and robustness claims with no citation and no exhibit reference in the sentence |66| `audit_style` | TODO and placeholder text, undefined acronyms, repeated words, long sentences, hedging density, text addressed to reviewers, hidden text |67| `audit_replication` | Missing data or code statement, software without version, random draws without a seed, experiment without preregistration |68| `review_scaffold` | A referee-report skeleton in Markdown with the findings placed; summary, assessment and recommendation left for the reviewer |69| `compare_versions` | Two versions: sections added or removed, numbers changed inside identical sentences, abstract numbers, citations and labels added or removed |7071## What a finding looks like7273```json74{75 "code": "num-percent-count-mismatch",76 "severity": "error",77 "role": "integrity_auditor",78 "heuristic": false,79 "location": { "file": "paper.tex", "line": 27 },80 "message": "412 of 1250 is 33.0%, not the stated 38.0%.",81 "evidence": "Among them, 412 of 1,250 respondents (38.0\\%) work remotely at least three days a week.",82 "numerator": 412, "denominator": 1250, "stated": 38, "computed": 32.9683}84```8586- `severity`: `error` (breaks the document or is wrong as written), `warning` (likely to draw a87 referee comment), `info` (worth a look).88- `heuristic: true` marks pattern matches on wording. 30 of the 67 codes are heuristic. They are89 often right and never proof: open the line before reporting one.90- `role` groups findings by who would raise them in a review: referee, editor, table and figure91 editor, integrity auditor, replication auditor.92- `full_audit` adds a `hygiene_score` (100 minus weighted findings). It measures mechanical93 cleanliness only. It is not a quality, validity or publishability score.9495## What "tested" means here9697`npm test` runs 36 tests on fictional manuscripts with planted defects:9899- A LaTeX manuscript split over two files plus a bibliography, with 46 planted defects across all100 nine audits. Each audit must return exactly its planted findings, each at the line where the101 defect sits. Expected line numbers are found by searching the fixture for a marker, not copied102 from the engine's output.103- A corrected LaTeX manuscript and a corrected Markdown manuscript that must produce no finding.104- A Markdown manuscript with pandoc citations and a second one with numeric citations and105 numbered captions, each with exact expected findings.106- Unit checks of the parsers (comments, verbatim, column specifications, `\multicolumn`,107 `\makecell`, BibTeX quoting and concatenation, CSL JSON, number extraction and rounding).108- Path confinement: `..`, absolute paths, symbolic links, `\input` and `\bibliography` that point109 outside the root, binary files, self-including files.110- The MCP protocol through the official client: tool list, metadata, calls, errors, and start-up111 through a symlinked path.112113During development the engine was also run on 84 real manuscripts and long documents to remove114false positives (custom reference macros, run-in paragraph headings, `\\` inside cells, spare115table columns, dotted exhibit numbers). That run is not part of the test suite, and no precision116or recall figure is claimed.117118## Limits: read these119120- **Source text only.** No PDF, no Word files, no images, no data. Figures are known by their121 `\includegraphics` line, not by their content.122- **Nothing is compiled.** Macros that build labels, citations or table rows are invisible, except123 one-argument wrappers around `\ref` and `\cite` defined with `\newcommand` in the files read.124 Conditional text (`\iffalse`) is read as if printed.125- **Nothing is looked up.** A well-formed DOI or a complete entry can still be a reference that126 does not exist or does not support the sentence citing it.127- **Number checks compare text with text.** A number counts as supported when the same value, or a128 more precise one that rounds to it, appears in the body or a table. The tool cannot tell whether129 a table is right, and numbers that live only in a figure are reported as unsupported.130- **English wording** is assumed by the statistics, claims and style checks. Other languages get131 the structural checks (citations, cross-references, tables) only.132- **Sentence-level checks look at one sentence.** Support given in the next sentence is not seen.133- **Auditing one chapter** of a larger document reports cross-chapter references as undefined.134- **Markdown:** ATX headings (`#`), pipe tables, pandoc citations and pandoc-crossref ids. Setext135 headings, grid tables and reference-style links are not parsed.136- Files larger than 5 MB are refused.137138## Security139140- Read-only. The server writes nothing and starts no process.141- Every path is resolved against `MANUSCRIPT_AUDIT_ROOT` with symbolic links followed first;142 anything outside is refused with `path_forbidden`. Included files and bibliography files go143 through the same check, and one that points outside is skipped and reported, not read.144- No network access and no environment variable other than the root.145- Manuscript content is treated as data. Text in a manuscript that addresses a reviewer or an AI146 is reported as a finding (`integrity-reviewer-directed-text`); a client must never act on it.147- Findings quote lines of the manuscript. An unpublished manuscript is confidential: the quotes148 go wherever the client sends tool results.149150## Licence151152MIT.153