The project reports a PyInstaller build of asammdf going from 431 MB to 259 MB by stubbing one GUI submodule, which knocked out the Qt dependency underneath it — and it found by analysis the same three packages that had been stubbed by hand. The safety rule matters as much as the finding: when the analyser is unsure it says required, so it under-reports rather than breaking your executable.
An MCP server for people shipping Python as an executable with PyInstaller, Nuitka or cx_Freeze. It parses your import graph with the standard library's AST module, tracks which packages are genuinely called on your runtime path, and generates stub packages for the ones that are only imported by a dependency.
- `analyze` walks the graph from your entry point and sorts every package into stubbable, nofollow or required, with estimated sizes and submodule hints
- `graph` renders the import graph as nodes and edges; `check` gives the detailed usage picture for one package
- `generate` emits the minimal stub code for a package plus the install, uninstall and hook-disable commands to apply it
- `generate_submodule` targets the harder case: a C-extension package that cannot be stubbed directly, eliminated indirectly by stubbing the submodule that imports it
- A deliberately conservative verdict rule — anything ambiguous is called required, so a wrong call costs you size rather than a broken build
- Build instructions that include a backup, a version-pinned reinstall and a verify command
`pip install mcp-pystub`, then run `mcp-pystub` as a stdio server from your client config. Each call needs your entry-point path and the site-packages path of the environment you are freezing. The analysis engine itself uses only the Python standard library. Known limits: dynamic imports through a variable cannot be traced statically, custom PyInstaller hooks may need disabling by hand, and pip names that differ from import names are not mapped. MIT licensed.
One command — pip install mcp-pystub
