Skip to main content
Glama

wheelripe

Before you move to a new Python, find every dependency that has no wheel for it yet — and the version bump that fixes each one.

Python 3.15 shipped on 2026-10-09. Moving a project means finding out, package by package, whether each locked dependency has a cp315 (or abi3, or free-threaded cp315t/abi3t) wheel for your platforms. Today that means upgrading, watching pip/uv fall back to an sdist and fail on a missing compiler or header, fixing one, and repeating — or hand-checking the PyPI JSON API like harlequin#1119 and dynamic-des#40 do. pip install --only-binary=:all: --python-version 3.15 stops at the first failure and never tells you which newer release would work.

wheelripe reads your lockfile, asks the index for every release's file list, and applies the same tag rules pip does (PEP 425/600/656/803 — CI cross-checks every verdict against pip on the real PyPI) for every target platform at once.

wheelripe checking a requirements file for CPython 3.15

Install

uvx --from git+https://github.com/Blackman99/wheelripe wheelripe          # one-off
pipx install git+https://github.com/Blackman99/wheelripe                   # or keep it

Not on PyPI yet; the release has a wheel you can pip install directly.

Related MCP server: mcp-toolkit

Use

wheelripe                               # auto-detects uv.lock / pylock.toml / poetry.lock / requirements.txt / pyproject.toml
wheelripe uv.lock --python 3.15t        # free-threaded
wheelripe requirements.txt --platform linux-aarch64,musllinux-x86_64 --glibc 2.28
BLOCKED  confluent-kafka 2.16.0          no cp315 wheel for any target platform (ships cp38–cp314)
         tracking: open issue #2299 · Python 3.15 support including binary wheels
                   https://github.com/confluentinc/confluent-kafka-python/issues/2299 · +2 more open
BUMP     numpy 1.26.4 → 2.5.2            no cp315 wheel in 1.26.4 (ships cp39–cp312); 2.5.2 is the first release with one
BUMP     pydantic_core 2.41.5 → 2.48.0   no cp315 wheel in 2.41.5 (ships cp39–cp314); 2.48.0 is the first release with one
READY    1 package (0 with binary wheels · 1 pure Python)

NOT RIPE for CPython 3.15: 1 blocked upstream · 2 need a version bump

A BUMP you can do today. A BLOCKED package you wait for, so wheelripe finds its GitHub repository from PyPI and links the open issue or PR asking for the new Python's wheels (in every output format), or tells you nobody has asked yet. One search per blocked package, no token needed (GITHUB_TOKEN raises GitHub's limit from 10 to 30 searches a minute); offline or rate-limited, it says so once and the verdicts and exit code stay the same. --no-tracking turns it off.

PyTorch, private mirrors and other indexes

wheelripe reads PEP 691 (JSON) and PEP 503 (HTML) simple indexes — PyTorch's download.pytorch.org, or a private one on Artifactory, Nexus, devpi or GitLab — with the options pip takes:

wheelripe torch==2.13.0 numpy==2.5.4 --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple
cli · 2 packages · index download.pytorch.org/whl/cpu + pypi.org

BUMP     torch 2.13.0 → 2.14.0   no cp315 wheel in 2.13.0 for macos-arm64, windows-amd64 (ships cp310–cp315); 2.14.0 is the first release with one · ready on linux-x86_64
READY    1 package (1 with binary wheels · 0 pure Python)
  • -i/--index-url replaces PyPI (which is then never asked about your package names); --extra-index-url adds more, and files from all of them are pooled, as pip does.

  • -i / --extra-index-url lines in requirements files (including -r includes, with ${VAR} expansion), the per-package registry in uv.lock, poetry.lock, pylock.toml and Pipfile.lock, and PIP_INDEX_URL / PIP_EXTRA_INDEX_URL / UV_DEFAULT_INDEX / UV_INDEX are honoured too. An explicit --index-url beats all of them.

  • Local versions work like pip: torch==2.14.0 matches 2.14.0+cpu on Linux and plain 2.14.0 on macOS; torch==2.14.0+cpu matches only the +cpu builds. CI checks this against pip on the live PyTorch index.

  • Credentials go in the URL (https://USER:TOKEN@host/simple) or ~/.netrc. They are sent only to that host and never printed: every URL in output, warnings and errors is redacted.

Exit code is 1 when anything needs a bump or is blocked (--fail-on blocked|build|never to change). Also: -f json|markdown|github, a GitHub Action (uses: Blackman99/wheelripe@v0.1.0), and an MCP server (wheelripe mcp) so coding agents check before they bump.

Docs: https://blackman99.github.io/wheelripe/docs/ · GOAL.md · ROADMAP.md · MIT

Available Tools

2 tools
check_python_upgradeCheck Python upgrade wheel readinessA
Read-onlyIdempotent

Before moving a project to a new Python (e.g. 3.15 or free-threaded 3.15t), list every dependency that has no installable wheel for it on the target platforms, and the smallest version bump that fixes each one. Reads uv.lock / pylock.toml / poetry.lock / Pipfile.lock / requirements.txt / pyproject.toml from path, or checks explicit requirements specs. Statuses: ready, bump (newer release has a wheel), blocked (no release has one: waiting on upstream), excluded (requires-python), build (sdist only), skip (marker), missing. Blocked packages carry tracking: the upstream issue/PR to watch.

NameRequiredDescriptionDefault
pathNoLockfile, requirements file, pyproject.toml or project directory. Default: server working dir.
glibcNoOldest glibc for linux-* targets, default 2.34
macosNoOldest macOS for macos-* targets, default 14
pythonNoTarget CPython, e.g. '3.15' or '3.15t' (free-threaded).3.15
trackingNoFor each blocked package, link the upstream GitHub issue/PR about wheels for the target Python (packages[].tracking). One GitHub search per repo; uses GITHUB_TOKEN from the server environment if set. Never changes a verdict.
index_urlNoSimple-API index (PEP 691/503) to use instead of PyPI, e.g. 'https://download.pytorch.org/whl/cpu'. Like pip --index-url. Default: -i from requirements files, PIP_INDEX_URL, then PyPI.
platformsNoTarget platforms. Default: linux-x86_64, macos-arm64, windows-amd64
requirementsNoRequirement specs such as 'numpy==1.26.4' (instead of path).
extra_index_urlsNoMore simple-API indexes; files from all indexes are pooled, like pip --extra-index-url.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the read-only/idempotent/open-world profile, but the description goes well beyond: it enumerates the verdict taxonomy, explains that blocked packages carry `tracking` links, and discloses that tracking costs one GitHub search per repo, uses GITHUB_TOKEN, and never changes a verdict. It also spells out index resolution precedence (index_url vs. requirements-file -i vs. PIP_INDEX_URL vs. PyPI).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first clause, followed by input-source mechanics and a compact status glossary. The status list is dense but each term is needed to interpret output; no filler sentences. Slightly long single breath, but structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description carries return-value burden and does so reasonably: verdict semantics and the `packages[].tracking` field are explained, along with the bump outcome. What's less explicit is the shape of the per-package record (current version, bump target, platform coverage), which an agent would need to consume results fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3; the description adds real meaning the schema lacks by naming the exact lockfile formats read from `path` (uv.lock, pylock.toml, poetry.lock, Pipfile.lock, requirements.txt, pyproject.toml). It still leaves `glibc`/`macos` and the platform set entirely to the schema, which is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb, resource, and trigger ('Before moving a project to a new Python... list every dependency that has no installable wheel for it'), plus the concrete output ('smallest version bump'). It does not name or differentiate against the sibling explain_wheel, so it falls short of the top band.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The trigger condition is explicit ('Before moving a project to a new Python (e.g. 3.15 or free-threaded 3.15t)'), and the description clarifies the two input modes: read lockfiles from `path`, or check explicit `requirements` specs. It stops short of stating when to use explain_wheel instead, so no full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_wheelExplain a wheel filenameA
Read-onlyIdempotent

Say whether a wheel filename (e.g. foo-1.0-cp315-abi3.abi3t-manylinux_2_28_x86_64.whl) installs on a target CPython and platforms, using PEP 425/600/656/803 tag rules.

NameRequiredDescriptionDefault
pythonNoTarget CPython, e.g. '3.15' or '3.15t' (free-threaded).3.15
filenameYes
platformsNoTarget platforms. Default: linux-x86_64, macos-arm64, windows-amd64

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds the useful behavioral detail that the verdict is derived from PEP 425/600/656/803 tag rules, which explains how the answer is computed, but it does not say what the response looks like or how tag mismatches are reported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense, front-loaded sentence with a helpful inline example; nothing extraneous. It is slightly packed with PEP citations, but every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, an agent learns the tool returns an install/no-install verdict for a given filename, python, and platform set. The example filename and PEP references give enough grounding to call it correctly, though the exact return shape and mismatch explanation remain unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, and the schema already documents the python and platforms parameters with defaults. The description only echoes that the target is CPython plus platforms and adds no format or edge-case detail (e.g. free-threaded 't' variants) beyond the schema text, so it neither compensates further nor regresses.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('say whether ... installs'), the resource (a wheel filename), and scope (target CPython and platforms), backed by a concrete example and the governing PEP references. It is clearly a compatibility-check tool and distinguishable from the sibling check_python_upgrade.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case (checking install compatibility before attempting an install) but never states when to pick this over the sibling tool or what prerequisites exist. No exclusions or alternative routing are given, leaving usage inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedcheck_python_upgrade
    • First observedexplain_wheel

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

check_python_upgrade audits an entire project's dependencies for wheel availability on a target Python/platform, while explain_wheel decodes a single wheel filename using tag rules. Their inputs and outputs are clearly different, so an agent can choose correctly; the overlap is only domain-level, not functional.

Naming Consistency5/5

Both names are snake_case and start with a verb (check_..., explain_...), followed by the object or context. The patterns are predictable and consistent across the tool set.

Tool Count4/5

Two tools is slightly below the typical 3–15 range, but this is a narrow wheel-compatibility utility where the pair covers both batch project analysis and single-artifact explanation. There is no redundant tool, so the small surface is reasonable rather than deficient.

Completeness4/5

The tools cover batch dependency upgrade readiness, status classification, upstream tracking, and single-wheel tag explanation. A minor gap is the lack of a standalone package/release wheel-matrix lookup, but the core upgrade decisions are supported.

Maintenance

ActivityNo data
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    9 MCP servers for React + TypeScript development automation — component scaffolding, dependency auditing, WCAG accessibility checking, test generation, TypeScript enforcement, and monorepo management. 134 tests, CI on Node 20+22.
    7
    106 npm
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that scans your lockfiles (npm, PyPI, Go, Rust, Ruby, PHP) for known vulnerabilities, enriches with EPSS exploit probability scores, and recommends fix versions. $14/mo — not per-seat.
    9
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    deptrust is a CLI that checks package versions for known vulnerabilities across npm, PyPI, crates.io, Go modules, RubyGems, NuGet, Maven, Packagist, pub.dev, CocoaPods, Hex.pm, Hackage, GitHub Actions, and more. It runs locally as a CLI and as an MCP server. It calls public package registry and OSV APIs directly; there is no hosted deptrust service to trust or configure.
    95 npm
    61
    MIT