Skip to main content
Glama
m053m716

LaTeX MCP

by m053m716

LaTeX MCP

LaTeX MCP is a local stdio Model Context Protocol server for compiling and inspecting LaTeX projects with this machine's TeX Live 2025 installation. It is intended for Claude Code and OpenAI Codex in VS Code, but any MCP client that supports local stdio servers can use it.

The server always invokes binaries under C:\texlive\2025\bin\windows; it does not trust the caller's PATH, cannot fall through to MiKTeX, never enables shell escape, and does not expose package installation.

Architecture

VS Code client
  -> .venv\Scripts\python.exe server.py (MCP over stdio)
     -> C:\tools\latex\build-latex.ps1
        -> C:\texlive\2025\bin\windows\latexmk.exe
           -> C:\texlive\2025\bin\windows\pdflatex.exe

The MCP repository owns the protocol surface, tests, and an MCP-local minimal English format configuration. TeX Live is a machine dependency. The PowerShell wrapper remains the canonical low-level build entry point.

Manuscript repositories do not need copies of server.py, .venv, or this repository. Tools accept an explicit absolute project_dir, so the MCP server process does not need to start in the manuscript workspace. If project_dir is empty, CLAUDE_PROJECT_DIR is used when available.

Related MCP server: LaTeX PDF MCP Server

Prerequisites and setup

  • Windows 11 x64.

  • Python 3.11 or newer; this installation uses Python 3.12.10.

  • TeX Live 2025 at C:\texlive\2025.

  • Build wrapper at C:\tools\latex\build-latex.ps1.

TeX Live 2025

On Windows 11 if you don't have it yet, you can follow these steps from admin powershell:

  1. Install/update git

winget install --id Git.Git -e
  1. Install/update Python 3.12

winget install --id Python.Python.3.12 -e
  1. Install/update cURL

winget install --id cURL.cURL -e
  1. Use cURL to install TeX Live 2025 installer/follow instructions thereafter:

$repo = "https://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2025/tlnet-final"
$installer = "$env:TEMP\install-tl-2025.exe"

curl.exe -L "$repo/install-tl-windows.exe" -o "$installer"

& $installer -repository $repo

In the TeX Live installer, select Advanced and configure:

Scheme: small Installation root: C:\texlive\2025 Default paper size: Letter

Source and documentation installation can also be disabled if you want to minimize the installation size.

Complete the TeX Live installation.

  1. Install the additional packages required by LaTeX_MCP
    After the base installation succeeds:

$tlmgr = "C:\texlive\2025\bin\windows\tlmgr.bat"

& $tlmgr --repository $repo install `
    ieeetran `
    latexmk `
    microtype `
    amsmath `
    amsfonts `
    mathtools `
    siunitx `
    booktabs `
    tools `
    makecell `
    algorithms `
    algorithmicx `
    pgf `
    xcolor `
    dblfloatfix `
    hyperref `
    placeins `
    preprint `
    cm-super

tlmgr automatically resolves and installs dependencies required by these packages.

  1. Verify the installation

$bin = "C:\texlive\2025\bin\windows"

& "$bin\pdflatex.exe" --version
& "$bin\latexmk.exe" --version
& "$bin\tlmgr.bat" --version
& "$bin\kpsewhich.exe" IEEEtran.cls
& "$bin\kpsewhich.exe" tikz.sty
& "$bin\kpsewhich.exe" siunitx.sty
& "$bin\kpsewhich.exe" algpseudocode.sty

Verify the default paper configuration with:

& "$bin\tlmgr.bat" paper

If necessary, explicitly set Letter afterward:

& "$bin\tlmgr.bat" paper letter

The resulting installation should reside at:

C:\texlive\2025

and the executables used by LaTeX_MCP should come explicitly from:

C:\texlive\2025\bin\windows

rather than from MiKTeX or another TeX distribution on PATH.

Installation from Repo

Create or refresh the isolated environment from this repository:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install ".[test]"

Dependencies are pinned in pyproject.toml; no global Python install is required. The current MCP SDK pin is mcp==2.0.0 and the test pin is pytest==8.4.2.

An editable install also exposes helper console scripts for registration:

.\.venv\Scripts\python.exe -m pip install -e .

Script

Scope

Purpose

latex-mcp

Run the stdio MCP server (same as invoking server.py).

latex-mcp-vscode

Project

Generate project-local config for one VS Code repository.

latex-mcp-install

User

Register the server in the global user Claude and Codex config.

Both registration scripts resolve this repository's .venv interpreter and server.py automatically (override with --python / --server), and every file they touch is reconciled in place: an existing latex entry is replaced rather than duplicated. Pass --dry-run to preview.

This machine's protected TeX Live tree does not contain a writable texmf-dist\ls-R filename database. The server handles that state by configuring read-only Kpathsea disk searches and user-scoped formats/maps. The MCP-local texmf directory supplies a minimal US-English format configuration; it does not change manuscript sources.

Tools

Tool

Arguments

Result and behavior

latex_environment

None

Reports exact TeX Live roots, binary paths, versions, BibTeX/Biber availability, wrapper availability, and filename-database state.

latex_find_file

filename

Resolves a simple TeX filename using the explicit TeX Live kpsewhich.exe; paths and option-like input are rejected.

latex_build

project_dir, main_tex="main.tex", clean_first=false

Runs the known wrapper with pdfLaTeX/LatexMk, noninteractive file/line errors, halt-on-error, SyncTeX, and no shell escape. Output is bounded; the full .log remains beside the manuscript.

latex_clean

project_dir, main_tex="main.tex"

Runs LatexMk -C for the selected main file and removes only standard generated products.

main_tex must resolve to a .tex file inside project_dir. Absolute paths, option-like names, missing files, and traversal outside the project are rejected. Subprocesses use argument arrays with shell=False.

Resources

URI

MIME type

Purpose

latex://templates/ieeetran-journal-preamble.tex

text/x-tex

Preferred baseline preamble for new 10-point IEEEtran journal manuscripts, including the documented mathematics, units, table, algorithm, TikZ, float, link, and balancing setup.

Discover the template with MCP resources/list and fetch its text with resources/read. It is a starting point: add manuscript-specific packages after reviewing compatibility, and let repository or venue requirements override it. The resource ends before title metadata and \\begin{document}, so callers can append a project-specific body. Existing documents are not automatically rewritten to use it.

Development and tests

Launch the stdio server directly:

C:\MyRepos\Python\LaTeX_MCP\.venv\Scripts\python.exe C:\MyRepos\Python\LaTeX_MCP\server.py

The terminal appears idle because it is waiting for MCP JSON-RPC on stdin. Diagnostics go to stderr; stdout is reserved for the protocol.

Run all automated unit, integration, and stdio protocol tests:

.\.venv\Scripts\python.exe -m pytest -q

The realistic IEEE smoke source is testdata\ieee_smoke\main.tex. Tests compile it with IEEEtran, algorithms, TikZ, siunitx, microtype, and the rest of the documented package stack, confirm PDF creation, and clean the generated output.

Registration

Project scope (one repository)

Run the generator from inside the repository you want to configure, or pass its path:

latex-mcp-vscode              # configures the current directory
latex-mcp-vscode C:\MyRepos\Papers\MyPaper

It reconciles these local artifacts, upserting a single latex entry into each:

File

Client

.mcp.json

Claude Code (project scope)

.codex\config.toml

Codex (project-local)

.vscode\mcp.json

VS Code native MCP client

.gitignore

Ignores the machine-specific local config above

AGENTS.md

Agent usage guidance and preferred IEEE style (managed block)

LATEX_MCP.md

Human note describing what was generated and how to verify

User scope (every project)

To register the server for all projects at once:

latex-mcp-install

It upserts the latex entry into %USERPROFILE%\.claude.json (mcpServers) and %USERPROFILE%\.codex\config.toml ([mcp_servers.latex]), preserving unrelated servers and settings.

Claude Code registration (manual reference)

Claude Code's MCP documentation specifies that user-scoped MCP servers are stored at %USERPROFILE%\.claude.json. The latex entry belongs under the top-level mcpServers object:

{
  "type": "stdio",
  "command": "C:\\MyRepos\\Python\\LaTeX_MCP\\.venv\\Scripts\\python.exe",
  "args": [
    "C:\\MyRepos\\Python\\LaTeX_MCP\\server.py"
  ]
}

This is user scope, so it is available in every Claude Code project. After configuration changes, reload the Claude Code VS Code session, open /mcp or the MCP management UI, and confirm that latex is connected and exposes four tools. The standalone claude CLI is not required.

Codex registration (manual reference)

OpenAI's MCP documentation specifies that the Codex IDE extension and CLI share %USERPROFILE%\.codex\config.toml. The user-level entry is:

[mcp_servers.latex]
command = "C:\\MyRepos\\Python\\LaTeX_MCP\\.venv\\Scripts\\python.exe"
args = ["C:\\MyRepos\\Python\\LaTeX_MCP\\server.py"]
cwd = "C:\\MyRepos\\Python\\LaTeX_MCP"
startup_timeout_sec = 15
tool_timeout_sec = 300
enabled = true

In VS Code, open the Codex gear menu, select MCP servers, and restart the extension after configuration changes. Confirm that latex is enabled and connected. Codex's official documentation states that the IDE extension and CLI share config.toml; the standalone CLI is not required for normal extension use.

Example agent requests

For guidance on selectively turning substantive implementation concepts into repository-local technical notes, see the technical manuscript workflow.

From any unrelated manuscript repository, ask:

Use the latex MCP server to compile the manuscript in the current workspace. Find the main TeX file, compile it, inspect any errors, fix the errors, and recompile until the build succeeds.

For a precise call, provide the project path:

Use latex_build with project_dir="C:\MyRepos\Papers\MyPaper" and main_tex="main.tex".

Troubleshooting

  • Call latex_environment first. Its pdflatex.path must be C:\texlive\2025\bin\windows\pdflatex.exe, and its version must contain TeX Live 2025. A MiKTeX path or version indicates that execution did not come through this server.

  • Use latex_find_file("package.sty") to distinguish a missing TeX package from a manuscript error. Package installation is intentionally not an MCP tool; maintain TeX Live separately with deliberate tlmgr administration.

  • Review the returned error summary, then open the complete .log at the returned log_path. MCP responses intentionally truncate large process output.

  • A normal warning that shell escape is disabled confirms the intended security policy. Documents that require external shell commands must use a separately reviewed workflow.

  • If a client shows the server as disconnected, verify both absolute registered paths, run the test suite, then reload the relevant VS Code extension. Editing a configuration file alone does not prove extension connectivity.

  • The TeX Live tree on this machine is read-only and uses per-user formats/maps. After changing TeX Live format sources or font packages, rerun the appropriate user maintenance (fmtutil-user or updmap-user) before rebuilding.

Updating

Pull or edit this single repository, activate no global environment, and run:

.\.venv\Scripts\python.exe -m pip install --upgrade ".[test]"
.\.venv\Scripts\python.exe -m pytest -q

The Claude and Codex registrations use stable absolute paths into this repository, so routine server updates do not require copying files or duplicating configuration in manuscript repositories.

Handoff MCP — session memory for agents

This repo has the handoff MCP server configured (see .mcp.json / .codex/config.toml). It is a durable, project-scoped place to leave breadcrumbs between sessions. Use it instead of re-deriving context.

At the start of a session, call handoff_list to reload where prior work stopped and what to do next, and todo_list for outstanding next steps. This is cheaper and more reliable than re-reading the whole transcript.

While working, when you find something that must be done but is not the current focus, call todo_add rather than holding it in the conversation.

When context gets heavy (stale greps, large logs, finished sub-tasks pile up), call context_report, then context_compact — it returns a summarise-then-handoff procedure and can persist the summary as a handoff in one call.

At the end of a work chunk, call handoff_add with a summary, next steps, and the few key facts (file paths, decisions, gotchas) the next worker needs. A fresh session can then resume from handoff_list alone.

Close the loop with todo_update (done/dropped) and handoff_resolve so the open lists stay a true worklist.

Tool

Use it to

handoff_list

Reload breadcrumbs at session start.

handoff_add

Record where you stopped and what is next.

handoff_resolve

Mark a handoff done.

todo_add / todo_list / todo_update

Track next-step TODOs.

project_status

Counts of open todos and handoffs.

context_report / context_compact

Notice and shrink a bloated context window.

Every tool is scoped to this project only; there is no way to reach another project's data. Full reference: docs/TOOL_GUIDE.md.

Available Tools

4 tools
latex_buildA

Build a project with pdfLaTeX/LatexMk, no shell escape, and bounded diagnostics.

ParametersJSON Schema
NameRequiredDescriptionDefault
main_texNomain.tex
clean_firstNo
project_dirNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden for behavioral disclosure. It does disclose useful operational constraints: no shell escape and bounded diagnostics. However, it does not mention that clean_first may delete or clean build artifacts, nor does it explain the side effects of a build beyond implying compilation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every phrase adds value: the tool's action, the engines used, and two important constraints are all communicated efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and 0% schema description coverage, the description leaves important gaps around parameter behavior, side effects of clean_first, and when this tool should be selected over siblings. The presence of an output schema helps with return values, but the invocation context is not fully specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description provides no parameter-specific meaning. The property names main_tex, project_dir, and clean_first are somewhat self-explanatory, but clean_first's behavior is not described at all, and the description does not compensate for the missing schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Build a project with pdfLaTeX/LatexMk.' It also adds distinguishing constraints such as 'no shell escape' and 'bounded diagnostics,' which make the tool clearly distinguishable from the sibling tools latex_environment, latex_find_file, and latex_clean.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear that this tool is for compiling/building a LaTeX project, and the 'no shell escape' constraint establishes a boundary for when it is appropriate. It does not explicitly name alternatives or give when-not guidance beyond that constraint, so it stops short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

latex_cleanB

Remove only normal LatexMk-generated products for the selected main file.

ParametersJSON Schema
NameRequiredDescriptionDefault
main_texNomain.tex
project_dirNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description must carry the full behavioral burden for this destructive operation. It does state that files are removed and limits the scope to 'normal LatexMk-generated products,' but it never explains which file types count as normal products, whether project_dir is affected, or whether any confirmation or safety mechanism exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler, the action verb is front-loaded, and the key restriction ('only normal LatexMk-generated products') appears immediately. It earns its place despite being terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with no annotations, no parameter descriptions, and unknown output-schema details, this description leaves important gaps: it does not enumerate the removed artifacts, explain 'normal,' or clarify how the main file and project directory are resolved. The output schema may describe return values, but it cannot compensate for missing operational semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description needed to clarify the parameters. It only loosely aligns with main_tex through the phrase 'selected main file,' and it provides no explanation of project_dir, path resolution, or what happens when parameters are left at their defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ('Remove') and resource ('normal LatexMk-generated products') and scopes the action to the selected main file. This distinguishes it from the sibling build/find/environment tools, though the term 'normal' is somewhat ambiguous and 'selected' is not formally defined.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is used for cleaning up LaTeXMk build products, and the word 'only' hints at a conservative cleanup behavior. However, it does not explicitly state when to choose this tool over latex_build or what situations warrant caution, so usage guidance is mostly implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

latex_environmentA

Report exact TeX Live 2025 binaries, versions, and supporting tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly indicates a read-only reporting operation and specifies the scope of what is reported. It does not detail error behavior or exact output shape, but for a simple no-parameter environment inspection tool this is sufficiently transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, tight sentence with no filler. Every word adds meaning: 'exact' signals precision, 'TeX Live 2025' specifies the version, and 'binaries, versions, and supporting tools' defines the report contents.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema and clearly differentiated siblings, this description is complete. An agent knows what to expect from the tool and can choose it correctly without needing additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema already fully covers this dimension. The description adds relevant scope about what the report includes, which is the only semantic information an agent could need here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Report'), a concrete resource ('TeX Live 2025 binaries, versions, and supporting tools'), and clearly differentiates from siblings like latex_build and latex_clean. An agent can immediately tell this is an environment-inspection tool, not a file-search or build tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: whenever an agent needs to know the exact TeX Live version, binaries, or installed supporting tools. However, it does not explicitly state when not to use it or contrast it with latex_find_file/latex_build/latex_clean, so usage guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

latex_find_fileA

Resolve a simple TeX package or class filename with TeX Live kpsewhich.

ParametersJSON Schema
NameRequiredDescriptionDefault
filenameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the burden of explaining behavior. It does disclose that the tool uses kpsewhich and is limited to 'simple' package/class filenames, but it does not describe what happens on success or failure (e.g., return value, error behavior) or whether it is purely read-only. This leaves some ambiguity for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It packs the key information—operation, resource type, and method—into minimal words, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple single-parameter tool, and the description covers the core operation, especially since an output schema exists to document return values. However, with no annotations, the description does not fully cover usage context, limitations of 'simple', or expected behavior when the file is not found, so it is only minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, 'filename', has no schema description, and schema coverage is 0%. The description compensates by specifying it is a 'TeX package or class filename' and hinting at the expected granularity via 'simple'. This adds meaningful context beyond the bare property name, though it still leaves open details like extension or path format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Resolve') and a clear resource ('TeX package or class filename') and mentions the underlying mechanism (TeX Live kpsewhich). It naturally distinguishes this tool from siblings like latex_build and latex_clean, which are clearly different operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied by the verb 'resolve' and the TeX domain, but the description does not explicitly state when to prefer this tool over latex_environment, latex_build, or latex_clean. There is no explicit when-not-to-use or alternative routing, though the sibling names make the distinction fairly intuitive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.3.1
    • First observedlatex_build
    • First observedlatex_clean
    • First observedlatex_environment
    • First observedlatex_find_file

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a distinct concern: environment inspection, file resolution, compilation, and cleanup. There is no functional overlap between them.

Naming Consistency4/5

All tools share the latex_ prefix and mostly use verb-led names like find_file, build, and clean. latex_environment is the only noun-based deviation but remains predictable in context.

Tool Count5/5

Four tools form a tight, well-scoped set for LaTeX project workflows without redundancy or bloat. Each tool serves a clear purpose.

Completeness4/5

The set covers the main lifecycle of inspecting, resolving, building, and cleaning LaTeX projects. Minor gaps exist such as no explicit output preview or detailed log retrieval, but the core workflow is complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers