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/\includegraph, 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 β
npxre-resolves the branch against GitHub on every launch and reinstalls if the commit changed. Push tomasterand 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 pullwhen you want updates.
Getting your credentials
- Project ID β open the project in ShareLaTeX; the ID is the last segment of the URL:
https://sharelatex.tum.de/project/[PROJECT_ID] - 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:
- Env vars (single project) β
SHARELATEX_PROJECT_ID+SHARELATEX_GIT_TOKEN. Optional:SHARELATEX_PROJECT_NAMEfor the display name. - Token from a file β set
SHARELATEX_PROJECT_IDtogether withSHARELATEX_GIT_TOKEN_FILE=/path/to/token.txt(instead ofSHARELATEX_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. - Multi-project file β
SHARELATEX_PROJECTS_CONFIG=/absolute/path/projects.json. - User config dir β
projects.jsonin:- Windows:
%APPDATA%\sharelatex-mcp\projects.json - macOS / Linux:
$XDG_CONFIG_HOME/sharelatex-mcp/projects.json(defaults to~/.config/sharelatex-mcp/projects.json)
- Windows:
- Working directory β
./projects.json - Package directory β
projects.jsonnext 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:
- Find sources with the Zotero MCP (
zotero_semantic_search,zotero_advanced_search). zotero_export_bibliography(item_keys=[...], export_format='bibtex')β raw BibTeX.add_bib_entriesmerges it by key and pushes. Nothing already present is touched.- Cite it. Check
list_bib_keysfirst if you're unsure what's already there. validate_projectconfirms every\citekey 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
gitthrough 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_FILEover inlining the token in the Claude Desktop JSON if your config file is backed up or synced. projects.jsonis.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.