# Overleaf

> Read and write Overleaf projects via the Overleaf git bridge (the universal mechanism, works on any machine for any user) with an optional read-only MCP companion. Use when the user wants to view, edit, add files (e.g. a rebuttal), or sync changes to an Overleaf paper. Handles first-run token setup, project cloning, the commit-and-push workflow, and the optional MCP install.

- Skill: `junhahyung/overleaf` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add junhahyung/overleaf`
- Raw SKILL.md: https://api.skillmd.com/api/skills/junhahyung/overleaf/raw
- Safety review: pending (external: skill-scanner PASS, skillspector WARNING)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: junhahyung (https://skillmd.com/u/junhahyung)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/junhahyung/overleaf

---


# Overleaf — Read & Write workflow

There are two channels for working with Overleaf, but only the first is
required:

1. **Overleaf git bridge** (read AND write) — every Overleaf project can be
   cloned as a git repo. Editing locally + `git push` syncs changes back
   to Overleaf. **This is the only path for writes, and it works on any
   machine with git + a personal Overleaf token.** Prefer this for
   everything.
2. **Overleaf MCP server** (read-only, optional) — a Node.js server that
   exposes structured browsing of registered projects. Tools:
   `mcp__overleaf__list_projects`, `list_files`, `read_file`,
   `get_sections`, `get_section_content`, `status_summary`. **If those
   tools aren't visible in this session, the MCP isn't installed here —
   skip it and use the git bridge.** Install instructions in the appendix.

## First-run setup (do this automatically, don't pre-ask the user)

Resolve the user's Overleaf git token (format `olp_…`) on every Overleaf
task in this order, stopping at the first hit. **Never echo the token to
chat output** — refer to it only via env var or file path.

```bash
TOKEN=""
[ -n "$OVERLEAF_GIT_TOKEN" ] && TOKEN="$OVERLEAF_GIT_TOKEN"
[ -z "$TOKEN" ] && [ -r "$HOME/.overleaf-token" ] && TOKEN=$(tr -d '\n' < "$HOME/.overleaf-token")
```

If `$TOKEN` is still empty after both checks, the user has no token
configured on this machine. Ask them once for it, with this message:

> I need an Overleaf personal git token to talk to your project.
> Get one from: Overleaf web → top-right account menu → **Account
> Settings** → **Git Integration** → **Create Token**. Paste it here
> (format `olp_…`) and I'll save it to `~/.overleaf-token` (mode 600).

Once they paste it, save it without further questions:

```bash
printf '%s\n' "<token>" > "$HOME/.overleaf-token" && chmod 600 "$HOME/.overleaf-token"
```

Do **not** ask the user where to store the token, which storage method to
use, etc. — `~/.overleaf-token` chmod 600 is the convention. If they have
a strong preference for env var or keychain, they'll bring it up; default
to the file.

The git URL pattern is always:
`https://git:<token>@git.overleaf.com/<24-char-projectId>`

The token ends up embedded in `.git/config` of each clone — that's how the
bridge works. Don't paste full remote URLs into chat output (use the
local clone path instead).

## Cloning a project

When the user gives you an Overleaf project URL like
`https://www.overleaf.com/project/<projectId>`:

1. **Extract the project ID** — the 24-char hex segment after `/project/`.
2. **Pick a clone path automatically:**
   - if the user invoked the skill from an empty cwd that's clearly named
     for this project (e.g. cwd contains "overleaf" or matches the paper),
     use that cwd,
   - else default to `~/projects/overleaf-<short-name>`,
   - else if they have explicit per-machine conventions in their personal
     setup, follow those (don't ask — just pick the most plausible).
3. **Clone:**
   ```bash
   target="<chosen-path>"
   if [ -d "$target" ] && [ -z "$(ls -A "$target" 2>/dev/null)" ]; then
     # target exists and is empty — clone via temp dir + rsync (git refuses
     # to clone into existing dirs, even empty ones, on some platforms)
     tmp=$(mktemp -d)
     git clone "https://git:${TOKEN}@git.overleaf.com/<projectId>" "$tmp"
     rsync -a "$tmp"/ "$target"/ && rm -rf "$tmp"
   else
     mkdir -p "$(dirname "$target")"
     git clone "https://git:${TOKEN}@git.overleaf.com/<projectId>" "$target"
   fi
   ```
   Auth errors usually mean the token is for a different account or the
   user lacks access to that specific project — ask the user.
4. **(MCP-only, optional)** If the MCP is installed *and* its
   `projects.json` is reachable, register the new project for convenience.
   See the appendix for the MCP file layout — the `projects.json` path is
   wherever the user installed the server. Use Read + Edit (not Write) to
   preserve formatting:
   ```json
   "<alias>": {
     "name": "<Human-readable name>",
     "projectId": "<projectId>",
     "gitToken": "<same-token-as-default>"
   }
   ```
   MCP access to the new alias only activates after a Claude Code restart
   (or `/mcp` reconnect). The git clone path works immediately.

## Reading

- **MCP path (only if `mcp__overleaf__*` tools are available in this
  session):** quick section lookup on a registered project via
  `mcp__overleaf__get_sections` / `get_section_content` with the alias as
  `projectName`.
- **Default path (always works):** read directly from the clone with the
  standard `Read` tool. Run `git pull --rebase` first if the user might
  have edited in the Overleaf web UI in the meantime.

## Writing (the actual workflow)

Overleaf merges anything you push, but it does **not** rebase your local
branch — so always pull first.

1. `git -C <clone-path> pull --rebase`
2. Edit / add files locally with `Edit` / `Write`. Image/figure files go
   in the project's existing `figures/` (or wherever the project's
   convention places them — check the tree first).
3. `git -C <clone-path> add <files>` then
   `git -C <clone-path> commit -m "<message>"`.
4. `git -C <clone-path> push`.
5. Confirm the new commit hash to the user. The change appears in the
   Overleaf web editor on next refresh.

If the push is rejected because Overleaf has newer commits, `git pull
--rebase` again, resolve any conflicts, then push.

## Common task: adding a conference rebuttal

Most ECCV/CVPR/etc. main-paper templates do **not** include the rebuttal
LaTeX scaffolding. A widely-used source is
`https://github.com/paolo-favaro/rebuttal-template` (ECCV 2026 rebuttal
template — adapt to other years/conferences as appropriate, or use the
template the user prefers).

Standard procedure:

1. Check the project tree for any existing `rebuttal*` file. If one
   exists, ask whether to edit it instead.
2. Clone the template into a temp dir (shallow clone is fine):
   `git clone --depth 1 https://github.com/paolo-favaro/rebuttal-template "$(mktemp -d)/rebuttal-template"`.
3. Compare overlapping files (`eccvabbrv.sty`, `splncs04.bst`, `main.bib`)
   with `diff -q`. **Do not overwrite the project's `main.bib`** — it is
   the user's bibliography. Only copy in files that don't already exist
   or that genuinely differ in a way the user wants.
4. Typically only `rebuttal.tex` and `cvpr.sty` need to be added.
5. Inside `rebuttal.tex`: set `\paperID` (look for `TODO REBUTTAL`
   markers). The boilerplate body needs to be replaced with the actual
   response.
6. Commit + push as usual.

## Things to avoid

- Do not call `git push --force` against an Overleaf remote — it can
  destroy collaborator edits made through the web UI.
- Do not put the git token into shell history, log files, or any
  committed file. The remote URL has the token embedded; don't paste that
  URL into chat output. Refer to clones by their local path.
- Do not commit Overleaf-built PDFs (`*.pdf` artifacts of the user's own
  paper) unless they were already tracked. Overleaf rebuilds the PDF on
  its side; pushed PDFs aren't used by the web compiler.
- `~/.overleaf-token` and any MCP `projects.json` file live **outside**
  any git repo; do not move them into one without scrubbing the token
  first.

---

## Appendix: installing the optional MCP server

The MCP is a quality-of-life addition — *everything* still works without
it. Only set it up if the user explicitly wants structured project
browsing or if multiple papers are in play and an alias map helps.

A working MCP install consists of three pieces:

**1. The server source** — a Node.js script (`overleaf-mcp-server.js`).
Source repo: `<MCP_REPO_URL>` *(maintainer fills this in before
sharing)*. Conventional install location: `~/OverleafMCP/`.

```bash
git clone <MCP_REPO_URL> ~/OverleafMCP
cd ~/OverleafMCP && npm install   # if there's a package.json
```

**2. A `projects.json` registry** next to the server, listing each
project the user wants the MCP to expose:

```json
{
  "projects": {
    "default": {
      "name": "Default",
      "projectId": "<24-char-id>",
      "gitToken": "<olp_…>"
    },
    "<alias>": {
      "name": "<Human-readable name>",
      "projectId": "<24-char-id>",
      "gitToken": "<olp_…>"
    }
  }
}
```

`chmod 600` it — it contains tokens. The MCP **caches this file at
startup**, so newly added entries only show up after a Claude Code
restart (or `/mcp` reconnect).

**3. A Claude Code MCP entry** in the user's MCP config (typically
`~/.claude/.mcp.json`):

```json
{
  "mcpServers": {
    "overleaf": {
      "command": "node",
      "args": ["<absolute-path-to>/overleaf-mcp-server.js"]
    }
  }
}
```

Restart Claude Code. The `mcp__overleaf__*` tools should now be visible.

If any of those three pieces is missing, the MCP simply won't expose its
tools — Claude will fall through to the git-bridge path automatically.

