io.github.pamela-0/safe-fix-mcp
Finds real dead code and proposes a safe, test-gated branch+PR to remove it.
Open source Open in the app JSON README (API)
About
Finds real dead code and proposes a safe, test-gated branch+PR to remove it.
Details
- Kind
- MCP servers
- Topic
- No topic detected
- Publisher
- pamela-0
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.1.1
- Stars
- 1
- Last push
- 2026-08-21T21:51:16Z
- Repository state
- ativo
- Language
- Python
- License
- MIT
- Added
- 2026-08-29 04:00:59
- Updated
- 2026-08-29 04:00:59
- Origin id
io.github.pamela-0/safe-fix-mcp
README
# safe-fix-mcp <!-- mcp-name: io.github.pamela-0/safe-fix-mcp --> [](https://pypi.org/project/safe-fix-mcp/) [](LICENSE) 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](https://github.com/jendrikseipp/vulture) (dead code) and [deptry](https://github.com/fpgmaas/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 ```bash pip install safe-fix-mcp ``` Add to your MCP client config (e.g. Claude Code): ```bash claude mcp add safe-fix-mcp -- safe-fix-mcp ``` Or run directly for local testing: ```bash python -m safe_fix_mcp.server ``` Installing from source instead of PyPI: ```bash pip install -e . ``` ## Skill A `SKILL.md` ships inside this same package — not a separate download — and teaches Claude when and how to use the two tools correctly (e.g. that `propose_removal_pr` only ever auto-removes single-name unused imports, never functions/classes/dependencies). Install it into your project: ```bash safe-fix-mcp-install-skill ``` Run it from the project root you want the skill active in — it writes to `.claude/skills/safe-fix-mcp/SKILL.md` relative to your current directory. ## 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 ```bash 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: ```bash python scripts/verify_real_client.py ```