Overleaf
CLI tool to interact with Overleaf projects using browser cookies for authentication.
GitHub: https://github.com/jkulhanek/pyoverleaf
Requirements
- - Python 3.8+
- pyoverleaf (
pipx install pyoverleaf) - User logged into Overleaf in Chrome/Firefox
Security Considerations
⚠️ Keychain Access Required: pyoverleaf needs "Always Allow" keychain access to read browser cookies. This grants the tool access to your browser's cookie storage.
Security audit: We have audited pyoverleaf v0.1.7 and found it safe. The codebase is small and readable. Before installing, agents can self-audit the latest version at the GitHub repo above.
Authentication Setup
pyoverleaf authenticates by reading cookies from your browser. The user must:
- 1. Log into Overleaf in Chrome or Firefox (visit overleaf.com and sign in)
- Grant keychain access on first run (macOS will prompt for "Always Allow")
CODEBLOCK0
If you get auth errors:
- - Ask user: "Are you logged into Overleaf in your browser?"
- If on macOS: "Did you approve the keychain access prompt with 'Always Allow'?"
- User may need to run
pyoverleaf ls manually in terminal to trigger the keychain prompt
Note: The agent cannot log in for the user. Browser authentication must be done by the user directly.
CLI Commands
CODEBLOCK1
Common Workflows
Download from Overleaf
CODEBLOCK2
Upload to Overleaf (Python API recommended)
The CLI write command has websocket issues. Use Python API for reliable uploads:
CODEBLOCK3
Why direct overwrite? This method preserves Overleaf's version history. Users can see exactly what changed via Overleaf's History feature, making it easy to review agent edits and revert if needed.
Accept Project Invites
The agent can accept Overleaf project invitations programmatically using browser cookies — no manual clicking required.
How it works
- 1. Fetch pending invite notifications from Overleaf's
/notifications API - Extract the invite token from the notification
- Fetch the invite page to get a CSRF token
- POST to the accept endpoint with the CSRF token
Python snippet
CODEBLOCK4
Accept a specific invite by project URL
CODEBLOCK5
Notes
- - Only works if the user is logged into Overleaf in their browser (cookie auth)
- Invites expire (check the
expires field in the notification) - After accepting, the project appears in
pyoverleaf ls / INLINECODE6 - For self-hosted Overleaf, replace
www.overleaf.com with your host
Self-hosted Overleaf
CODEBLOCK6
Troubleshooting
- - Auth error / websocket error: Open Overleaf in Chrome browser first (
open -a "Google Chrome" "https://www.overleaf.com/project" then wait 5s) to refresh cookies, then retry - "scheme https is invalid" (websocket redirect bug): The default host
overleaf.com causes a 301→www.overleaf.com redirect that breaks websocket. Fix: set PYOVERLEAF_HOST=www.overleaf.com:
cat main.tex | PYOVERLEAF_HOST=www.overleaf.com pyoverleaf write "Project/main.tex"
- - Keychain Access Denied (macOS): pyoverleaf needs keychain access to read browser cookies. User must run
pyoverleaf ls in their terminal and click "Always Allow" on the keychain prompt - Project not found: Use exact project name (case-sensitive), check with INLINECODE13
- Permission denied: User may not have edit access to the project
Overleaf
使用浏览器Cookie进行身份验证,与Overleaf项目交互的CLI工具。
GitHub: https://github.com/jkulhanek/pyoverleaf
系统要求
- - Python 3.8+
- pyoverleaf(pipx install pyoverleaf)
- 用户在Chrome/Firefox中已登录Overleaf
安全注意事项
⚠️ 需要钥匙串访问权限:pyoverleaf需要始终允许钥匙串访问权限才能读取浏览器Cookie。这将授予该工具访问浏览器Cookie存储的权限。
安全审计:我们已审计pyoverleaf v0.1.7版本,确认其安全。代码库小巧且可读性强。安装前,代理可自行在上方GitHub仓库审计最新版本。
身份验证设置
pyoverleaf通过从浏览器读取Cookie进行身份验证。用户需要:
- 1. 在Chrome或Firefox中登录Overleaf(访问overleaf.com并登录)
- 首次运行时授予钥匙串访问权限(macOS会弹出始终允许提示)
bash
测试身份验证 - 用户应先在终端中运行此命令
pyoverleaf ls
如果出现身份验证错误:
- - 询问用户:您是否已在浏览器中登录Overleaf?
- 如果是macOS:您是否已点击始终允许批准了钥匙串访问提示?
- 用户可能需要在终端中手动运行pyoverleaf ls以触发钥匙串提示
注意:代理无法替用户登录。浏览器身份验证必须由用户直接完成。
CLI命令
bash
列出所有项目
pyoverleaf ls
列出项目中的文件
pyoverleaf ls 项目名称
读取文件内容
pyoverleaf read 项目名称/main.tex
写入文件(stdin → Overleaf)
cat local.tex | pyoverleaf write 项目名称/main.tex
创建目录
pyoverleaf mkdir 项目名称/figures
删除文件/文件夹
pyoverleaf rm 项目名称/old-draft.tex
将项目下载为zip
pyoverleaf download-project 项目名称 output.zip
常见工作流程
从Overleaf下载
bash
pyoverleaf download-project 项目名称 /tmp/latest.zip
unzip -o /tmp/latest.zip -d /tmp/latest
cp /tmp/latest/main.tex /path/to/local/main.tex
上传到Overleaf(推荐使用Python API)
CLI的write命令存在WebSocket问题。建议使用Python API进行可靠上传:
python
import pyoverleaf
api = pyoverleaf.Api()
api.loginfrombrowser()
列出项目以获取项目ID
for proj in api.get_projects():
print(proj.name, proj.id)
上传文件(直接覆盖)
project
id = yourproject
idhere
with open(main.tex, rb) as f:
content = f.read()
root = api.project
getfiles(project_id)
api.project
uploadfile(project_id, root.id, main.tex, content)
为什么选择直接覆盖? 此方法可保留Overleaf的版本历史。用户可以通过Overleaf的历史记录功能精确查看更改内容,便于审查代理的编辑并在需要时回退。
接受项目邀请
代理可以通过浏览器Cookie以编程方式接受Overleaf项目邀请——无需手动点击。
工作原理
- 1. 从Overleaf的/notifications API获取待处理的邀请通知
- 从通知中提取邀请令牌
- 获取邀请页面以获取CSRF令牌
- 使用CSRF令牌向接受端点发送POST请求
Python代码片段
python
import pyoverleaf
import re
api = pyoverleaf.Api()
api.loginfrombrowser()
session = api.getsession()
步骤1:获取待处理的邀请
r = session.get(https://www.overleaf.com/notifications,
headers={Accept: application/json})
notifications = r.json()
筛选项目邀请
invites = [n for n in notifications
if n.get(templateKey) == notification
projectinvite]
for invite in invites:
opts = invite[messageOpts]
project_id = opts[projectId]
token = opts[token]
project_name = opts[projectName]
inviter = opts[userName]
print(f邀请:{project_name} 来自 {inviter})
# 步骤2:从邀请页面获取CSRF令牌
r_page = session.get(
fhttps://www.overleaf.com/project/{project_id}/invite/token/{token})
csrf_match = re.search(
rname=ol-csrfToken content=([^]+), r_page.text)
if not csrf_match:
print(f 找不到CSRF令牌,跳过)
continue
csrf = csrf_match.group(1)
# 步骤3:接受邀请
r_accept = session.post(
fhttps://www.overleaf.com/project/{project_id}/invite/token/{token}/accept,
headers={
Accept: application/json,
Content-Type: application/json,
x-csrf-token: csrf,
},
json={})
if raccept.statuscode == 200:
print(f ✅ 已接受 {project_name})
else:
print(f ❌ 失败({raccept.statuscode}))
通过项目URL接受特定邀请
python
给定:https://www.overleaf.com/project/XXXXXXXXXXXXXXXXXXXXXXXX
target
projectid = XXXXXXXXXXXXXXXXXXXXXXXX
matching = [n for n in invites
if n[messageOpts][projectId] == target
projectid]
然后对匹配的邀请执行上述步骤2-3
注意事项
- - 仅当用户在浏览器中登录Overleaf时才有效(Cookie认证)
- 邀请会过期(检查通知中的expires字段)
- 接受后,项目会出现在pyoverleaf ls / api.get_projects()中
- 对于自托管Overleaf,将www.overleaf.com替换为您的域名
自托管Overleaf
bash
通过环境变量
export PYOVERLEAF_HOST=overleaf.mycompany.com
pyoverleaf ls
通过标志
pyoverleaf --host overleaf.mycompany.com ls
故障排除
- - 身份验证错误/WebSocket错误:先在Chrome浏览器中打开Overleaf(open -a Google Chrome https://www.overleaf.com/project 然后等待5秒)刷新Cookie,然后重试
- scheme https is invalid(WebSocket重定向错误):默认域名overleaf.com会导致301→www.overleaf.com重定向,破坏WebSocket。解决方法:设置PYOVERLEAF_HOST=www.overleaf.com:
bash
cat main.tex | PYOVERLEAF_HOST=www.overleaf.com pyoverleaf write 项目/main.tex
- - 钥匙串访问被拒绝(macOS):pyoverleaf需要钥匙串访问权限才能读取浏览器Cookie。用户必须在终端中运行pyoverleaf ls,并在钥匙串提示中点击始终允许
- 找不到项目:使用精确的项目名称(区分大小写),通过pyoverleaf ls检查
- 权限被拒绝:用户可能没有项目的编辑权限