vinconig

ShareLaTeX MCP Server

Community vinconig
Updated

ShareLaTeX MCP Server

An MCP (Model Context Protocol) server that gives Claude and other MCP clients access to ShareLaTeX projects over Git β€” read LaTeX files, analyze document structure, extract sections, and write changes back.

It targets ShareLaTeX @ TUM (TUM's self-hosted Overleaf Server Pro instance) by default, and works with any other Server Pro deployment that has Git integration enabled β€” just set SHARELATEX_HOST.

Forked from mjyoo2/OverleafMCP, which targets overleaf.com. This fork speaks the Server Pro URL shape (https://<host>/git/<project_id>) instead.

Features

  • πŸ“„ Files: list, read, write, append, and delete β€” with parent directories created on demand and binary files refused rather than mangled
  • πŸ—ΊοΈ Outline: one document-order tree across the whole \input/\include graph, not just per file
  • ✍️ Targeted edits: replace a section, or insert a new one before/after an anchor, leaving the rest of the file untouched
  • βœ… Validation without compiling: unbalanced braces, unclosed environments, unknown citation keys, undefined labels, missing includes β€” no LaTeX installation needed
  • πŸ“š Bibliography merging: import BibTeX by citation key, idempotently, so nothing already cited is ever lost
  • πŸ•“ History: log, diff, and revert a file to any commit
  • πŸ—οΈ Multi-project: several projects, even across instances

Quick Start (recommended)

No clone, no npm install. Add this block to your Claude Desktop config and restart Claude Desktop.

Config file location

OS Path
Windows %APPDATA%\Claude\claude_desktop_config.json
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Linux ~/.config/claude/claude_desktop_config.json

macOS / Linux

{
  "mcpServers": {
    "sharelatex": {
      "command": "npx",
      "args": ["-y", "github:vinconig/ShareLatexMCP"],
      "env": {
        "SHARELATEX_PROJECT_ID": "YOUR_PROJECT_ID",
        "SHARELATEX_GIT_TOKEN": "YOUR_GIT_TOKEN"
      }
    }
  }
}

Windows β€” Claude Desktop on Windows needs cmd /c to find npx:

{
  "mcpServers": {
    "sharelatex": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "github:vinconig/ShareLatexMCP"],
      "env": {
        "SHARELATEX_PROJECT_ID": "YOUR_PROJECT_ID",
        "SHARELATEX_GIT_TOKEN": "YOUR_GIT_TOKEN"
      }
    }
  }
}

Restart Claude Desktop. The sharelatex tools should appear in the πŸ”§ menu.

The host defaults to sharelatex.tum.de, so TUM users need nothing beyond the project ID and token.

Updating: nothing to do β€” npx re-resolves the branch against GitHub on every launch and reinstalls if the commit changed. Push to master and the next Claude Desktop restart runs it.

The flip side is that each launch needs network access to GitHub. If you want the server to start offline (or faster), use the local clone from Local Development instead and git pull when you want updates.

Getting your credentials

  1. Project ID β€” open the project in ShareLaTeX; the ID is the last segment of the URL: https://sharelatex.tum.de/project/[PROJECT_ID]
  2. Git Token β€” ShareLaTeX β†’ Account Settings β†’ Git Integration β†’ "Create Token". The token is shown once; copy it immediately.

Sanity-check the pair from a terminal before wiring up Claude Desktop β€” this should prompt for a password (paste the token) and clone:

git clone https://[email protected]/git/YOUR_PROJECT_ID

Using another Server Pro instance

Set SHARELATEX_HOST alongside the other env vars:

"env": {
  "SHARELATEX_PROJECT_ID": "...",
  "SHARELATEX_GIT_TOKEN": "...",
  "SHARELATEX_HOST": "sharelatex.example.edu"
}

A full URL is accepted too (https://sharelatex.example.edu/) β€” it is reduced to the bare hostname. The Git URL is always built as https://<host>/git/<project_id>.

In a multi-project projects.json, set host per project instead; it overrides SHARELATEX_HOST for that entry.

Multi-Project Setup

The env-var Quick Start only handles a single project. For multiple projects, drop a projects.json file into the user config directory and skip the env block in your Claude Desktop config.

File location

OS Path
Windows %APPDATA%\sharelatex-mcp\projects.json
macOS / Linux ~/.config/sharelatex-mcp/projects.json (or $XDG_CONFIG_HOME/sharelatex-mcp/projects.json if set)

File contents

{
  "projects": {
    "default": {
      "name": "Main Paper",
      "projectId": "...",
      "gitToken": "..."
    },
    "thesis": {
      "name": "My Thesis",
      "projectId": "...",
      "gitToken": "..."
    },
    "external": {
      "name": "Paper on another instance",
      "projectId": "...",
      "gitToken": "...",
      "host": "sharelatex.example.edu"
    }
  }
}

Claude Desktop config β€” same as Quick Start but no env block:

{
  "mcpServers": {
    "sharelatex": {
      "command": "npx",
      "args": ["-y", "github:vinconig/ShareLatexMCP"]
    }
  }
}

(Add cmd /c on Windows, as in the Quick Start.)

Reference a specific project in tool calls with projectName:

Use read_file with filePath: "main.tex", projectName: "thesis"

If projectName is omitted, the default entry is used. To put projects.json somewhere other than the standard location, point SHARELATEX_PROJECTS_CONFIG=/absolute/path/projects.json at it from the env block.

Configuration Reference

The server picks the first matching configuration source:

  1. Env vars (single project) β€” SHARELATEX_PROJECT_ID + SHARELATEX_GIT_TOKEN. Optional: SHARELATEX_PROJECT_NAME for the display name.
  2. Token from a file β€” set SHARELATEX_PROJECT_ID together with SHARELATEX_GIT_TOKEN_FILE=/path/to/token.txt (instead of SHARELATEX_GIT_TOKEN). Useful when you don't want the token in the Claude Desktop JSON. The file is read once at startup and any trailing whitespace/newline is trimmed.
  3. Multi-project file β€” SHARELATEX_PROJECTS_CONFIG=/absolute/path/projects.json.
  4. User config dir β€” projects.json in:
    • Windows: %APPDATA%\sharelatex-mcp\projects.json
    • macOS / Linux: $XDG_CONFIG_HOME/sharelatex-mcp/projects.json (defaults to ~/.config/sharelatex-mcp/projects.json)
  5. Working directory β€” ./projects.json
  6. Package directory β€” projects.json next to the server script (legacy, for clone-based installs).

SHARELATEX_HOST is independent of the above β€” it applies to every project that doesn't set its own host, and defaults to sharelatex.tum.de.

When env vars are set and a file is also present, env vars win and a notice is logged to stderr so the shadowing is visible.

Environment variables

Variable Required Purpose
SHARELATEX_PROJECT_ID yes (single-project mode) Project ID from the ShareLaTeX URL
SHARELATEX_GIT_TOKEN yes, unless ..._FILE is used Git token from Account Settings
SHARELATEX_GIT_TOKEN_FILE β€” Path to a file containing the token
SHARELATEX_HOST β€” Instance hostname (default sharelatex.tum.de)
SHARELATEX_PROJECT_NAME β€” Display name for the single project
SHARELATEX_PROJECTS_CONFIG β€” Absolute path to a projects.json

Local Development

Option 1 β€” Run the cloned script directly

git clone https://github.com/vinconig/ShareLatexMCP.git
cd ShareLatexMCP
npm install

Then point Claude Desktop at the script and pass credentials via env vars (the same loader path the npx install uses):

{
  "mcpServers": {
    "sharelatex": {
      "command": "node",
      "args": ["/absolute/path/to/ShareLatexMCP/sharelatex-mcp-server.js"],
      "env": {
        "SHARELATEX_PROJECT_ID": "...",
        "SHARELATEX_GIT_TOKEN": "..."
      }
    }
  }
}

On Windows, args should use "C:\\Users\\you\\ShareLatexMCP\\sharelatex-mcp-server.js".

If you'd rather use a multi-project file:

cp projects.example.json projects.json   # then edit it

projects.json next to the script is the lowest-priority fallback, so this still works without env vars.

Option 2 β€” Smoke-test the MCP protocol from the shell

No Claude Desktop required:

SHARELATEX_PROJECT_ID=... SHARELATEX_GIT_TOKEN=... node sharelatex-mcp-server.js

You should see ShareLaTeX MCP server running on stdio on stderr. The process stays open waiting for JSON-RPC on stdin; Ctrl+C to exit.

To drive a real tool call, pipe in an initialize handshake followed by a tools/call:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_files","arguments":{}}}' \
| SHARELATEX_PROJECT_ID=... SHARELATEX_GIT_TOKEN=... node sharelatex-mcp-server.js

The working clone lives in your temp directory as sharelatex-<project_id>.

Available Tools

All tools take an optional projectName (defaults to "default"). Every tool that writes takes a commitMessage.

Reading and navigating

Tool Purpose
list_projects List configured projects.
list_files List files. Defaults to .tex; pass extension: "*" for everything, includeBuild: true to include build/.
read_file Read a text file. Binary files (PDF, images) are rejected rather than returned as mojibake. Optional maxBytes.
get_sections Sectioning commands in one file, with line numbers.
get_outline Document-order outline of the whole thesis, following \input/\include recursively from main.tex. Use this instead of get_sections on main.tex, which contains only includes.
get_section_content The content of one section by title.
search_project Regex or literal search across files β†’ file:line text.
status_summary File counts by extension, chapter list, bibliography size, validation totals.
validate_project See below.

Writing

Tool Purpose
write_file Write a complete file. Creates parent directories.
write_section Replace one existing section, leaving the rest of the file untouched. occurrence disambiguates repeated titles.
insert_section Insert a new section before/after an anchor section, or at end_of_file. write_section cannot add sections that don't exist yet.
append_to_file Append to a file, creating it if absent.
delete_file Remove a file and push the deletion.

Bibliography

Tool Purpose
list_bib_keys Citation keys already in the bibliography, with type and title.
add_bib_entries Merge BibTeX by citation key. Existing keys are kept unless overwrite: true, so nothing already cited can be lost. Re-running with the same input is a no-op.

History

Tool Purpose
file_history Recent commits, optionally for one file.
show_diff Diff the working tree against a commit (default HEAD~1).
revert_file Restore a file from a commit and push that restoration.

Validation

validate_project checks the whole \input graph without compiling β€” no LaTeX installation required, so it works identically in Claude Desktop:

Check Severity
Unbalanced braces error
\begin{X} / \end{X} mismatch error
\input/\include target missing error
Citation key not in bibliography.bib warning
\ref/\autoref to an undefined label warning
Duplicate \label warning
Undefined glossary or acronym key warning

Comments are ignored, and the bodies of verbatim/lstlisting/minted blocks are excluded so code samples with unbalanced braces don't produce false alarms.

Every write goes through the same structural gate: a write whose result would have unbalanced braces or an unclosed environment is refused before pushing, with the offending line numbers. Warnings never block β€” you routinely cite a key moments before importing it β€” they come back in the tool response instead.

Thesis workflows

Citations, without exporting .bib by hand

If you also have a Zotero MCP configured in the same client, the manual "export from Zotero, upload to the web editor" loop disappears:

  1. Find sources with the Zotero MCP (zotero_semantic_search, zotero_advanced_search).
  2. zotero_export_bibliography(item_keys=[...], export_format='bibtex') β†’ raw BibTeX.
  3. add_bib_entries merges it by key and pushes. Nothing already present is touched.
  4. Cite it. Check list_bib_keys first if you're unsure what's already there.
  5. validate_project confirms every \cite key resolves.

Two things to get right up front: zotero_export_bibliography renders through Zotero's web API even in local mode, so it needs ZOTERO_API_KEY and ZOTERO_LIBRARY_ID; and citation keys must be stable (BetterBibTeX with pinned keys), or citations silently rot when keys drift.

Figures and tables

This server writes UTF-8 β€” it cannot push a PNG. That is a better fit for LaTeX than it sounds: write plots as pgfplots code plus a CSV, both plain text, both pushable:

\begin{figure}[htpb]
  \centering
  \begin{tikzpicture}
    \begin{axis}[xlabel={Epoch}, ylabel={Accuracy}]
      \addplot table[x=epoch, y=acc, col sep=comma] {figures/results.csv};
    \end{axis}
  \end{tikzpicture}
  \caption{Validation accuracy.}\label{fig:accuracy}
\end{figure}

Vector output, reproducible, diffable, and it regenerates when the numbers change β€” unlike an exported bitmap. Tables work the same way via pgfplotstable, or as booktabs markup. Genuinely binary assets (screenshots, photographs) still have to go through the web editor.

Conventions that survive both Claude Desktop and Claude Code

Put a CONVENTIONS.md in the LaTeX project itself and start writing sessions with "read CONVENTIONS.md first". It travels with the project and is readable through read_file anywhere β€” unlike client-specific configuration. Worth encoding: which citation and cross-reference commands your template uses, label prefixes, table style, and one sentence per line, which is what makes show_diff and section rewrites reviewable.

Safety

Avoid leaving the ShareLaTeX web editor open on a project while writing through the MCP β€” the editor auto-commits, which shows up here as a rejected push. After a substantial rewrite, show_diff then revert_file if it went wrong.

Usage Examples

# List all projects
Use the list_projects tool

# Get project overview
Use status_summary tool

# Read main.tex file
Use read_file with filePath: "main.tex"

# Get Introduction section
Use get_section_content with filePath: "main.tex" and sectionTitle: "Introduction"

# List all sections in a file
Use get_sections with filePath: "main.tex"

# Write the full content of a file to the project
Use write_file with filePath: "main.tex", content: "...", commitMessage: "..."

# Write the content of a specific section to the project
Use write_section with filePath: "main.tex", sectionTitle: "Introduction", newContent: "\\section{Introduction}\n...", commitMessage: "..."

Security Notes

  • The Git token grants full read/write access to your project β€” treat it like a password.
  • The token is passed to git through a credential helper reading it from the process environment. It never appears on a command line and is never written into the temp clone's .git/config.
  • Prefer SHARELATEX_GIT_TOKEN_FILE over inlining the token in the Claude Desktop JSON if your config file is backed up or synced.
  • projects.json is .gitignored in this repo. Never commit real project IDs or Git tokens.
  • File paths supplied through MCP tool calls are restricted to the cloned project directory; .. traversal and absolute paths are rejected.

License

MIT β€” see LICENSE. Original work Β© mjyoo2.

MCP Server Β· Populars

MCP Server Β· New

    PSU3D0

    agent-spreadsheet

    MCP server for spreadsheet analysis and editing. Slim, token-efficient tool surface designed for LLM agents.

    Community PSU3D0
    pitiflautico

    NeoBrowser

    MCP server that drives real Chrome with your real logged-in sessions β€” genuine fingerprint (passes bot.sannysoft), human-like input, bot-wall aware. 43 tools, single static Rust binary.

    Community pitiflautico
    aeonfun

    Aeon MCP Server

    The most autonomous AI agent framework: runs unattended on GitHub Actions, self-healing skills, drives Claude Code, Grok, Codex & more. No approval loops. Configure once, forget forever.

    Community aeonfun
    nhadaututtheky

    NeuralMemory

    NeuralMemory stores experiences as interconnected neurons and recalls them through spreading activation, mimicking how the human brain works. Instead of searching a database, memories are retrieved through associative recall - activating related concepts until the relevant memory emerges.

    Community nhadaututtheky
    norrietaylor

    Distillery

    Team knowledge evaporates daily β€” pairing sessions, debugging context, architectural rationale lost to Slack. Distillery captures it at the point of creation, connects it into a living graph, and surfaces it conversationally. It monitors feeds, tracks what matters to your projects, and alerts you before you know to ask. A team brain that learns.

    Community norrietaylor