Repository navigation
Releases
v0.5.0
backrest-mcp v0.5.0
Security
- Nested policy messages projected through pinned key allowlists (F-04): a field a later Backrest adds to
prunePolicy,checkPolicy,forgetPolicy,commandPrefix,scheduleorretentionis dropped until it is named. - Restore prefix moved out of
/tmp(default~/backrest-restore/) and refused unless it is a real 0700 directory owned by the server user (#1182). - Deploy from the lock: install/update with
uv sync --frozen --extra dev, notpip install -e ., so production runs the dependency set CI audits.
Added
list_plans,find_plan_for_path(path)(approximate restic exclude matching),get_backup_freshness(max_age_hours?)withstale_countandunscheduled_count. All read the secret-free projection only.scripts/run_live_conformance.py: live tests with credentials read in-process, never on argv.- NATS credentials:
NATS_CREDS_FILE, orNATS_USER+NATS_PASSWORD.
Changed
src/layout — an editable install must be redone beforepython -m backrest_mcp.serverworks again.- Bounded dependency ranges and a committed
uv.lock; CI installs--frozenand audits the lock. - Repository standard: SHA-pinned actions, least-privilege workflow permissions, gitleaks, CodeQL, OSSF Scorecard, CODEOWNERS, Dependabot, ruff
E F W I UP B SIM RUF+ format, coverage floor 96%.
See CHANGELOG.md for detail.
v0.4.1
Security
-
get_configno longer returns Backrest secrets. Before this release it passed Backrest'sGetConfigresponse through unchanged. Backrest v1.13.0 masks onlyauth.users[].passwordBcrypt, so the tool returned:repos[].password(the restic encryption key) in cleartextenvvalues and credential-bearinguriuserinfo- restic
flagsand hook targets - the multihost
syncblock
get_confignow returns an allowlist projection built by the newbackrest_mcp/redact.py. Unknown keys are dropped by construction. Secret-bearing fields become summaries:envKeys(names only),hasPassword,flagCount,backupFlagCount, and the hook action type.- Repo URIs lose userinfo, query strings and fragments, and are fully redacted when the userinfo boundary is ambiguous.
- restic
rclone:inline connection strings are redacted.
If you called
get_configon an earlier version, treat your repo password as disclosed to that session's transcript and any LLM tracing. -
restore_snapshotsends and audit-logs the resolved target path. This narrows a check-to-restore symlink race; it does not close it.restore_snapshotis registered only withBACKREST_ALLOW_DESTRUCTIVE=true.
See CHANGELOG.md for details.
v0.4.0
What's Changed
- fix: point PM2 ecosystem at venv python3, not system python3 by @TadMSTR in #3
- fix: parse forge.env inside ecosystem.config.js, drop --env-file by @TadMSTR in #4
- chore: add Release workflow (tag push → GitHub Release) by @TadMSTR in #5
- fix(observability): make failing telemetry visible, fail fast, and log once by @TadMSTR in #6
Full Changelog: v0.3.0...v0.4.0
v0.3.0 — live Backrest v1.13.0 conformance + HTTP transport
Reconciled the mock-only v0.2.1 against the deployed Backrest v1.13.0 connect-rpc API (forge :9898). Field names target the deployed version, not upstream main (which has since diverged).
Fixed
- Broken standalone entrypoint — added missing
if __name__ == "__main__": main()(python -m backrest_mcp.serverwas a silent no-op). get_summaryfailed-count fieldbackupsFailedLast30days→backupsFailed30days; added warning/scanned fields.get_operationsrepo filter now resolvesrepo_id→repoGuidand fans out across repos when unfiltered.list_snapshots()no-arg HTTP 500 fixed by enumerating + merging repos (Backrest #223).
Added
get_health,get_logs(Connect server-streaming),get_download_url.- HTTP/PM2 transport (
BACKREST_MCP_TRANSPORT=http) — loopback-only bind + mandatoryStaticTokenVerifierbearer token;main()fails closed.stdioremains default. - CI (ruff + pytest 3.11/3.12/3.13),
otel/natsextras, live-conformance tests (BACKREST_LIVE_TEST=1).
Security
- Connect-stream decoder hardening (audit
backrest-mcp-modernization-2026-07, Low): 64 MiB buffered-response cap + raises on a malformed frame whose declared length overruns the buffer, instead of silently truncating.
Changed
list_snapshot_filesargumentrepo_guid→repo_id(resolved to GUID internally; v1.13.0 wire field remainsrepo_guid).
Full notes: CHANGELOG.md.