safe-fix-mcp
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, zis skipped — removing the whole line would silently removeztoo). - 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
ghisn'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
giton PATHgh(GitHub CLI) on PATH and authenticated, if you wantpropose_removal_prto 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74c893023293835d52aebd1293e52c10b8b714d7bb494a68add60a5d0b91b02c
|
|
| MD5 |
10e107994be5cca2a36f85bbb21924c0
|
|
| BLAKE2b-256 |
897ebc604a2ab365cf3a8054b2aceb01775bd1b44a20d7a6456b704ad61a107d
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
788423aea6c4247cb1ca14df1fb4b5a6196ef57be9e4186c17407432faa7a26b
|
|
| MD5 |
7c8a17780cdabc2932f374765f479827
|
|
| BLAKE2b-256 |
b1db8daa98f196e142e7bb4eb4efcea4a569e9a52ef6ae36a82071f4c17cb8cc
|