An MCP (Model Context Protocol) server that connects Claude directly to Overleaf and your local LaTeX toolchain. Instead of copying code out of Claude, pasting it into Overleaf, waiting for compilation, and checking the PDF manually — you just describe what you want. Claude handles the rest.
overleaf-mcp
An MCP (Model Context Protocol) server that connects Claude directly to Overleaf and your local LaTeX toolchain. Instead of copying code out of Claude, pasting it into Overleaf, waiting for compilation, and checking the PDF manually — you just describe what you want. Claude handles the rest.
The Problem
Editing a LaTeX resume in Overleaf with Claude's help looks like this today:
- Ask Claude to tailor your resume to a job description
- Claude returns a wall of LaTeX
- You copy it manually
- You paste it into Overleaf
- You click Recompile
- You check the PDF
- You go back and repeat
That is six manual steps for every single edit. If you are applying to twenty jobs, that compounds fast.
What This Does
overleaf-mcp gives Claude a set of tools to do all of that directly:
- Read and write
.texfiles in your Overleaf project via browser automation - Compile LaTeX locally with TinyTeX or system pdflatex
- Open the compiled PDF in Preview for review
- Tailor your resume to a job description — Claude rewrites the bullets, saves the file, compiles, and opens the PDF, all as a single workflow
- Score your resume against a job description with ATS keyword analysis
- Generate a matching LaTeX cover letter
- Download compiled PDFs from Overleaf to a folder of your choice with human-readable filenames
Everything works with the Overleaf Free tier. No Git bridge required. Browser automation handles the sync.
Requirements
- Node.js 20 or higher
- Claude Desktop or Claude Code (Claude Pro subscription)
- A free Overleaf account
- macOS (the PDF preview step uses
open— Windows/Linux support planned) - pdflatex in your PATH — either via TinyTeX or a full TeX Live install
Installation
Option 1: npx (no install required)
npx overleaf-mcp
Option 2: Global install
npm install -g overleaf-mcp
Option 3: Clone and build locally
git clone https://github.com/Sahith59/OverLeaf_MCP
cd overleaf-mcp
npm install
npm run build
Install Playwright browser (required for Overleaf automation)
npx playwright install chromium
Install TinyTeX (if you do not have pdflatex)
curl -sLO https://yihui.org/tinytex/install-unx.sh
sh install-unx.sh
tlmgr install enumitem hyperref fontawesome5 geometry babel-english
Configuration
For Claude Desktop
Open your Claude Desktop config file:
~/Library/Application Support/Claude/claude_desktop_config.json
Add the overleaf-mcp entry under mcpServers:
{
"mcpServers": {
"overleaf-mcp": {
"command": "npx",
"args": ["overleaf-mcp"],
"env": {
"OVERLEAF_EMAIL": "your@email.com",
"OVERLEAF_PASSWORD": "yourpassword",
"PDF_DOWNLOAD_DIR": "/Users/yourname/Desktop/Resumes"
}
}
}
}
If you cloned the repo locally, use node instead of npx:
{
"mcpServers": {
"overleaf-mcp": {
"command": "node",
"args": ["/absolute/path/to/overleaf-mcp/dist/index.js"],
"env": {
"OVERLEAF_EMAIL": "your@email.com",
"OVERLEAF_PASSWORD": "yourpassword",
"PDF_DOWNLOAD_DIR": "/Users/yourname/Desktop/Resumes"
}
}
}
}
Quit and reopen Claude Desktop after saving the config.
For Claude Code
claude mcp add --scope user overleaf-mcp npx overleaf-mcp
Then restart Claude Code.
Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| OVERLEAF_EMAIL | Yes | — | Your Overleaf login email |
| OVERLEAF_PASSWORD | Yes | — | Your Overleaf login password |
| PDF_DOWNLOAD_DIR | No | ~/Desktop/OverLeaf_Resumes | Where downloaded PDFs are saved |
| LATEX_OUTPUT_DIR | No | ~/.overleaf-mcp/output | Local compile output and file cache |
| DEFAULT_TEMPLATE | No | software-engineer | Default resume template name |
Credentials are never hardcoded. They come from environment variables only — either via the Claude Desktop config block or a .env file when running locally.
Verifying the Setup
After installation and config, open a new Claude conversation and type:
call the ping tool
Expected response:
{
"status": "ok",
"server": "overleaf-mcp",
"overleaf_email_set": true
}
If the tool is not found, confirm the MCP server is registered:
claude mcp list
Usage
Logging in to Overleaf
The first time you use any Overleaf tool:
call overleaf_login
A Chrome window opens and logs you in. The session is stored locally in ~/.overleaf-mcp/browser-data/ and persists across restarts — you should not need to log in again unless you explicitly log out.
If a CAPTCHA appears, solve it manually in the Chrome window. The tool waits up to two minutes.
Getting Your Project ID
Every Overleaf tool requires a project ID. Get it by listing your projects:
call overleaf_list_projects
Response:
{
"projects": [
{ "id": "abc123def456...", "name": "My Resume" }
]
}
The id is a 24-character hex string. Copy it — you will use it in every prompt that touches Overleaf.
Reading and Editing Files
Reading a file caches it to disk and returns only metadata (line count, size). The full content never enters Claude's context unnecessarily — this is intentional to keep token usage low.
read main.tex from overleaf project abc123def456
Making a targeted change (name, email, one bullet point, a date):
In overleaf project abc123def456, change "John Smith" to "Jane Doe" in main.tex
Claude calls overleaf_edit_file with just the old and new string. The full document never appears in the conversation. Token cost for a name change: roughly 50 output tokens.
Pushing a full rewrite after local edits:
Push ./output/main.tex to main.tex in overleaf project abc123def456
Compiling
Compile on Overleaf:
compile overleaf project abc123def456
Compile locally (faster, works offline):
compile ./output/main.tex locally and open the PDF
Downloading the PDF
Download with a timestamp filename (default):
download the pdf from overleaf project abc123def456
Download with a human-readable filename:
download the pdf from overleaf project abc123def456 with filename "stripe-senior-swe"
Saves to PDF_DOWNLOAD_DIR as stripe-senior-swe.pdf.
Tailoring Your Resume to a Job Description
Before tailoring, make sure the file is cached from Overleaf at least once:
read main.tex from overleaf project abc123def456
Then:
Tailor my resume to this job description:
[paste the full job description here]
Claude calls tailor_resume, receives the cached resume alongside the JD, rewrites the bullet points and skills section to match JD keywords, saves the result via write_latex, compiles it, and opens the PDF. No content appears as text in the chat — all steps run as tool calls.
After reviewing the PDF:
Push the tailored resume to overleaf project abc123def456, compile it, and download the PDF with filename "company-role"
ATS Score
Score your resume against a job description to see how well it matches before applying:
Score my resume against this job description:
[paste job description]
Response format:
{
"score": 78,
"verdict": "Good match — missing a few key technical terms",
"matched_keywords": ["Python", "REST API", "PostgreSQL"],
"missing_keywords": ["Kubernetes", "gRPC"],
"weak_sections": ["Summary: too generic"],
"top_suggestions": [
"Add Kubernetes to your skills section — it appears 4 times in the JD",
"Rewrite your summary to lead with distributed systems experience"
]
}
A common workflow is to score first, note the missing keywords, tailor the resume, then score again to confirm improvement.
Generating a Cover Letter
Generate a cover letter for the Senior Software Engineer position at Stripe based on my resume and this JD:
[paste job description]
Claude writes a three-paragraph LaTeX cover letter matching your resume's visual style, saves it to ./output/cover-letter.tex, compiles it, and opens the PDF. One page, no filler.
Full Application Workflow
This is the end-to-end prompt that covers the entire process in one shot:
1. Read main.tex from overleaf project abc123def456
2. Score it against this JD: [paste JD] — note the score
3. Tailor my resume to the same JD
4. Score it again to confirm improvement
5. Generate a cover letter for [Role] at [Company]
6. Compile both files locally and open the PDFs
7. Push the tailored resume to Overleaf, compile, and download with filename "[company]-[role]"
Token Efficiency
Token usage is kept low by design:
overleaf_read_filecaches to disk and returns metadata only — reading a file does not put 2,000 tokens of LaTeX into Claude's contextoverleaf_edit_filedoes find/replace internally — only the changed strings appear in the output, not the full documentoverleaf_push_filereads from disk and writes to Overleaf — no file content passes through Claude's output at alltailor_resume,ats_score, andgenerate_cover_letterread from cache internally — the JD is the only parameter you provide
A simple name change costs around 50 output tokens. JD tailoring is unavoidably larger because Claude needs to read and rewrite the resume, but everything else is kept minimal.
Available Tools
Connectivity
| Tool | Description |
|------|-------------|
| ping | Check that the server is alive and credentials are configured |
Local LaTeX
| Tool | Description |
|------|-------------|
| read_latex | Read a local .tex file |
| write_latex | Write content to a local .tex file |
| compile_latex | Compile with pdflatex, return PDF path or errors |
| open_pdf | Open a PDF in Preview.app |
| list_latex_files | List .tex templates in the templates directory |
Overleaf Automation
| Tool | Description |
|------|-------------|
| overleaf_login | Open browser and log in — session persists across restarts |
| overleaf_logout | Close and clear the browser session |
| overleaf_list_projects | List all your Overleaf projects with IDs |
| overleaf_open_project | Navigate to a project in the browser |
| overleaf_read_file | Download a file from Overleaf and cache it locally — returns metadata only |
| overleaf_edit_file | Find and replace a specific string — token-efficient for targeted changes |
| overleaf_push_file | Push a local file to Overleaf — no content passes through Claude's output |
| overleaf_write_file | Full overwrite of a file in Overleaf — use sparingly, token-heavy |
| overleaf_compile | Trigger Overleaf's compile and wait for the result |
| overleaf_download_pdf | Download the compiled PDF to your configured download folder |
Resume Intelligence
| Tool | Description |
|------|-------------|
| list_templates | List available resume templates |
| switch_template | Copy a template to the active cache as the working file |
| get_cached_resume | Read the cached resume without re-downloading from Overleaf |
| tailor_resume | Rewrite resume bullets to match a job description — triggers full write/compile/open pipeline |
| ats_score | Score resume against a JD with keyword analysis and improvement suggestions |
| generate_cover_letter | Write a matching LaTeX cover letter — triggers full write/compile/open pipeline |
Troubleshooting
Tool not found after setup
Run claude mcp list to confirm the server is registered. If it is missing, re-add it:
claude mcp add --scope user overleaf-mcp npx overleaf-mcp
Restart Claude Code or Claude Desktop and try again.
Login times out
This is usually a slow network or a CAPTCHA. When a CAPTCHA appears, solve it manually in the Chrome window — the tool waits up to two minutes. If login consistently fails, verify your credentials by logging into overleaf.com manually in a browser.
old_string not found on edit
The string must match exactly, including whitespace and line breaks. Copy the text directly from the file rather than retyping it.
Compile fails with missing package
Install the missing package with tlmgr:
tlmgr install <package-name>
Common packages needed for the default template:
tlmgr install enumitem hyperref fontawesome5 geometry babel-english preprint
Phase 3 tools output text instead of calling write_latex
Rebuild and restart:
npm run build
Then restart Claude Code or Claude Desktop. The tool descriptions include explicit instructions that tell Claude to execute each step as a tool call. These instructions are only loaded at server startup.
PDF not saved to the download folder
Check that PDF_DOWNLOAD_DIR is set in your config and that the folder exists. Create it if needed:
mkdir -p ~/Desktop/OverLeaf_Resumes
Browser session lost after restart
The session is stored in ~/.overleaf-mcp/browser-data/. If it is missing or corrupted, call overleaf_login to create a fresh session.
Project Structure
overleaf-mcp/
├── src/
│ ├── index.ts MCP server entry point
│ ├── tools/
│ │ ├── latex.ts Local LaTeX tools (read, write, compile, open)
│ │ ├── overleaf.ts Overleaf automation tools
│ │ └── resume.ts Resume intelligence tools
│ └── overleaf/
│ ├── browser.ts Playwright persistent context
│ ├── auth.ts Login flow with CAPTCHA detection
│ └── editor.ts File read/write/edit/push/compile/download
├── templates/
│ └── software-engineer.tex Starter ATS-friendly resume template
├── dist/ Compiled output (generated by npm run build)
├── .env.example Environment variable reference
└── README.md
Local Development
git clone https://github.com/Sahith59/OverLeaf_MCP
cd overleaf-mcp
npm install
cp .env.example .env
# Edit .env with your credentials
npm run build
To watch for changes during development:
npm run dev
Register locally with Claude Code:
claude mcp add --scope user overleaf-mcp node /absolute/path/to/overleaf-mcp/dist/index.js
Contributing
Bug reports and pull requests are welcome. Please open an issue before starting work on a significant change so we can discuss the approach first.
License
MIT