Changelog¶
All notable changes to this project will be documented in this file.
The format follows Keep a Changelog, and the project adheres to Semantic Versioning. The 0.x line signals iteration; the v1.0 API surface will be committed to once the tool list stabilises.
[Unreleased]¶
[0.4.1] - 2026-05-27¶
First published release of the 0.4.x line. [0.4.0] was tagged (2026-05-12) but never reached PyPI — see Fixed. 0.4.1 ships all of 0.4.0's changes (listed below) with the release-pipeline issue resolved.
Fixed¶
- The release pipeline no longer blocks on the live Overleaf write suite. Overleaf git write is a premium-only feature, so gating the PyPI publish on a live paid credential made releases brittle: when the test project's Overleaf premium lapsed, writes began returning HTTP 403, which silently blocked the v0.4.0 publish. The release
acceptancejob and the per-PRreal-overleafjob are now non-blocking signals;nightly.ymlremains the dedicated daily canary.
Changed¶
- CI dependency/action bumps:
actions/deploy-pages4→5,actions/upload-pages-artifact3→5,actions/checkout4→6, plus grouped Python dependency updates.
[0.4.0] - 2026-05-12¶
Added¶
- Acceptance test suite (
tests/acceptance/): 13 end-to-end tests against a real Overleaf project covering every tool (read, write, sync). Each test does the action via the actual MCP tool handler and verifies the change reached Overleaf by re-cloning fresh. - Acceptance gate on releases.
release.ymlnow runs the acceptance suite before build/publish. A failing acceptance test blocks the PyPI publish. - Nightly canary (
nightly.yml): runs the acceptance suite at 06:00 UTC daily and opens a GitHub issue on failure. Catches upstream changes (Overleaf API, mcp SDK, token rotation overdue) within ~24h. pytest -m acceptanceopt-in pattern; defaultpytestrun excludes the suite viaaddopts. Suite skips cleanly withoutOVERLEAF_TEST_*secrets so forks and local dev never try to hit a remote they can't authenticate against.- Brand banner (
assets/banner.{svg,png}) perbanner-spec.md. README references the SVG at the top. - MkDocs Material documentation site + GitHub Pages deploy workflow + README docs badge.
- Codecov upload from CI; Coverage and Downloads badges on README.
- CONTRIBUTING.md, EXAMPLES.md, deployment recipes, README troubleshooting section.
- Dependabot for actions + dependencies; pre-commit hooks.
Changed¶
- README badges and prose aligned to brand system (license in Hunter Green, version in Ink).
- Dependency bumps:
codecov-action5 → 6,setup-uv3 → 7,download-artifact4 → 8,setup-python5 → 6,upload-artifact4 → 7,ruffbumped.
[0.3.0] - Remote deployment¶
Added¶
- Streamable HTTP transport. New
overleaf-mcp serve-httpsubcommand exposes the server over HTTP using the MCP SDK's modern Streamable HTTP transport (the one claude.ai web uses). Defaults to127.0.0.1:8080;--host 0.0.0.0+ a reverse proxy gets you public access. Same tool surface, same behavior. Only the wire layer differs from stdio. - Mandatory bearer-token auth on the HTTP path. Server refuses to start without
OVERLEAF_MCP_AUTH_TOKENset, because the keychain holds the user's Overleaf tokens and exposing those to an open HTTP port would be wrong. There is no "open mode" flag, even for local testing. - Endpoint:
POST /mcp/(trailing slash required) carryingAuthorization: Bearer <token>. - Token check uses
hmac.compare_digestso timing on a partial-match attempt doesn't leak the token byte-by-byte. /healthzendpoint returns{"status": "ok"}and is exempt from auth so monitoring doesn't need credentials.core/auth.pymodule withresolve_auth_token()andcheck_bearer_token(): transport-agnostic primitives so any future transport (websocket, etc.) reuses the same auth model.
Notes¶
- TLS is intentionally out of scope; use a reverse proxy (nginx, caddy, cloudflare) for it. Keeps the server's dep graph small.
- The stdio transport (
overleaf-mcp serve) is unchanged. Existing Claude Desktop configs keep working. - Real-socket integration test spins up uvicorn, drives the MCP wire format with the SDK's
streamable_http_client, and round-trips a tool call through bearer auth: the same code path claude.ai web uses.
[0.2.0] - Tool surface completion¶
Added¶
get_sectionstool. Lists every LaTeX section in a.texfile with level, line range, and a markdown-style indent so the structure is scannable in Claude's response. Use this beforeget_section_contentto discover what's available.get_section_contenttool. Returns the body of a named section. Errors loudly when the title isn't found (lists available titles) or matches multiple sections (forces disambiguation rather than silently picking one).create_filetool. Distinct fromedit_file. Errors withFileExistsErrorif the target already exists, forcing the caller to useedit_filefor overwrites. Samepull → validate → write → commit → pushflow.delete_filetool. Pulls latest, removes the file, commits as the system git author, pushes back. Errors if the file doesn't exist (no silent no-ops).project_statustool. One-shot summary: alias + display name, tracked file count, working-tree dirty state, and the last commit (short SHA, author, relative date, subject). Useful for orientation before starting work or for debugging stale-clone situations.overleaf-mcp project clone <alias>CLI subcommand. Replaces the manualgit clone https://git:TOKEN@...step in setup. Uses the same askpass token-injection asprobe_remoteso the token never lands on the subprocess command line or in the cloned repo's git config.--forceremoves a stale clone and re-clones from scratch.doctornow points users at this command instead of suggesting a rawgit clone.
Changed¶
authenticated_git_envcontext manager extracted. The askpass-tempfile pattern previously inlined inprobe_remoteis now a reusable context manager incore/project.py.probe_remote, the newclone_with_tokenhelper, and any future token-authenticated git invocation share the same single implementation. No public API change.
Internal¶
- New
GitClient.delete_file(path)andGitClient.last_commit_summary()primitives back the newdelete_fileandproject_statustools.
[0.1.2] - Patch release¶
Added¶
- Non-interactive
init.overleaf-mcp initnow accepts--alias,--project-id,--display-name, and--forceflags so the command is fully scriptable. Passing--aliasengages non-interactive mode end-to-end: missing required flags fail fast (no silent stdin reads),--project-idbecomes required, and an existing alias requires--forceto overwrite (no confirm prompt). The bare interactive form (overleaf-mcp init) is unchanged. - Non-interactive
auth add. Two new options for token entry without TTY prompts: --token-stdinreads the token from stdin (printf '%s' "$TOK" | overleaf-mcp auth add ...). Recommended for scripts, since it keeps the token off the process command line.--token-from-env VAR_NAMEreads the token from a named environment variable. Empty or unset variables fail fast.- The two options are mutually exclusive; passing both is a usage error.
- There is intentionally no
--token VALUEflag because values on the command line leak viaps.
Notes¶
- These additions are purely additive. Existing interactive flows and tests keep working unchanged (26 pre-existing CLI tests still pass; 15 new tests cover the flag paths).
[0.1.1] - Patch release¶
Fixed¶
overleaf-mcp --versionno longer crashes withRuntimeError: 'overleaf_mcp' is not installed. The CLI now passespackage_name="overleaf-mcp-server"to click'sversion_option, so the metadata lookup targets the PyPI distribution name rather than the Python module name. All other commands were unaffected by the bug.
Planned for v0.2¶
get_sectionsandget_section_contenttools using the existingSectionParserinterfacecreate_fileanddelete_filetoolsproject_statustool (file count, last sync, dirty state)- HTTP/SSE transport for remote / multi-client setups
- A
project cloneCLI subcommand to remove the manualgit clonestep in setup
[0.1.0] - Initial release¶
Added¶
- Five MCP tools:
list_projects,list_files,read_file,edit_file,sync - stdio transport with three equivalent entry points (
overleaf-mcp serve,python -m overleaf_mcp, librarybuild_server()) - CLI commands for setup:
init,auth add/auth remove/auth list,doctor - Token storage in the OS keychain via
keyring(macOS Keychain, Windows Credential Manager, libsecret on Linux), with environment-variable fallbacks (OVERLEAF_TOKEN_<ALIAS>,OVERLEAF_TOKEN) - Configuration file at
~/.config/overleaf-mcp/config.toml(overridable viaOVERLEAF_MCP_CONFIG) - Local clone cache at
~/.cache/overleaf-mcp/<alias>(overridable viaOVERLEAF_MCP_CACHE) - Regex-based LaTeX section parser behind an abstract
SectionParserinterface - 100% line and branch test coverage on the core and tools layers; an end-to-end integration test exercising the real MCP wire format