Repository Public Research preview
1# latex-build-mcp23An MCP server that compiles LaTeX and tells an agent, in structured form, what is wrong with the result: errors with file and line, overfull boxes, Beamer frames that run past the slide, undefined or unused labels and citations, the numbering recorded in the `.aux`, and a LaTeX → Word conversion that keeps cross-reference numbers.45It needs a TeX distribution on the machine (TeX Live or MacTeX). Optional tools add features: `latexmk`, `biber`, `pandoc`, `texcount`, `chktex`, `pdftotext`. `toolchain_status` shows what is there and what each missing tool disables.67## Install89```sh10npm install # in this directory11```1213```json14{15 "mcpServers": {16 "latex-build": {17 "command": "node",18 "args": ["/path/to/latex-build-mcp/server.mjs"],19 "env": { "LATEX_MCP_ROOT": "/path/to/your/papers" }20 }21 }22}23```2425| Variable | Meaning | Default |26|---|---|---|27| `LATEX_MCP_ROOT` | The only directory the server reads and writes | working directory |28| `LATEX_MCP_TIMEOUT_S` | Time limit for each child process, in seconds | 120 |2930## Tools3132| Tool | What it returns |33|---|---|34| `toolchain_status` | Installed tools and versions, engines available, capabilities |35| `compile` | Success, page count, PDF path, parsed diagnostics. `engine`: pdflatex, xelatex, lualatex. `clean: true` builds from scratch |36| `parse_log` | Errors (file, line, context, explanation), warnings, overfull / underfull boxes, undefined references and citations, duplicate labels, missing files, fonts and characters, rerun hints |37| `check_overflow` | Overfull hboxes above `hbox_threshold_pt` with the source text; overfull vboxes; for Beamer, the overflowing frames by number, title and line |38| `beamer_report` | Every frame (title, line, pages, overlay slides), overflowing frames, frames without a title |39| `audit_references` | Static scan: undefined references, duplicate labels with locations, unused labels, unreferenced floats, undefined citations, unused and duplicate `.bib` keys |40| `bib_audit` | Backend expected by the document against the one that ran, entries not found, warnings, errors, incomplete entries |41| `word_count` | texcount figures (text, headings, captions), or a documented approximation |42| `lint` | chktex, curated subset (`all: true` for everything) |43| `extract_numbering` | Number, page and kind of every label; captions; citation labels |44| `to_docx` | A `.docx` with cross-references, caption numbers and equation numbers resolved from the `.aux`, and the list of what does not survive |45| `pdf_text` | Text of a page range of the PDF |46| `clean_build` | Removes the build directory created by this server (`confirm: true`) |47| `explain_error` | Cause and fix for a known error message |4849The tools that read a build (`parse_log`, `check_overflow`, `beamer_report`, `bib_audit`, `extract_numbering`, `to_docx`, `pdf_text`) use the last `compile` of the same file and say so when there is none.5051## Safety5253- **One root.** Every path is resolved, symlinks included, and refused when it leaves `LATEX_MCP_ROOT`. `\input` files outside the root are skipped by the scans.54- **No shell.** Programs are started with `execFile` and a timeout; nothing is passed through a shell.55- **No shell escape.** Engines always run with `-no-shell-escape`: `\write18` and piped `\input` do nothing, and `compile` lists the commands the document tried to run. Documents that need shell escape (minted, externalised TikZ, gnuplot) will not build here; pre-generate their output.56- **No project rc file.** latexmk runs with `-norc`, because a `latexmkrc` is Perl code. Settings from such a file (custom engines, extra rules) are therefore ignored.57- **A marked build directory.** Output goes to `.latex-build/` next to the main file, marked with a file. The server refuses to build into, and `clean_build` refuses to remove, a directory that is not marked. Source files are never deleted or modified.58- **Files are data.** Text in `.tex`, `.bib` and log files is returned as data; the server gives it no authority.5960A TeX document is still a program: it can read files the TeX configuration allows (by default, not parent directories or dotfiles) and loop until the timeout. Compile untrusted documents in a sandbox.6162## Limits6364- Log parsing is exact for logs produced by this server (long lines, `file:line:error`). For other logs, wrapped at 79 columns, file attribution can be missing.65- TeX reports an overfull paragraph when the paragraph ends: a paragraph that starts in an `\input` file and ends in its parent is attributed to the parent.66- Beamer overflow is what Beamer reports as an overfull `\vbox`. Content placed with absolute positioning (textpos, TikZ overlays) that leaves the slide raises no warning. Frame titles come from the source in order; frames produced by macros, `\againframe` or conditionals make the mapping approximate, and the report says so.67- `audit_references` is a static scan: labels and keys built by macros are not seen.68- `to_docx`: cross-references become plain text; section numbers come from pandoc, not the `.aux`; citations are re-rendered by citeproc (author-date unless a CSL file is given); TikZ, custom layout and PDF/EPS images do not carry over.69- `word_count` without texcount is an approximation and is labelled as such.7071## Tests7273```sh74npm test # offline parser tests + real compiles of the fixtures (about 20 s)75npm run test:offline # no TeX needed76```7778The integration tests compile five small fixtures through the MCP protocol and assert exact diagnostics: file and line of each defect, the overflowing frame of the deck, the numbers in the Word file, that `\write18` and a hostile `latexmkrc` do nothing, and that paths outside the root are refused. Tested on macOS with TeX Live 2026, pandoc 3.9 and Node 26. Not tested on Windows or with MiKTeX.7980## License8182MIT83