overleaf-mcp-rt
Health Uyari
- License — License: AGPL-3.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- spawnSync — Synchronous process spawning in scripts/build.mjs
- network request — Outbound network request in scripts/latency-probe.mjs
- network request — Outbound network request in src/cli.ts
- process.env — Environment variable access in src/config.ts
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
MCP server for self-hosted Overleaf Community Edition — real-time edits via Overleaf's native OT pipeline. Alternative to git-bridge for AI coding agents (Claude Code, Cursor, …).
Overleaf MCP
A real-time Model Context Protocol server for self-hosted Overleaf — no git-bridge, no Server Pro, no fork required.
Overleaf MCP lets AI coding agents (Claude Code, Claude Desktop, Codex, Cursor, Continue, and any other MCP-compliant client) read, write, and compile LaTeX projects in any personal or self-hosted Overleaf Community Edition instance. Instead of relying on a git-bridge integration — a paid Server Pro feature that personal Overleaf installations don't have — it speaks Overleaf's native operational-transform (OT) protocol over Socket.IO, the same approach pioneered by Overleaf-Workshop. Edits flow live into the editor as collaborator operations, with no "file changed externally" toast and no extra infrastructure.
Distributed on npm as overleaf-mcp-rt — the rt suffix marks this as the real-time / OT-backed flavor, distinct from git-bridge–style Overleaf MCP servers.
npx overleaf-mcp-rt@latest --help
Table of contents
- Why "real-time"? Native OT vs git-bridge
- Install
- Quick start
- MCP client config
- Sanity-check:
diagnose - Tools
- v1.2 release notes
- v1.1 release notes
- v1.0 release notes
- Roadmap
- FAQ
- Source of truth
- License
- Acknowledgements
Why "real-time"? Native OT vs git-bridge
| Overleaf MCP (native OT) | git-bridge–style MCP servers | |
|---|---|---|
| Works on personal / Community Edition Overleaf | ✅ | ❌ (Server Pro only) |
| Latency to editor | live (per patch) | minutes (git push + bridge sync) |
| Server requirements | stock Overleaf CE 3.x – 6.x | Overleaf Server Pro + git-bridge license |
| "File changed externally" toast | never — edits arrive as co-author OT ops | yes — every git sync triggers it |
| Auth model | session cookie | git over HTTPS / SSH |
If you run your own Overleaf Community Edition — in Docker, on a homelab, anywhere — and you want Claude Code or another AI agent to edit LaTeX in it with edits showing up live in the browser, this is the project for you.
Install
# A. Zero-install via npx (recommended for MCP clients)
npx overleaf-mcp-rt@latest --help
# B. Global install for shell use
npm install -g overleaf-mcp-rt
overleaf-mcp-rt --help
Requires Node.js ≥ 20.
Quick start
# 1. Get a session cookie (paste from devtools or use --email/--password)
npx overleaf-mcp-rt login --url https://overleaf.example.com
# 2. Smoke test connectivity, auth, and OT handshake
npx overleaf-mcp-rt diagnose
# 3. List your projects
npx overleaf-mcp-rt ls
MCP client config
Works in Claude Code, Claude Desktop, Cursor, Codex (via MCP), Continue, and any MCP-compliant client.
{
"mcpServers": {
"overleaf": {
"command": "npx",
"args": ["-y", "overleaf-mcp-rt@latest"],
"env": {
"OVERLEAF_URL": "https://overleaf.example.com",
"OVERLEAF_SESSION_COOKIE": "overleaf_session2=s%3A..."
}
}
}
}
If your Overleaf is fronted by an authentication proxy (Cloudflare Access, Authelia, oauth2-proxy, HTTP Basic Auth, etc.), pass the proxy headers via the optional OVERLEAF_EXTRA_HEADERS env var as a JSON object — its keys/values are merged into every REST request and the Socket.IO upgrade. Run diagnose (next section) to verify both layers.
Sanity-check: diagnose
After wiring credentials, run from a shell:
overleaf-mcp-rt diagnose
Output is a step-by-step report:
✓ config — URL https://overleaf.example.com
✓ REST handshake — cookie valid, CSRF scraped
✓ project listing — 3 project(s) accessible
✓ OT handshake — publicId P.abc...
A ✗ on any step prints the underlying error code (OVERLEAF_AUTH_FAILED, PROXY_AUTH_FAILED, PROJECT_ACCESS_DENIED) so you know which layer to fix.
Tools
17 MCP tools, all prefixed overleaf_* so they remain unambiguous in hosts that don't auto-namespace by server name. Every tool's error responses use the structured error envelope.
Discovery & read
| Tool | Purpose |
|---|---|
overleaf_list_projects |
List accessible projects. |
overleaf_get_project_tree(projectId) |
Folder + file tree (live, OT-backed). |
overleaf_read_doc(projectId, path) |
Full text doc content. Live: reflects collaborators' keystrokes up to the instant of the call. |
overleaf_check_changes(projectId) |
What collaborators changed since the agent's last tool call. The same report rides along on every other tool result (see Working alongside humans), so this is only for polling. |
overleaf_read_doc_range(projectId, path, startLine?, endLine?, startOffset?, length?) |
Substring of a doc by 1-indexed inclusive line range or by char offset/length. Returns totalLines / totalChars. Use this to verify a small region after an edit instead of re-fetching the whole doc. |
overleaf_read_file(projectId, path, as?) |
Binary file. Default as=auto: native MCP image content for image MIMEs, text content for text MIMEs, resource for PDFs, base64 envelope otherwise. Pass as=base64 to force the {contentBase64, mimeType} envelope for any type — useful for programmatic copy via overleaf_upload_file. |
Edit
| Tool | Purpose |
|---|---|
overleaf_edit_doc(projectId, path, edits[], dryRun?) |
The recommended editing surface. Exact string replacement, the way coding agents edit files: each edit is {old_string, new_string, replace_all?}. Returns a write summary plus a unified diff of what changed. |
overleaf_write_doc(projectId, path, content, overwrite?) |
Replace a whole doc. Only the differing characters are sent. Refused if the agent hasn't read the doc this session (DOC_NOT_READ) or a collaborator edited it since (DOC_CHANGED_EXTERNALLY), unless overwrite: true. |
overleaf_edit_doc
{ "projectId": "…", "path": "main.tex", "edits": [
{ "old_string": "Results are good.", "new_string": "Results are excellent." },
{ "old_string": "\\cite{old}", "new_string": "\\cite{new}", "replace_all": true }
] }
old_stringmust identify exactly one place in the doc, or the call fails withEDIT_AMBIGUOUSand the matching line numbers — add surrounding text, or setreplace_all.- Edits apply in order, each to the result of the previous, and atomically: if any edit fails, nothing is sent.
- Text is addressed by content, never by offset, and matched against the live doc at the instant the op is emitted. An agent edit therefore composes with whatever a human is typing elsewhere in the file. If the human changed the very text being targeted, the call fails with
EDIT_NO_MATCH, reports the closest region, and the attached<external-changes>block shows their edit. - If
old_stringisn't found verbatim, a match that differs only in trailing whitespace, indentation, or line wrapping is accepted when unambiguous (reported innotes). The replaced span is always the doc's real text. - The op sent to Overleaf is the minimal character diff, so collaborators' cursors and selections outside the changed characters are undisturbed.
- To insert, use an anchor as
old_stringand repeat it innew_string. To delete, passnew_string: "".dryRun: truereturns the diff and resolved OT ops without sending.
Legacy v1.1 edits carrying a mode field (replace, insert_before, insert_after, replace_lines, unified_diff, raw_ops) are still accepted. replace_lines and raw_ops address the doc by position, so they are refused with DOC_CHANGED_EXTERNALLY if a collaborator edited the doc since the agent last saw it.
Working alongside humans
The server keeps a live, server-confirmed copy of every doc the agent has opened by applying each collaborator's OT op as it arrives, so the agent always edits the current version. On top of that it remembers what the agent has been shown. Whenever those differ, the next tool result for that project (success or error) gets an extra text block:
<external-changes>
Collaborators changed this project since your last tool call. …
main.tex — edited by Ada Lovelace, 12s ago (v41 → v45)
@@ -1,3 +1,3 @@
\section{Introduction}
-We study the problem of widgets.
+We study the problem of gadgets.
File tree:
- created doc appendix.tex by Ada Lovelace
</external-changes>
This is the Overleaf analogue of a coding agent noticing a file changed on disk: the agent stays current without re-reading, and each change is reported once. Only docs the agent has read are reported; the agent's own edits never are.
Project tree CRUD
| Tool | Purpose |
|---|---|
overleaf_create_doc(projectId, parentPath, name, content?) |
Create a text doc; optional initial content is OT-written after creation. Use parentPath: "" for the project root. |
overleaf_create_folder(projectId, parentPath, name) |
Create a folder. |
overleaf_upload_file(projectId, parentPath, name, contentBase64, mimeType?) |
Upload a binary; mimeType inferred from extension when omitted. The server may auto-promote text MIME types to docs. |
overleaf_rename(projectId, path, newName) |
Rename a doc/file/folder. |
overleaf_move(projectId, path, newParentPath) |
Move a doc/file/folder. Use newParentPath: "" for the project root. |
overleaf_delete_entity(projectId, path) |
Delete a doc/file/folder. |
Compile
| Tool | Purpose |
|---|---|
overleaf_compile(projectId, draft?, stopOnFirstError?) |
Trigger a LaTeX compile, return output URLs. |
overleaf_read_compile_log(projectId) |
Compile and return output.log text. |
overleaf_download_pdf(projectId) |
Compile and return the PDF as an MCP resource (application/pdf, base64 blob). |
Error envelope
Every tool error serializes as JSON inside an MCP text content block (with isError: true):
{
"code": "OT_DELETE_MISMATCH",
"message": "Delete op #0 at position 0 expected \"FOO\" but doc has \"BAR\"",
"context": { "p": 0, "expected": "FOO", "actual": "BAR", "opIndex": 0 },
"retryable": false,
"hint": "The d-string did not match the doc at position p. Re-read the doc to get the current text, then recompute offsets."
}
| Code | Meaning |
|---|---|
OVERLEAF_GENERIC |
Validation or other non-typed errors (ambiguous anchor, out-of-bounds line range, mixed-mode edit_doc, etc.). |
OVERLEAF_AUTH_FAILED |
Session cookie invalid/expired. Re-run overleaf-mcp-rt login. |
PROXY_AUTH_FAILED |
A reverse proxy blocked the request — set OVERLEAF_EXTRA_HEADERS. |
PROJECT_ACCESS_DENIED |
The session can't reach the requested project. |
NOT_FOUND |
No such doc/file/folder at the given path. |
NETWORK_ERROR |
Transport-level failure (retryable: true). |
OT_DELETE_MISMATCH |
A d-string in overleaf_edit_doc's raw_ops mode didn't match the doc at p. Pre-validated client-side, so you find out before the round-trip. |
EDIT_NO_MATCH |
old_string (or a unified_diff's context) isn't in the live doc. context.closest holds the most similar region. |
EDIT_AMBIGUOUS |
old_string matches more than one place; context.lines lists them. |
DOC_CHANGED_EXTERNALLY |
A collaborator edited the doc after the agent last saw it, and the requested operation (overleaf_write_doc, replace_lines, raw_ops) depends on that stale view. Nothing was written. |
DOC_NOT_READ |
overleaf_write_doc on a non-empty doc the agent never read. |
INVALID_CONFIG |
Missing or malformed OVERLEAF_URL / cookie / extra headers. |
retryable: true is set for transient failures (NETWORK_ERROR); agents can use it to drive a retry loop. hint provides a one-line next step for the most common failures.
v1.2 release notes
v1.2 makes the server safe to use while a human is editing the same doc in the browser, and reworks editing around how coding agents edit files.
- Fixed: agent edits knocking browser sessions "out of sync". The OT engine ignored collaborators'
otUpdateAppliedbroadcasts, so once a human typed, the agent's next op was computed against stale text and submitted at a stale version. document-updater rejected it (Delete component … does not match), and Overleaf's real-time service answers a rejected op by sendingotUpdateErrorto — and disconnecting — every client in the doc, discarding the human's unsaved keystrokes. The engine now applies every remote op to its snapshot, transforms its own in-flight op past ops that beat it to the server (a port of the ShareJStexttype document-updater itself uses, so both sides compute the same result), and edits are evaluated against the live text at the instant of emit. - Fixed: write confirmation. The
applyOtUpdateack only means the op was queued. The engine now waits for the real confirmation (otUpdateApplied {doc, v}) and surfacesotUpdateErrorrejections, which were previously invisible. - Fixed: parallel reads. real-time fails a
joinDocthat another join overtakes; joins are now serialized, and updates that arrive before a join's response are replayed onto the snapshot. overleaf_edit_docis nowold_string/new_string/replace_allwith uniqueness checks, sequential atomic multi-edit, whitespace-tolerant fallback matching, minimal-diff ops, and a unified diff in the result. v1.1mode-based edits still work.unified_diffmode no longer sends "delete everything, insert everything".- External-change awareness — every tool result carries an
<external-changes>block (diff + author + file-tree events) when collaborators changed something the agent has seen. New tool:overleaf_check_changes. overleaf_write_docguards — refuses to clobber unread or externally-changed docs (DOC_NOT_READ,DOC_CHANGED_EXTERNALLY);overwrite: trueopts out.- The server starts even when the cookie has expired. Auth is checked on the first tool call and reported as
OVERLEAF_AUTH_FAILEDwith a hint, instead of the process exiting before the MCP handshake (which hosts show as an unexplained "connection closed"). Runningoverleaf-mcp-rt loginfixes a live session without restarting it. OT_VERSION_DRIFTis no longer emitted: version tracking makes the retry loop it reported on unnecessary.- Overleaf CE 6.x is supported. The protocol work in this release was done against the 6.0.0
real-time/document-updatersources and verified live on a 6.0.0 instance: an agent making 60 rapid edits while a human typed in three places in the browser ended byte-identical on both sides, with no out-of-sync modal and no OT errors in the server logs. 6.x is now the primary target; 5.x was the original one, and the wire protocol used here is unchanged across 3.x – 6.x. (An automated multi-version test matrix is planned separately.)
v1.1 release notes
v1.1 adds the agent-ergonomics surface that the v1.0 raw OT-ops surface made painful to use, and renames every tool with an overleaf_* prefix:
- All tools renamed
overleaf_*—read_doc→overleaf_read_doc,compile→overleaf_compile, etc. The prefix keeps tool names unambiguous in MCP hosts that don't auto-namespace by server (Cursor, Continue, custom stdio). Claude Code'smcp__<server>__<tool>namespacing still applies on top. overleaf_edit_doctool — anchor-basedreplace(withunique/first/all/Nth occurrence semantics),insert_before/insert_after, line-rangereplace_lines,unified_diff, andraw_opsas an escape hatch. All edits in one call resolve against the same baseline and apply atomically;dryRun: truereturns the resolved OT ops without emitting them. This is the recommended editing surface —apply_patch(the v1.0 raw-ops tool) was removed becauseoverleaf_edit_doc'sraw_opsmode is a strict superset.overleaf_read_doc_range— fetch a substring of a doc by line range or offset/length, withtotalLines/totalCharsreturned alongside. Saves an agent the round-trip cost of fetching a 50 KB doc just to verify a 200-byte edit.overleaf_read_file as=base64— opt into a{contentBase64, mimeType}envelope even for image MIMEs, so an agent can copy a binary asset between two project paths viaoverleaf_upload_filewithout losing access to the bytes.- Edit summaries —
overleaf_write_docandoverleaf_edit_docboth return{versionBefore, versionAfter, charsBefore, charsAfter, charsDelta, opsApplied}. Agents can sanity-check edits without re-reading the doc. - Structured error envelope — tool errors serialize as
{code, message, context, retryable, hint?}JSON instead of a flat string. New error codes:OT_DELETE_MISMATCHandOT_VERSION_DRIFT. - Wire-format change for errors: error responses are now JSON inside
textcontent; v1.0 emitted${code}: ${message}plain text. v1.0 clients that regex-parsed error strings will need to switch to JSON parsing. - Defensive validation —
overleaf_edit_docpre-validates ops against the local baseline before emit, so a wrong offset surfaces immediately instead of via an opaque server reject (or, worse, silent no-op). - Removed:
apply_patch— replaced byoverleaf_edit_docwithmode: 'raw_ops'. Migration: wrap your oldopsarray in{edits: [{mode: 'raw_ops', ops: [...]}]}.
v1.0 release notes
This is the first stable release on npm. It bundles everything from the prior internal development phases (read-only, OT writes, tree mutations, polish) into a single shipping package:
- Live OT reads & writes —
read_doc,write_doc, and a raw-OTapply_patch(later collapsed intooverleaf_edit_docin v1.1) flow through Overleaf's native operational-transform pipeline. Other connected browser sessions see edits as a co-author typing, not as a "file changed externally" toast. - Full tree CRUD over REST —
create_doc,create_folder,upload_file,rename,move,delete_entity. - Compile pipeline —
compile,read_compile_log,download_pdf(returned as a binary MCP resource). diagnoseCLI subcommand — stepped report (config → REST → reverse-proxy → projects → OT) so failed setups surface the exact failing layer with a typed error code.- Reverse-proxy auth pass-through —
OVERLEAF_EXTRA_HEADERSis merged into both the REST client and the Socket.IO handshake. - Resilience — per-doc write serialization (no baseline races), reconnect with jitter, OT-engine eviction signaling, WHATWG-URL normalization (subpath-safe),
pdfDownloadDomainhonored for overleaf.com REST flows. - Compatibility — stock Overleaf CE 3.x – 6.x. No fork of
sharelatex/sharelatexand no patched server image required, so you can keep upgrading Overleaf cleanly. - License — AGPL-3.0-or-later (required because the OT/auth client is ported from Overleaf-Workshop).
Pre-1.0 development happened under internal v0.1–v0.4 milestones; those are now collapsed into v1.0 and per-phase notes are kept only in docs/superpowers/plans/ for historical context.
Roadmap
v1.x — full CLI parity + agent-facing skills
Today every tool listed above is reachable via MCP only; the bundled CLI just covers login, ls, and diagnose. Some agents (Codex CLI, Aider, terminal-only setups, anything that would rather shell out than pay tokens on an MCP envelope) are happier driving a normal command-line tool. Planned for v1.x:
- CLI parity for every MCP tool — one subcommand per tool, JSON output by default so agents can parse it,
--humanfor tty-friendly tables. Sketch:overleaf-mcp-rt projects ls/tree <projectId>overleaf-mcp-rt doc read <projectId> <path>/write <projectId> <path>(stdin) /edit <projectId> <path> <edits.json>/patch <projectId> <path> <ops.json>overleaf-mcp-rt file read <projectId> <path>/upload <projectId> <parentPath> <name> <file>overleaf-mcp-rt fs mkdir | mv | rm | renameoverleaf-mcp-rt compile <projectId> [--draft] [--stop-on-first-error]/log/pdf -o out.pdf
- Agent skills for the CLI — a
skills/directory shipped with the package, in Claude Code skills format (also usable by other agents that ingest skill-style instructions). Each skill teaches the canonical Overleaf workflow on top of the CLI: edit-then-compile-then-read-log, upload-figure-and-cite, refactor-bibliography, recover-from-compile-error. - Same env, two surfaces —
OVERLEAF_URL/OVERLEAF_SESSION_COOKIE/OVERLEAF_EXTRA_HEADERSapply to both modes. The MCP server stays the default invocation for back-compat; the CLI is additive.
Beyond v1.x
- Cursor rules and Continue tool definitions in a
recipes/directory. overleaf-mcp-rt watch— mirror a local directory into a project as you edit it, for non-MCP workflows.- Optional in-process snapshot history for project-level rollback.
Track or contribute via GitHub issues.
FAQ
Does this require Overleaf Server Pro?
No. It targets stock Overleaf Community Edition (3.x – 6.x). The whole point of this project is to give personal/self-hosted CE users the same agent-driven editing experience that Server Pro git-bridge users get.
Does this require git-bridge?
No. Edits are sent as live OT operations over Socket.IO — the same protocol Overleaf's web editor uses internally.
Will edits show a "file changed externally" toast in the browser?
No. The MCP server connects as a regular collaborator, so other browser sessions see edits as a co-author typing.
Does it work with overleaf.com (the hosted SaaS)?
REST-backed tools (list_projects, compile, download_pdf) work against overleaf.com when you supply a session cookie. OT-backed reads/writes are designed and tested against Community Edition; the SaaS may diverge in protocol details and is not a targeted platform.
Does it work behind a reverse proxy?
Yes. Pass any required headers (Cloudflare Access service token, Basic Auth, oauth2-proxy / Authelia forwarded-user, etc.) via OVERLEAF_EXTRA_HEADERS as a JSON object — they're merged into both REST and Socket.IO. Run overleaf-mcp-rt diagnose after configuring; a missing header surfaces as OVERLEAF_AUTH_FAILED on the REST step or OT connectionRejected on the OT step.
How does this compare to Overleaf-Workshop?
Overleaf-Workshop is the VS Code extension that pioneered speaking Overleaf's native OT/Socket.IO protocol from outside the browser. This project ports significant portions of its auth and OT client into a Model Context Protocol server, so any MCP-compatible AI agent — not just a VS Code user — can edit Overleaf projects in real time. Both are AGPL-3.0.
Why is the npm package overleaf-mcp-rt if the project is called "Overleaf MCP"?
The rt suffix marks this as the real-time / OT-backed flavor, since other "overleaf-mcp"–style packages may use git-bridge or zip-snapshot approaches. The shorter "Overleaf MCP" is the human-readable project name.
Source of truth
Design docs and per-phase plans live in docs/superpowers/. When in doubt, the design spec there is canonical.
License
AGPL-3.0-or-later. Required because this project ports significant portions of code from Overleaf-Workshop (also AGPL-3.0).
Acknowledgements
This project ports significant portions of the auth and OT code from Overleaf-Workshop by iamhyc and contributors. Used under AGPL-3.0.
Built on the Model Context Protocol by Anthropic.
Keywords: Overleaf · ShareLaTeX · MCP · Model Context Protocol · Claude Code · Claude Desktop · Codex · Cursor · Continue · LaTeX · self-hosted Overleaf · Overleaf Community Edition · operational transform · Socket.IO · git-bridge alternative · AI LaTeX agent · real-time collaborative editing
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi