litewrite-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@litewrite-mcp-server pull my thesis project and show what's changed"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
litewrite-mcp-server
An MCP server that bridges local AI agents to the HKUDS Litewrite platform (a self-hosted, Overleaf-like collaborative LaTeX/Markdown writing platform). It lets agents discover projects, read, upload, and update files, and work against a local mirror working copy with git-style pull / push / status — conceptually mirroring how the Overleaf MCP servers bridge MCP to Overleaf.
Note: Litewrite stores files as objects (S3/MinIO) behind an internal HTTP API and has no native Git integration, so this server implements the "local directory + sync" model over that internal API instead of
git clone/git push.
Architecture
Local AI agent (Claude, etc.)
│ MCP (stdio)
▼
┌─────────────────────────┐ POST /api/internal/projects/* ┌──────────────────┐
│ litewrite-mcp-server │ ──► X-Internal-Secret header ─────────► │ Litewrite │
│ (TypeScript / MCP SDK) │ ◄── JSON {success,data} │ (self-hosted) │
└──────────┬──────────────┘ └──────────────────┘
│ local mirror working copy (~/.litewrite-mcp/<projectId>)
│ + .litewrite-manifest.json (content hashes)
▼
~/.litewrite-mcp/<projectId>/{main.tex, chapters/, figures/, ...}Related MCP server: Typleaf MCP Server
Requirements
Node.js >= 18
A running, reachable self-hosted HKUDS Litewrite server, with
INTERNAL_API_SECRETset.
Install & Build
cd litewrite-mcp
npm install
npm run build # emits dist/Configuration (environment variables)
Variable | Required | Default | Description |
| yes | — | Must equal the Litewrite server's |
| no |
| Base URL of the Litewrite server. |
| no |
| Root dir for the per-project local mirror working copies. |
| no |
| Default owner used when a call omits |
Run
Once built, the server runs over stdio:
LITEWRITE_INTERNAL_SECRET=... node dist/index.jsRegister with a local agent
Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"litewrite": {
"command": "node",
"args": ["/absolute/path/to/litewrite-mcp/dist/index.js"],
"env": {
"LITEWRITE_INTERNAL_SECRET": "your-internal-secret",
"LITEWRITE_BASE_URL": "http://localhost:3000"
}
}
}
}Tools
Remote project & file operations (direct API)
Tool | Endpoint | Description |
|
| List projects for an owner; discover |
|
| List files/dirs in a project (recursive option). |
|
| Read a file's content from the server. |
|
| Replace an existing file's full content. |
|
| Create a new text file or directory. |
|
| Upload text or binary (base64) file, create/overwrite. |
|
| Delete a file/directory (irreversible). |
|
| Rename or move a file/folder. |
Local working copy + sync (git-style)
Tool | Network? | Description |
| yes | Mirror a project down into |
| yes | Upload local changes up; delete remotely-removed-local files. |
| yes | Diff local mirror vs server ( |
| no | List files in the local mirror. |
| no | Read a file from the local mirror. |
| no | Write/overwrite a file in the local mirror. |
Typical workflow
1. litewrite_list_projects -> get projectId
2. litewrite_pull {projectId} -> mirror files locally
3. litewrite_local_list {projectId} -> see local files
4. litewrite_local_write ... -> edit locally (e.g. revise main.tex)
5. litewrite_status {projectId} -> review what changed
6. litewrite_push {projectId} -> upload changes to LitewriteOr skip the local copy entirely and use litewrite_read_file / litewrite_write_file /
litewrite_upload_file directly.
Security notes
The MCP server holds the Litewrite
INTERNAL_API_SECRET. It grants read/write to every project the secret can reach, so keep it out of source control and restrict which agent can start this server.All local file paths are validated against directory-traversal (
..is rejected).The local working copies contain plaintext document content; guard the
LITEWRITE_LOCAL_DIR.
Limitations
Binary files are uploaded via base64 (
upload), but thereadendpoint returns text, sopullmay skip binary assets it cannot round-trip. Upload such files directly.Endpoint request/response shapes follow the Litewrite internal API; field names may change on upgrades. Adjust
src/api-client.tsaccordingly.
License
MIT
Available Tools
14 toolslitewrite_create_fileCreate a New FileBIdempotent
Create a new text file (or directory) in a Litewrite project (POST /api/internal/files/create).
Args:
projectId (string, required): The project id.
name (string, required): Name of the new file or folder, e.g. "notes.md".
type (string, required): "file" or "directory".
parentPath (string, optional): Parent directory relative to project root, e.g. "chapters".
content (string, optional): Initial text content for a file.
Returns a confirmation.
Inputs: name (required), type (required), projectId (required), content, +1 more.
litewrite_delete_fileDelete a FileADestructive
Delete a file (or directory) from a Litewrite project (POST /api/internal/files/delete). This is irreversible.
Inputs: filePath (required), projectId (required).
litewrite_list_filesList Files in a ProjectARead-onlyIdempotent
List the files and directories in a Litewrite project (POST /api/internal/files/list).
Args:
projectId (string, required): The project id (from litewrite_list_projects).
directory (string, optional): Subdirectory to list from the project root, e.g. "chapters".
recursive (boolean, optional): When true, list all nested files; default true.
Returns an array of {path, type: 'file'|'directory', size?}.
Inputs: projectId (required), directory, recursive.
litewrite_list_projectsList Litewrite ProjectsARead-onlyIdempotent
List projects available in the Litewrite platform for a given owner (POST /api/internal/projects/list).
Use this to discover a projectId before pulling or reading files.
Args:
ownerId (string, optional): defaults to the LITEWRITE_OWNER_ID env var, or "default".
search (string, optional): name filter.
limit (number, optional, 1-200, default 50): max results.
Returns an array of projects with fields {id, name, description?, mainFile?, compiler?, updatedAt?, createdAt?}.
Inputs: limit, search, ownerId.
litewrite_local_listList Local Working CopyARead-onlyIdempotent
List the files in the local mirror of a project (no network call).
This is the local working copy at ~/.litewrite-mcp/ used by litewrite_pull/push/status.
Args:
projectId (string, required): The project id.
Returns relative file paths present on disk.
Inputs: projectId (required).
litewrite_local_readRead Local Working Copy FileARead-onlyIdempotent
Read a file from the local mirror of a project (no network call).
Unlike litewrite_read_file, this reads the on-disk local copy at ~/.litewrite-mcp/.
Args:
projectId (string, required): The project id.
filePath (string, required): Relative path in the local copy.
Returns the raw bytes (framed as text) of the local file.
Inputs: filePath (required), projectId (required).
litewrite_local_writeWrite Local Working Copy FileADestructiveIdempotent
Write or overwrite a file in the local mirror of a project (no network call).
Changes are NOT uploaded to Litewrite until you run litewrite_push.
Args:
projectId (string, required): The project id.
filePath (string, required): Relative path in the local copy.
content (string, required): The full text content to write.
Text files edited/created here will be uploaded by litewrite_push.
Inputs: content (required), filePath (required), projectId (required).
litewrite_pullPull Project to Local MirrorAIdempotent
Mirror a Litewrite project down into a local directory (git-clone/pull style).
Downloads all text files from the server into the local working copy at ~/.litewrite-mcp/ (or LITEWRITE_LOCAL_DIR), removes local files that no longer exist on the server, and records a content manifest so a later push can detect changes.
Args:
projectId (string, required): The project id.
Returns what was downloaded and removed.
Inputs: projectId (required).
litewrite_pushPush Local Changes to LitewriteADestructiveIdempotent
Upload local working-copy changes back to Litewrite (git-push style).
Compares the local mirror (~/.litewrite-mcp/) against the last manifest: new/changed text files are uploaded, removed local files are deleted on the server, and the manifest is refreshed.
Use litewrite_status first to see what will change.
Args:
projectId (string, required): The project id.
Returns what was uploaded and deleted.
Inputs: projectId (required).
litewrite_read_fileRead a File from LitewriteARead-onlyIdempotent
Read the content of a file directly from the Litewrite server (POST /api/internal/files/read).
Prefers the server copy over the local mirror; use litewrite_local_read to read the local working copy instead.
Args:
projectId (string, required): The project id.
filePath (string, required): Path relative to the project root, e.g. "main.tex" or "chapters/intro.tex".
startLine / endLine (number, optional): Read only a line range.
Returns the file content as UTF-8 text.
Inputs: filePath (required), projectId (required), endLine, startLine.
litewrite_rename_fileRename / Move a FileADestructiveIdempotent
Rename or move a file/folder in a Litewrite project (POST /api/internal/files/rename).
Args:
projectId (string, required): The project id.
sourcePath (string, required): Current relative path.
newName (string, optional): New name (keeps the same parent).
targetPath (string, optional): Full target relative path to move it.
Provide at least one of newName or targetPath.
Inputs: projectId (required), sourcePath (required), newName, targetPath.
litewrite_statusShow Project Sync StatusARead-onlyIdempotent
Compare the local mirror of a project with Litewrite without changing anything (git-status style).
Reports which local files are added/modified/removed versus the last pull/push, and which files exist only on the remote. Use it before deciding whether to push local changes or pull remote ones.
Args:
projectId (string, required): The project id.
Returns a list of changes with their kind (added/modified/removed/remote_new).
Inputs: projectId (required).
litewrite_upload_fileUpload a File (Text or Binary)ADestructive
Upload a file to Litewrite, creating or overwriting it (POST /api/internal/files/upload).
Use for binary assets (images, PDFs) where edit/create are unsuitable, or as an alternative to create.
Args (provide exactly one source):
projectId (string, required): The project id.
filePath (string, required): Relative target path, e.g. "figures/logo.png".
content (string, optional): The text content to upload.
contentBase64 (string, optional): The raw file data base64-encoded.
overwrite (boolean, optional): Allow overwriting an existing file; default false.
Returns a confirmation.
Inputs: filePath (required), projectId (required), content, overwrite, +1 more.
litewrite_write_fileWrite / Update a File on LitewriteADestructiveIdempotent
Replace the full content of an existing file on the Litewrite server (POST /api/internal/files/edit).
For creating a brand-new file use litewrite_create_file; for binary files use litewrite_upload_file.
Args:
projectId (string, required): The project id.
filePath (string, required): Path relative to the project root.
content (string, required): The new full text content.
Returns a confirmation.
Inputs: content (required), filePath (required), projectId (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Most tools are clearly distinct, especially server vs local operations with explicit cross-references in descriptions. However, create_file, write_file, and upload_file have some overlap when creating or updating text files, though descriptions clarify intended use.
All tool names use the litewrite_ prefix followed by a snake_case verb_noun pattern, with local operations using litewrite_local_*. This is highly consistent and predictable.
14 tools provide a well-scoped set covering project listing, server file CRUD, and local mirror sync, with no excessive or trivial tools. Each tool earns its place.
Covers file lifecycle (create, read, update, delete, rename, upload) and local mirror workflow (pull, push, status, local list/read/write). Project listing suffices for discovery; no obvious gaps.
Related MCP Connectors
Edit your Overleaf LaTeX projects from Claude and ChatGPT; every change is a real Git commit.
Git-backed platform for skills, tools, and context for AI agents
Project memory, documentation and controlled secret access for AI coding agents.
Persistent AI LaTeX workspace: edit and compile multi-file projects, export publication-ready PDFs.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to read, write, and compile LaTeX projects locally, view PDF pages as images, and manage project files, with live updates reflected in a web-based editor.-
- AlicenseAqualityBmaintenanceEnables AI assistants to manage Typst and LaTeX projects on self-hosted Typleaf instances, including reading and editing documents, compiling to PDF, analyzing structure and page layout, checking citations, and reviewing git history.229MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to read, edit, upload, compile, and manage projects in a self-hosted Overleaf Community Edition via MCP, while also providing a git remote for cloning and pushing changes.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables a writer and their AI tools to edit, compile, and manage self-hosted LaTeX projects through authenticated MCP tools, with revision-safe edits, file history, and isolated TeX compilation.MIT