Access Overleaf projects via CLI. Use for reading/writing LaTeX files, syncing local .tex files to Overleaf, downloading projects, and managing Overleaf project structure. Triggers on Overleaf, LaTeX sync, or tex file uploads to Overleaf.
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
CLI tool to interact with Overleaf projects using browser cookies for authentication.
GitHub: https://github.com/jkulhanek/pyoverleaf
pipx install pyoverleaf)⚠️ 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.
pyoverleaf authenticates by reading cookies from your browser. The user must:
# Test auth - user should run this in their terminal first
pyoverleaf lsIf you get auth errors:
pyoverleaf ls manually in terminal to trigger the keychain promptNote: The agent cannot log in for the user. Browser authentication must be done by the user directly.
# List all projects
pyoverleaf ls
# List files in project
pyoverleaf ls "Project Name"
# Read file content
pyoverleaf read "Project Name/main.tex"
# Write file (stdin → Overleaf)
cat local.tex | pyoverleaf write "Project Name/main.tex"
# Create directory
pyoverleaf mkdir "Project Name/figures"
# Remove file/folder
pyoverleaf rm "Project Name/old-draft.tex"
# Download project as zip
pyoverleaf download-project "Project Name" output.zippyoverleaf download-project "Project Name" /tmp/latest.zip
unzip -o /tmp/latest.zip -d /tmp/latest
cp /tmp/latest/main.tex /path/to/local/main.texThe CLI write command has websocket issues. Use Python API for reliable uploads:
import pyoverleaf
api = pyoverleaf.Api()
api.login_from_browser()
# List projects to get project ID
for proj in api.get_projects():
print(proj.name, proj.id)
# Upload file (direct overwrite)
project_id = "your_project_id_here"
with open('main.tex', 'rb') as f:
content = f.read()
root = api.project_get_files(project_id)
api.project_upload_file(project_id, root.id, "main.tex", content)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.
# Via env var
export PYOVERLEAF_HOST=overleaf.mycompany.com
pyoverleaf ls
# Via flag
pyoverleaf --host overleaf.mycompany.com lsWhen pulling from Overleaf:
/tmp/diffPush rules (from TOOLS.md):
Here's an example of using the Overleaf skill to remove em dashes (a common AI writing artifact) from a paper and push the changes:
open -a "Google Chrome" "https://www.overleaf.com/project" then wait 5s) to refresh cookies, then retryoverleaf.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"pyoverleaf ls in their terminal and click "Always Allow" on the keychain promptpyoverleaf lsOpenLAIR/dr-claw
3456bb4
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.