Skip to main content

safe-fix-mcp

PyPI License: MIT

A real MCP server that finds dead code in a Python repository and proposes a branch + PR for the one class of finding that's actually safe to auto-remove: unused imports on a single-name import line. Everything else it finds — unused functions, classes, unused dependencies — stays report-only. A human always merges. This tool never merges anything itself.

Why this exists

Most "dead code" tools stop at reporting. The ones that go further usually delete with no safety net. This does neither: it drafts a real, minimal, reviewable PR, gated on the target repo's own full test suite actually passing after the removal — not a heuristic, a real pytest run. If the suite fails, nothing is committed or pushed; the repo is left exactly as it started.

Tools

scan_dead_code(repo_path=".", min_confidence=60)

Read-only. Runs vulture (dead code) and deptry (dependency issues) and returns a human-readable list of findings. Never modifies anything.

propose_removal_pr(repo_path=".")

  • Refuses on a dirty working tree — never edits on top of uncommitted work.
  • Filters to unused imports at ≥90% vulture confidence, on single-name import lines only (from x import y, z is skipped — removing the whole line would silently remove z too).
  • Creates a real branch, removes the qualifying imports, runs the repo's real full test suite.
  • Only on a real pass: commits, pushes, and tries to open a PR via gh pr create.
  • If gh isn't installed/authenticated, the branch is still committed and pushed for real — only PR creation degrades, with the real error returned so you can open it manually.

Install

pip install safe-fix-mcp

Add to your MCP client config (e.g. Claude Code):

claude mcp add safe-fix-mcp -- safe-fix-mcp

Or run directly for local testing:

python -m safe_fix_mcp.server

Installing from source instead of PyPI:

pip install -e .

Requirements

  • Python ≥ 3.10
  • git on PATH
  • gh (GitHub CLI) on PATH and authenticated, if you want propose_removal_pr to actually open the PR — without it, the branch still gets pushed for real, and the tool tells you to open the PR by hand.

Development

pip install -e ".[dev]"
pytest

Known limitation

vulture flags scan_dead_code/propose_removal_pr themselves as "unused" — a known false-positive class, not a real bug: they're dispatched by the @mcp.tool() decorator at runtime, not called directly anywhere in the source, so static call-graph analysis can't see the real caller (the MCP framework itself).

Verifying it for real

scripts/verify_real_client.py launches the packaged server as a real subprocess and talks to it with the real mcp.client.ClientSession — the same path a real MCP client uses. Useful as a smoke test after any change:

python scripts/verify_real_client.py

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

safe_fix_mcp-0.1.1.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

safe_fix_mcp-0.1.1-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file safe_fix_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: safe_fix_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.9

File hashes

Hashes for safe_fix_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 74c893023293835d52aebd1293e52c10b8b714d7bb494a68add60a5d0b91b02c
MD5 10e107994be5cca2a36f85bbb21924c0
BLAKE2b-256 897ebc604a2ab365cf3a8054b2aceb01775bd1b44a20d7a6456b704ad61a107d

See more details on using hashes here.

File details

Details for the file safe_fix_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: safe_fix_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.9

File hashes

Hashes for safe_fix_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 788423aea6c4247cb1ca14df1fb4b5a6196ef57be9e4186c17407432faa7a26b
MD5 7c8a17780cdabc2932f374765f479827
BLAKE2b-256 b1db8daa98f196e142e7bb4eb4efcea4a569e9a52ef6ae36a82071f4c17cb8cc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page