wheelripe
Queries the PyPI JSON API for package release file lists to determine whether locked dependency versions have compatible wheels (cp315, abi3, free-threaded) for target Python versions and platforms, helping agents identify ready packages, required version bumps, or upstream blockers.
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.

Install
uvx --from git+https://github.com/Blackman99/wheelripe wheelripe # one-off
pipx install git+https://github.com/Blackman99/wheelripe # or keep itNot 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.28BLOCKED 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 bumpA 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/simplecli · 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-urlreplaces PyPI (which is then never asked about your package names);--extra-index-urladds more, and files from all of them are pooled, as pip does.-i/--extra-index-urllines in requirements files (including-rincludes, with${VAR}expansion), the per-package registry inuv.lock,poetry.lock,pylock.tomlandPipfile.lock, andPIP_INDEX_URL/PIP_EXTRA_INDEX_URL/UV_DEFAULT_INDEX/UV_INDEXare honoured too. An explicit--index-urlbeats all of them.Local versions work like pip:
torch==2.14.0matches2.14.0+cpuon Linux and plain2.14.0on macOS;torch==2.14.0+cpumatches only the+cpubuilds. 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 toolscheck_python_upgradeCheck Python upgrade wheel readinessARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Lockfile, requirements file, pyproject.toml or project directory. Default: server working dir. | |
| glibc | No | Oldest glibc for linux-* targets, default 2.34 | |
| macos | No | Oldest macOS for macos-* targets, default 14 | |
| python | No | Target CPython, e.g. '3.15' or '3.15t' (free-threaded). | 3.15 |
| tracking | No | For 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_url | No | Simple-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. | |
| platforms | No | Target platforms. Default: linux-x86_64, macos-arm64, windows-amd64 | |
| requirements | No | Requirement specs such as 'numpy==1.26.4' (instead of path). | |
| extra_index_urls | No | More simple-API indexes; files from all indexes are pooled, like pip --extra-index-url. |
TDQS
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.
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.
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.
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.
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.
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 filenameARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| python | No | Target CPython, e.g. '3.15' or '3.15t' (free-threaded). | 3.15 |
| filename | Yes | ||
| platforms | No | Target platforms. Default: linux-x86_64, macos-arm64, windows-amd64 |
TDQS
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.
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.
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.
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.
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.
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.
2 tool updates
v0.1.0- First observed
check_python_upgrade - First observed
explain_wheel
TDQS
Scored across 2 tools
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.
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.
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.
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
Related MCP Connectors
Audit your MCP servers for poisoned tools and leaked secrets, and check AI-generated code for flaws.
What breaks between versions, vulnerabilities, compatible versions, EOL dates: npm, PyPI, Rust, PHP.
Breaking changes between two versions: npm, PyPI, GitHub Actions, Helm, Terraform, crates.io, Go.
Security research: MCP registries verify identity, not tool behavior. See gtfo.dev.
Related MCP Servers
- AlicenseAqualityDmaintenanceDiagnose, secure, and benchmark your MCP servers. Zero-config CLI for Claude Code, Cursor, VS Code, and Windsurf.411 npm3MIT
- AlicenseAqualityCmaintenance9 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.7106 npm3MIT
- AlicenseAqualityBmaintenanceAn 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.91MIT
- AlicenseNot gradedqualityAmaintenancedeptrust 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 npm61MIT