Typleaf MCP Server
🌿 Typleaf MCP Server
一个为 Typleaf Pro 上的 Typst 项目提供的 Model Context Protocol (MCP) 服务器——一个可自托管、支持 Typst 的 Overleaf 分支。
28 个工具,覆盖完整的 CRUD、文档结构分析、git 历史与差异、编译、PDF 下载、PDF 版式感知和引文验证。
Typleaf 同时编译 Typst 和 LaTeX,因此这个服务器处理两者。正确的解析器会根据文件扩展名自动选择——你无需指定。
You: "What kind of project is 6a6dfc57bbb3aac01ed9a71d?"
AI: [project_info] Typst, root main.typ, 36 .typ files, bibliography refs.yml
You: "Read sections/03-method.typ"
AI: [read_file] Here's the content: …
You: "Tighten the Background section"
AI: [update_section] ✓ Edited and pushed
You: "Compile it and tell me how many pages"
AI: [get_page_count] 61 pages (format=typst, source=pdf)
You: "Which page does each heading start on?"
AI: [section_page_map] p.1 = Introduction … p.8 == Parameters …这是
overleaf-mcp-plus(由 rangehow 编写)的一个 fork,重新面向自托管的 Typleaf。参见 与上游相比的变更。
🚀 设置
1. 安装
pip install "typleaf-mcp[compile]"或者不安装直接运行:
uvx --from "typleaf-mcp[compile]" typleaf-mcp2. 获取你的凭据
变量 | 用途 | 获取方式 |
| 所有功能 | 你的实例的 URL,例如 |
| 所有其他功能——读取、写入、编译、PDF | 开发工具 → Application → Cookies → 你的实例 → |
| 可选——仅提交历史 |
|
你不需要 git 令牌。 Typleaf 的 git bridge 是一个可选模块,许多部署并没有运行它——在这些情况下,没有令牌可设置。这个服务器仅凭会话 cookie 就能读写(参见 后端)。只有
list_history、get_diff和sync_project需要 git,而且这些工具会解释差距,而不是直接报错。
Cookie 名称: Overleaf 自带两个。Typleaf 所基于的 Community Edition 设置的是
overleaf.sid;托管服务设置的是overleaf_session2。猜错时错误信息看起来就像会话过期,因此该服务器会使用你的值同时发送两个名称,除非你通过TYPLEAF_SESSION_COOKIE指定其中一个。你的实例显示哪个,直接复制哪个。
TYPLEAF_BASE_URL故意不设默认值。 此服务器会将会话凭据和 git 令牌发送到你指向的任意主机。默认到www.overleaf.com——正如上游为单一服务主机所做的、正确的做法——会导致一个未经配置的安装把私有实例的凭据泄露给第三方。所以它直接报错。所有三个变量的OVERLEAF_*拼写均可作为回退,因此现有的overleaf-mcp配置只需修改 base URL。
会话 cookie 是 HttpOnly:你必须从 DevTools 的 Cookies 面板复制,而不是 JS 控制台。
Git 工具还需要在服务器上启用 git-bridge 模块。如果没有启用,即使每个项目都在 Web 界面可见,克隆也会 404——错误信息会这么说。
3. 注册服务器
{
"mcpServers": {
"typleaf": {
"command": "typleaf-mcp",
"env": {
"TYPLEAF_BASE_URL": "https://typleaf.example.com",
"TYPLEAF_SESSION": "s%3A...",
"TYPLEAF_GIT_TOKEN": "olp_..."
}
}
}
}Related MCP server: claudeleaf
🔌 后端
服务器会根据你的部署实际提供的能力选择后端:
web(仅凭 cookie) | git(启用 bridge) | |
选择条件 | 没有 | 已设置令牌 |
读取 / 写入文件 | ✅ | ✅ |
提交信息 | ❌ — 编辑变为普通项目更改 | ✅ |
| ❌ | ✅ |
status_summary 会报告当前使用的是哪一个。
Web 后端如何写入。 没有 HTTP 端点能直接设置文档内容——setDocument 真实存在,但站点的服务认证验证了,编辑器本机通过 WebSocket 使用 operational transform 写入。但 Cookie 自动认证的 POST /Project/<id>/upload 是 upserts:上传你已存在的名称会就地替换该实体,保留其 id,而文本文件会成为可编辑的 doc 而不是二进制附件。
问题是上传需要 folder_id,而没有任何 HTTP 端点能暴露文件夹 id——/entities 只提供路径,/metadata 只提供 doc id,创建已存在的文件夹会返回 400 file already exists。文件夹 id 只出现在实时服务的 joinProject 数据中,并且是通过 socket.io 0.9——一个几乎找不到维护者且没有能说 Python 客户端的协议。因此 realtime.py 实现读取树所需的四种帧类型类型,后续写入网民普通 HTTP 完成。这就绕过了实现 operational transform 这一步,而这才是与 Overleaf 编辑器交互真正困难的部分。
编辑现有文档一样要经过 operational transform,而不是上传。 编辑是以 操作 的形式发送的——{"p": 12, "d": "Original"}, {"p": 12, "i": "EDITED"}——与编辑器使用的同一个 WebSocket 发送,因此,协作打开该文件的你会看到它直接出现。已用第二个客户端验证:它实时收到该 op。在一个 2,430 字符的文件中修改一个词,传输 7 个字符,因此光标、选区、未修改文本的修订审阅归属都能保留。
上传仍被用于没有可编辑文档的情况——比如新文件和二进制资源。
有一个值得记录的小锦囊:为什么在日志中看很惊悚?本服务器的 socket.io 0.9 栈把它放进一个设置了 MASK 位的帧中,而 RFC 6455 禁止服务器这么做,严格的客户端只会在 编辑已经生效之后 关闭连接,而不是读取源码字节。因此这次写入必须通过读取文档确认,而不是通过 ack——但这也是更强的检查方法:它验证的是文档结果,而不是传输过程。
多文件写入要么全部成功,要么全部失败。 使用 write_files,而不是用循环调用 rewrite_file。每次编辑在任何内容写入之前都会完成校验和解析,因此常见失败——文件缺失、搜索字符串匹配多次或根本不存在、路径重复、名字非法——都不会实际改任何内容。如果仍有写入失败,则回对这些写的文件恢复。
这不是真正的事务(Typleaf 没有多文档事务),也没有 cookiframe"可恢复的版本,所以有两个限制会被报告,而不是隐藏:回滚可能本身失败,这时结果会把哪些文件处于什么样状态写清楚;以及写入这些文件的过程是真实发生的,所以一个正在观看的协作者可能已经看到了后来被撤销的状态。
🎯 Typst 特质
编译设置就是让项目成为 Typst 项目的关键
Typleaf 的 CLSI 只有在项目的 compiler 是 typst 并且根文档以 .typ 结尾时才生成 Typst 同步索引。一个项目里全是 .typ,但仍是默认的 pdflatex,那么系统会收到与 Typst 毫不相干的 TeX 报错,而且所有定位在 PDF 中的工具都会静默地返回空结果。
You: "Make a new Typst paper"
AI: [create_project name="Paper" compiler="typst"] ✓或在一个现有项目上运行: set_compiler(project_id, "typst").
标题
get_sections、update_section 和 section_page_map 识别第 0 列的 = 版节标题——与 Typst 编辑器自己的 outline 规则完全一致,因此服务器报告的章节与你所进行的 IDE 左侧文档结构完全一致。纯代码块、行注释和(嵌套)块注释会被跳过,因此代码样例里的 = 不会被认为是标题。
#heading(level: n)[…] 调用会被 project_info 识别,但有意识通过 update_section 编辑——重写由程序生成的标题主体,这算是 operations span。
编译日志
Typst 不写日志文件;所有信息都会输出到 stderr 到 stderr,然后 CLSI 捕获到 output.log。 download_log 把这些诊断解析为一个简洁的列表,使用 file:line:column 的格式:
Typst compile log — 1 error(s), 1 warning(s)
✗ expected comma (sections/05-parameters.typ:13:74)
⚠ unknown font family: calibri要查看未解析的原始文本,则调用 raw=true。
PDF 定位工具,以及它们的明确边界
locate_in_pdf 和 section_page_map 支持 Typst,依赖 Typleaf 的 TypstSyncManager,而不是 SyncTeX 对接。这四个差异是真实的,并会明确报告,而不是被隐藏:
更粗略。 Typleaf 在源码中加入零宽
#metadata标记,然后再问"typst query" 对这些标记出现在哪里。锚点是按源码 *行* 的,但只有在标记可安全添加的位置才会创建——因此查找只对所在块有效。#let/#show模板主体内的内容完全没有锚点,而#for` 循环体只为整个循环生成一个锚点。更慢。
output.typst-sync.json被列在编译输出中,但 Web 层代理并不会对其提供(已验证:它对 404 而对同一构建的output.pdf正常返回),因此无法离线解析。一个 LaTeX 项目只需一次output.synctex.gz解析就可以确定所有标题;而 Typst 项目里 每个节标题一次请求。因此section_page_map默认限制为最多 150 个标题(TYPLEAF_MAX_SECTIONS),在接近上限时会说明情况。按正文内容查询,而不是章节行。 含有
#outline()的文档会把每个标题渲染两次,而 Typleaf 的同步映射会保留符合当前文件 document-order 轨迹的版本——而这对于每个文件 第一个 级章节都会失败,因为没有之前的轨迹。在实测一个真实 104 页文档上,= Functions解析到了第 2 页(目录),真实页面是第 12 页。正文内容绝不会复制到目录中,因此那才是我们要查询的。任何残留的向后跳转都会在输出中被标记成!,而不会作为真实结果尝试展示。没有文本框的图。
text_area_fill_pct/text_area_remaining_pt来自于 LaTeXgeometry包的日志输出。Typst 不报告任何页面结构,因此这些字段在 Typst 中只会显示为不可用,而不是伪造值。物理页面填充百分比会(从 PDF MediaBox 计算)依然给出。
section_page_map 可默认跟随 #include 进入整个文档。Typst 的根文件通常很瘦,自身标题数量为零,所以传 file 来只映射单个文件。
Typst 页面计数通过对 PDF 解析得到,因为 typst 不会打印 Output written on … (N pages) 这样的行。而 Typst 编译如果没有诊断摘录,将会不生成任何日志,download_log 会把这种情况报告为成功,而不是找不到文件。
引用文献
Typst 既读取 BibTeX,也读取它原生的 Hayagriva YAML。 verify_citations 两者都处理: .yml 条目会转换为验证器需要的最小 BibTeX( title、 DOI、 arXiv id、 author、 year、 journal——实际对结论起作用的字段)。
与 LaTeX 端不同,因为这很好: .yml 是一个多种语言的扩展名,直接扫描会把 GitHub Actions workflow 传给验证器。所以对 Typst,该工具从源码中读取 #bibliography(…) 调用——沿着 #include 图搜索,因为 #bibliography 常出现在 back-matter.typ 里——如果不声明才回退到 .bib 扫描。报告中会说明走的是哪条路径。
对于 Typst 项目,它还会列出引用但没有定义的 key,这些会渲染为损坏的 ? 引用。LaTeX 会在编译时发出综述;Typst 的警告则很容易被忽略。页面上便签 (@fig-plot 针对 <fig-plot> 的引用) 会全项目排除,因此一份标记良好的文档不会把自己该类标签标记为缺失 citation。
🛠 工具(29)
定位
工具 | 描述 |
| 格式(Typst/LaTeX)、编译根文件、文件数量、已声明的参考文献。开销小——不编译。先调用它。 |
| 实例上的所有项目 |
| 格式、文件数量、根文件的标题结构 |
读取
工具 | 描述 |
| 列出文件,可选择按扩展名过滤 |
| 读取文件内容 |
| 对所有文本文件执行正则表达式搜索——请求无关项目大小只需发起 |
| 带层级和预览的标题结构 |
| 按标题获取某个章节的完整正文 |
| 用 CrossRef 和 arXiv 验证 DOI/arXiv ID;支持 BibTeX + Hayagriva |
写入
工具 | 描述 |
| 新建项目,可选带 |
| 新建文件;自动创建父文件夹 |
| 外科手术式精确查找替换(类似 |
| 替换整个文件内容 |
| 替换某一章节的正文,同时保留其标题 |
| 跨多个文件应用一次协调一致的更改,要么全部生效,要么全部不生效 |
| 上传本地二进制文件(图片、PDF) |
| 删除文件 |
| 切换项目编译器( |
历史
工具 | 描述 |
| 提交日志,可按文件和日期过滤 |
| 两个引用或工作区之间的差异 |
| 拉取最新更改 |
编译与输出
工具 | 描述 |
| 触发编译;返回状态及输出文件 |
| 将编译出的 PDF 保存到本地 |
| 编译日志——解析后的 Typst 诊断信息,或原始 TeX 日志 |
| 将项目源码以 |
| 将项目源码解压到一个目录 |
布局
工具 | 描述 |
| 编译后 PDF 的总页数 |
| 源码某一行落在 PDF 的哪一页:页码 + 矩形区域 |
| 每个标题对应的页码,以及最后一页的饱满程度 |
所有写入都会立即 commit 并 push。每个工具都带有 MCP 安全提示(readOnlyHint / destructiveHint / idempotentHint),并且如果存在任何仍未分类的工具,启动检查会拒绝运行。
🔄 与上游相比的变更
overleaf-mcp-plus 原本面向托管版 overleaf.com 与 LaTeX。这次重新定向共涉及五个方面:
新增——Typst 支持
typst.py— 解析标题、include/import、参考文献和引用;与 Typleaf 自己的编辑器规则保持一致document.py— 基于扩展名来进行调度,使每个工具都能用一条代码路径同时处理两种格式typst_log.py— 解析typst compile诊断信息的解析器hayagriva.py— 将.yml参考文献转换为 BibTeX,供校验工具使用layout.py— 基于 Typleaf 的 Typst 同步映射的第二个后端;LaTeX 的 SyncTeX 路径保持不变新工具:
project_info、set_compiler;create_project新增了compiler参数
自托管
TYPLEAF_BASE_URL为必填项,且没有默认值(见上文)git bridge 位于实例自身的 origin 上,即
/git/<id>,而不是独立的git.overleaf.com主机克隆失败时会将 git-bridge 模块列为可能的原因,并从 URL 中抹去 token
本地副本 sidecar 会记录 checkout 来自哪个 实例,而不只是项目 ID
打开中编辑器也能存活的写入
上游是直接通过 HTTP 整体替换文件。这种方式本身没有问题,但任何打开了该文件的协作者都会收到 “this file has gone out of sync” 并丢失自己的定位。这个 fork 改为经过实时通道来做编辑——用最小化的 ShareJS diff,使改动像真人输入一样流进已打开的编辑器。
ot.py— 极小的 insert/delete 组件,按文档逆序发出,确保每个 offset 都始终有效;发送前还会在本地重放realtime.py/polling.py— socket.io 0.9 客户端(WebSocket 和 xhr-polling)。Typleaf 的 git bridge 是可选模块,因此在没有该模块的实例上,实时服务是唯一存有文件夹和文档 ID 的地方transaction.py— 多文件编辑会预先校验,并在部分失败时回滚;这样你不会在编译坏掉之后才发现写入失败了search_files— 在服务器端执行正则搜索,而不是一个个地列出并读取候选文件
其中比较棘手的一个问题是 Typleaf 实时服务中的编码 bug:它把文档行按 Latin-1 解码后返回,而它自己的 ShareJS 偏移量却是针对正确解码的字符串计算的。如果对实际拿到的文本做 diff,首个非 ASCII 字符之后的所有偏移量都会错——插入操作什么也校验不到,只会被静默地放到错误的位置;删除操作匹配不上,服务器便会断开连接。纯 ASCII 文件无论怎么处理都是完全同的字节,因此能完meeting好地工作,这让人误以为那是体积或权限问题。ot.decode_doc_text 是为了撤销这种呈现而存在的;它是幂等的,所以即使未来某个实例被修复为提供正确的 UTF-8,它仍能保持正确。
带入 fork 的 Bug 修复
上游的
download_log无法调用:一次糟糕的合并把它的 return 语句遗留在section_page_map内部,于是该工具游走到了Unknown tool: download_log凭据守卫现在会报告 base URL 缺失,而不仅仅是 cookie 缺失
维持原样 — git 客户端、LaTeX 解析器、SyncTeX 引擎、线程安全的按项目锁定、MCP SDK v2 处理器注册、工具安全注解。
🧪 开发
git clone <this repo> && cd typleaf-mcp
python -m venv .venv && .venv/bin/pip install -e ".[compile]" pytest
.venv/bin/python -m pytest tests -q391 个测试,不需要外部网络。tests/conftest.py 把本包指向一个 .invalid 主机,因此任何跳过测试桩的测试都会以 DNS 错误失败,而不会访问到真实服务器。
tests/test_integration_fake_instance.py 在真实 socket 上运行一个替身风格的 Typeleaf,并断言它 收到的请求 ——包括会话 cookie 是否发送、写入请求是否携带 CSRF token、每个构建输出 URL 是否带 ?clsiserverid、sync/code 是否收到纯项目路径、以及 Typst 项目是否从未请求过 .synctex.gz。这些都是 mock httpx 覆盖不了的连接细节,也正是本包历史上 bug 多的地方。测试是整套测试中最慢的部分(约 18 秒),因为每次调用都会建立新连接。
tests/test_verify_citations.py 在未安装 tofu-search 时自动跳过;本 fork 新增的哦 discovery 和报告逻辑在 tests/test_verify_discovery.py 中单独测试,而该测试 без 无此依赖。
📄 许可证
MIT。与 Overleaf, Inc.、Digital Science 或 Typst 项目无附属关系。Typleaf Pro 是独立的社区项目。
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables access to Overleaf LaTeX projects through Git integration, allowing users to read files, analyze document structure, extract sections, and manage multiple projects through natural language commands.177MIT
- AlicenseNot gradedqualityCmaintenanceEnables Claude and AI agents to read and edit Overleaf documents in real time, with support for project listing, document manipulation, LaTeX compilation, and live collaboration.1038MIT
- FlicenseBqualityCmaintenanceEnables AI agents to interact with Overleaf projects directly, including creating projects, managing files, and editing documents in real-time using Overleaf's native Operational Transformation protocol.10
- AlicenseNot gradedqualityBmaintenanceConnects Claude/ChatGPT to Overleaf projects via the Git integration, enabling read, edit, write, and file management through natural language commands.2AGPL 3.0
Related MCP Connectors
Edit your Overleaf LaTeX projects from Claude and ChatGPT; every change is a real Git commit.
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/superzeldalink/typleaf-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server