0xWisco_Labs_ beta Launching soon
API reference

Every tool, every field.

The same 4 tools are available two ways: as an MCP server your agent connects to once, and as a plain HTTP API. Both take the same parameters and return the same JSON.

Connect

MCP (Claude Code, Cursor, and any client that supports remote MCP servers over streamable HTTP):

claude mcp add --transport http wisco-labs https://api.wiscolabs.dev/mcp

Or in a client's JSON config:

{
  "mcpServers": {
    "wisco-labs": { "url": "https://api.wiscolabs.dev/mcp" }
  }
}

VS Code (Copilot agent mode), in .vscode/mcp.json:

{
  "servers": {
    "wisco-labs": { "type": "http", "url": "https://api.wiscolabs.dev/mcp" }
  }
}

HTTP: POST https://api.wiscolabs.dev/v1/<dataset>/<tool> with a JSON body, or GET with the same names as query parameters.

Make it automatic. Agents only call a tool when they think of it. Add this to your project's CLAUDE.md, AGENTS.md or Cursor rules:

## Dependencies
Before adding, upgrading or pinning any Python or npm dependency, check it with the
wisco-labs tools: upgrade_check for the whole requirements.txt or package-lock.json,
what_changed for a single package. Never install a version they report as vulnerable
or malicious; use the suggested version instead. Tell me about any breaking changes
or removals before upgrading.

Basics

  • No key needed during the beta. Please keep usage reasonable; heavy automated use may be rate limited.
  • Responses are JSON. Package names are matched the way each registry does (e.g. Flask and flask are the same).
  • Coverage: the 3,000 most-used PyPI packages and 1,000 most-used npm packages. Vulnerabilities are checked for any package, tracked or not.
  • Freshness: data is collected continuously. GET https://api.wiscolabs.dev/health returns when it was last published.

Errors

Errors come back as JSON with an error message that says what to fix.

StatusMeaning
400A required parameter is missing, or a value isn't valid (e.g. not a real version number).
404Unknown tool, or a package we don't track (where the tool needs its history).
503Data is being published for the first time; try again shortly.
500Something went wrong on our side. It's logged; please try again.

Check a whole project's dependencies

Give it a project's dependencies: a requirements.txt or pip freeze output for Python, or a package-lock.json, package.json, or name@version lines for npm. Flags malicious packages and versions with known vulnerabilities (with the smallest safe version to move to, preferring a low-risk patch), then reports what each upgrade breaks, removes, or deprecates, ranked into remove_now / fix_now / no_fix_available / upgrade_first / safe / review / needs_care.

MCP tool
upgrade_check
HTTP
POST /v1/package_changes/upgrade_check with a JSON body, or GET /v1/package_changes/upgrade_check?… with query parameters

Parameters

ParameterWhat it is
requirementsrequiredPython: requirements.txt contents, one 'package==version' per line. npm: the contents of package-lock.json (best), package.json, or one 'name@version' per line. Lines without one exact version are listed but can't be assessed.
ecosystemoptional, default PyPIPyPI or npm. A package.json or package-lock.json is recognized as npm automatically.
limitoptional, default 5Max items shown per category for each package

What comes back

FieldMeaning
ecosystemPyPI or npm: the ecosystem the dependencies were read as.
input_notesPresent only when some input lines couldn't be read exactly (e.g. a version range in package.json); explains what was skipped.
summaryCounts across the whole project: packages checked, outdated, up to date, not tracked, not assessed (no exact version), how many upgrades are high / medium / low risk, and total breaking changes, removals, deprecations and security fixes the upgrades would bring.
securityVulnerabilities in the versions you're on now: how many packages are affected, the number of known vulnerabilities, packages grouped by worst severity, and any packages reported as malicious.
recommendationPackage names sorted into what to do, most urgent first. remove_now: reported as malicious. fix_now: has known vulnerabilities and a fixed version exists. no_fix_available: vulnerable with no fix released yet. upgrade_first: the upgrade gains security fixes without high risk. safe_to_upgrade: no notable changes. review_then_upgrade: removals, deprecations or new runtime requirements to check. needs_care: breaking changes or a major version jump.
packages[]One entry per outdated package: current and latest version, suggested_version (the smallest version without known vulnerabilities, when the current one has any), the vulnerabilities, upgrade_risk, and the same change lists as what_changed (breaking_changes, removals, deprecations, security_fixes_gained, major_version_bumps, runtime_requirement_changes, notes_coverage).
up_to_date[]Packages already on the latest version, with any known vulnerabilities that still affect it.
not_tracked[]Packages outside our coverage (the most-used packages of each ecosystem). Known vulnerabilities are still checked for them.
not_assessed[]Lines without one exact version (e.g. flask>=2.0), listed but not checked.

Example request

curl -X POST https://api.wiscolabs.dev/v1/package_changes/upgrade_check \
  -H 'Content-Type: application/json' \
  -d '{"requirements": "requests==2.31.0\nurllib3==1.26.18", "limit": "2"}'
Example response (shortened)
{
  "ecosystem": "PyPI",
  "summary": {
    "packages_checked": 2,
    "outdated": 2,
    "up_to_date": 0,
    "not_tracked": 0,
    "not_assessed": 0,
    "high_risk": 1,
    "medium_risk": 1,
    "low_risk": 0,
    "total_breaking": 0,
    "total_removed": 32,
    "total_deprecated": 15,
    "total_security_fixes_gained": 23
  },
  "security": {
    "vulnerable_packages": 2,
    "known_vulnerabilities": 3,
    "vulnerable_packages_by_worst_severity": {
      "critical": 0,
      "high": 0,
      "medium": 2,
      "low": 0,
      "unknown": 0
    },
    "malicious_packages": [],
    "data": "OSV (osv.dev) and the GitHub Advisory Database, CC-BY 4.0"
  },
  "recommendation": {
    "remove_now": [],
    "fix_now": [
      "urllib3",
      "requests"
    ],
    "no_fix_available": [],
    "upgrade_first": [],
    "safe_to_upgrade": [],
    "review_then_upgrade": [],
    "needs_care": []
  },
  "packages": [
    {
      "package": "urllib3",
      "current": "1.26.18",
      "latest": "2.8.0",
      "suggested_version": "2.5.0",
      "vulnerability_count": 2,
      "max_severity": "medium",
      "known_vulnerabilities": [
        {
          "id": "GHSA-34jh-p97f-mpxf",
          "aliases": [
            "CVE-2024-37891"
          ],
          "summary": "urllib3's Proxy-Authorization request header isn't stripped during cross-origin redirects",
          "severity": "medium",
          "fixed_in": [
            "1.26.19"
          ],
          "malicious_package": false,
          "url": "https://osv.dev/vulnerability/GHSA-34jh-p97f-mpxf"
        },
        {
          "id": "GHSA-pq67-6m6q-mj2v",
          "aliases": [
            "CVE-2025-50181"
          ],
          "summary": "urllib3 redirects are not disabled when retries are disabled on PoolManager instantiation",
          "severity": "medium",
          "fixed_in": [
            "2.5.0"
          ],
          "malicious_package": false,
          "url": "https://osv.dev/vulnerability/GHSA-pq67-6m6q-mj2v"
        }
      ],
      "upgrade_risk": "high",
      "summary": {
        "releases_between": 24,
        "releases_with_notes": 24,
        "breaking": 0,
        "removed": 27,
        "deprecated": 14,
        "security_fixes_gained": 18,
        "other_changes": 156
      },
      "breaking_changes": [],
      "removals": [
        {
          "version": "2.0.0",
          "text": "Removed support for Python 2.7, 3.5, and 3.6 (#883, #2336).",
          "source": "changelog",
          "id": "51ebe54cd8a78119"
        },
        {
          "version": "2.0.0",
          "text": "Removed fallback on certificate `commonName` in `match_hostname()` function. This behavior was deprecated in May 2000 in RFC 2818. Instead only `subjectAltName` is used to verify the hostname by default. To enable verifying the hostname against `commonName` use `SSLContext.hostname_checks_common_name = True` (#2113).",
          "source": "changelog",
          "id": "876f65d187a11987"
        }
      ],
      "deprecations": [
        {
          "version": "2.0.0",
          "text": "Deprecated `HTTPResponse.getheaders()` and `HTTPResponse.getheader()` which will be removed in urllib3 v2.1.0. Instead use `HTTPResponse.headers` and `HTTPResponse.headers.get(name, default)`. (#1543, #2814).",
          "source": "changelog",
          "id": "b25e165299973395"
        },
        {
          "version": "2.0.0",
          "text": "Deprecated `urllib3.contrib.pyopenssl` module which will be removed in urllib3 v2.1.0 (#2691).",
          "source": "changelog",
          "id": "f287b578471e6771"
        }
      ],
      "security_fixes_gained": [
        {
          "version": "2.5.0",
          "text": "Fixed a security issue where restricting the maximum number of followed redirects at the `urllib3.PoolManager` level via the `retries` parameter did not work.",
          "source": "changelog",
          "id": "a611198286ef9ab9"
        },
        {
          "version": "2.6.0",
          "text": "Fixed a security issue where streaming API could improperly handle highly compressed HTTP content (\"decompression bombs\") leading to excessive resource consumption even when a small amount of data was requested. Reading small chunks of compressed data is safer and much more efficient now. (GHSA-2xpw-w6gg-jr37)",
          "source": "changelog",
          "id": "489b0b74658a81d6"
        }
      ],
      "major_version_bumps": [
        {
          "version": "2.0.0",
          "released": "2023-04-26"
        }
      ],
      "runtime_requirement_changes": [
        {
          "version": "1.26.19",
          "requires": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
        },
        {
          "version": "2.0.0",
          "requires": ">=3.7"
        }
      ],
      "notes_coverage": "complete",
      "suggested_upgrade_risk": "high"
    }
  ],
  "up_to_date": [],
  "not_tracked": [],
  "not_assessed": []
}

What changed between two versions of a package

What breaks, gets removed, is deprecated, or gains a security fix when upgrading one package between two versions, with an overall upgrade risk.

MCP tool
what_changed
HTTP
POST /v1/package_changes/what_changed with a JSON body, or GET /v1/package_changes/what_changed?… with query parameters

Parameters

ParameterWhat it is
namerequiredPackage name, e.g. flask (PyPI) or express or @babel/core (npm)
fromrequiredThe version you're on now
torequiredThe version you want to upgrade to (use latest_version from package_info if unsure)
ecosystemoptional, default PyPIPyPI or npm
limitoptional, default 15Max items shown per category

What comes back

FieldMeaning
upgrade_riskhigh: the project lists breaking changes, or the upgrade crosses a major version. medium: removals, deprecations, new runtime requirements, or yanked versions in between. low: none of those.
versioningsemantic or calendar. Major-version jumps only count as risky for semantic versioning.
summaryCounts for every release between from and to: releases with notes, breaking changes, removals, deprecations, security fixes gained, and other changes.
breaking_changes[]Each change the project's own release notes call breaking: version, text (quoted from the notes), source (changelog or github_releases), and a stable id.
removals[]Removed features, functions and supported versions, in the same shape as breaking_changes.
deprecations[]Deprecated features that will be removed later, in the same shape.
security_fixes_gained[]Security fixes described in the release notes that the upgrade brings.
major_version_bumps[]Each major version crossed, with its release date.
runtime_requirement_changes[]Versions that changed the required language runtime (e.g. Python >=3.9, Node >=18).
yanked_versions_in_range[]Versions in between that were withdrawn by the maintainers.
known_vulnerabilitiesHow many known vulnerabilities affect the from version, which ones the upgrade fixes, and which are still present in the to version.
notes_coveragecomplete: every release in between has release notes. partial: some do. none: only version signals (major bumps, runtime requirements) are available.

Example request

curl -X POST https://api.wiscolabs.dev/v1/package_changes/what_changed \
  -H 'Content-Type: application/json' \
  -d '{"name": "flask", "from": "2.3.3", "to": "3.1.3", "limit": "3"}'
Example response (shortened)
{
  "ecosystem": "PyPI",
  "package": "flask",
  "repo": "pallets/flask",
  "from": "2.3.3",
  "to": "3.1.3",
  "upgrade_risk": "high",
  "versioning": "semantic",
  "summary": {
    "releases_between": 8,
    "releases_with_notes": 8,
    "breaking": 0,
    "removed": 2,
    "deprecated": 1,
    "security_fixes_gained": 0,
    "other_changes": 28
  },
  "breaking_changes": [],
  "removals": [
    {
      "version": "3.0.0",
      "text": "Remove previously deprecated code. #5223 (edited)",
      "source": "changelog",
      "id": "3cf6eee9d0aab566"
    },
    {
      "version": "3.1.0",
      "text": "Drop support for Python 3.8. #5623 (edited)",
      "source": "changelog",
      "id": "06741e103c17a6da"
    }
  ],
  "deprecations": [
    {
      "version": "3.0.0",
      "text": "Deprecate the `__version__` attribute. Use feature detection, or `importlib.metadata.version(\"flask\")`, instead. #5230 (edited)",
      "source": "changelog",
      "id": "937b5578ec9cdedf"
    }
  ],
  "security_fixes_gained": [],
  "major_version_bumps": [
    {
      "version": "3.0.0",
      "released": "2023-09-30"
    }
  ],
  "runtime_requirement_changes": [
    {
      "version": "3.1.0",
      "requires": ">=3.9"
    }
  ],
  "yanked_versions_in_range": [],
  "known_vulnerabilities": {
    "in_from_version": 0,
    "fixed_by_upgrade": [],
    "still_present_after_upgrade": []
  },
  "notes_coverage": "complete"
}

Known vulnerabilities in a package version

Is this exact version of a package affected by known security advisories? Returns each vulnerability (with CVE ids and severity), the versions that fix it, and the smallest safe upgrade.

MCP tool
vulnerabilities
HTTP
POST /v1/osv/vulnerabilities with a JSON body, or GET /v1/osv/vulnerabilities?… with query parameters

Parameters

ParameterWhat it is
namerequiredPackage name
versionrequiredThe exact version you're using
ecosystemoptional, default PyPIPackage ecosystem (OSV naming)

What comes back

FieldMeaning
affectedtrue if this exact version is affected by at least one known vulnerability.
max_severityThe worst severity among them: critical, high, medium, low, or unknown.
malicious_packagetrue if the package is reported as malicious: remove it rather than upgrade.
vulnerabilities[]Each advisory: id (GHSA, PYSEC, MAL...), aliases (CVE ids), summary, severity, cvss_score, the versions that fix it (fixed_in), the publish date, and a link.
minimum_safe_versionThe smallest newer version with no known vulnerabilities.
minimum_safe_same_majorThe smallest safe version without changing major version: often a low-risk patch. null if none exists.
latest_version_affectedtrue if even the newest version is still affected.
notePresent when the answer needs a caveat, e.g. for packages whose release history we don't track.
sourceWhere the vulnerability data comes from, with its license.

Example request

curl -X POST https://api.wiscolabs.dev/v1/osv/vulnerabilities \
  -H 'Content-Type: application/json' \
  -d '{"name": "urllib3", "version": "1.26.18"}'
Example response (shortened)
{
  "ecosystem": "PyPI",
  "package": "urllib3",
  "version": "1.26.18",
  "affected": true,
  "vulnerability_count": 2,
  "max_severity": "medium",
  "malicious_package": false,
  "vulnerabilities": [
    {
      "id": "GHSA-34jh-p97f-mpxf",
      "aliases": [
        "CVE-2024-37891"
      ],
      "summary": "urllib3's Proxy-Authorization request header isn't stripped during cross-origin redirects",
      "severity": "medium",
      "cvss_score": 4.4,
      "malicious_package": false,
      "fixed_in": [
        "1.26.19"
      ],
      "published": "2024-06-17",
      "url": "https://osv.dev/vulnerability/GHSA-34jh-p97f-mpxf"
    },
    {
      "id": "GHSA-pq67-6m6q-mj2v",
      "aliases": [
        "CVE-2025-50181"
      ],
      "summary": "urllib3 redirects are not disabled when retries are disabled on PoolManager instantiation",
      "severity": "medium",
      "cvss_score": 5.3,
      "malicious_package": false,
      "fixed_in": [
        "2.5.0"
      ],
      "published": "2025-06-18",
      "url": "https://osv.dev/vulnerability/GHSA-pq67-6m6q-mj2v"
    }
  ],
  "minimum_safe_version": "2.5.0",
  "minimum_safe_same_major": null,
  "latest_version_affected": false,
  "source": "OSV (osv.dev) and the GitHub Advisory Database, CC-BY 4.0"
}

Basic facts about a package

Latest and latest stable version, repository, release count, and where its release notes come from.

MCP tool
package_info
HTTP
POST /v1/package_changes/package_info with a JSON body, or GET /v1/package_changes/package_info?… with query parameters

Parameters

ParameterWhat it is
namerequiredPackage name
ecosystemoptional, default PyPIPyPI or npm

What comes back

FieldMeaning
latest_versionThe newest published version, including pre-releases.
latest_stable_versionThe newest version that isn't a pre-release or yanked. Use this as the upgrade target.
repoThe source repository (owner/name) where release notes are read from.
release_countHow many versions have been published.
versions_with_notesHow many of those have release notes we could read.
notes_sourcesWhere the notes come from: changelog (a file in the repository) and/or github_releases.
first_releaseDates of the first and latest releases (first_release, latest_release).

Example request

curl -X POST https://api.wiscolabs.dev/v1/package_changes/package_info \
  -H 'Content-Type: application/json' \
  -d '{"name": "flask"}'
Example response (shortened)
{
  "ecosystem": "PyPI",
  "package": "flask",
  "summary": "A simple framework for building complex web applications.",
  "homepage": null,
  "repo": "pallets/flask",
  "latest_version": "3.1.3",
  "latest_stable_version": "3.1.3",
  "release_count": 64,
  "versions_with_notes": 62,
  "notes_sources": [
    "changelog"
  ],
  "first_release": "2010-04-16",
  "latest_release": "2026-02-19"
}

For machines

Everything on this page, in formats agents and code generators read directly:

https://api.wiscolabs.dev/llms.txt        what's here, in plain text
https://api.wiscolabs.dev/v1/catalog      every dataset, tool and parameter
https://api.wiscolabs.dev/openapi.json    OpenAPI schema
https://api.wiscolabs.dev/docs            interactive (Swagger) explorer

Data and credit

Changes are sorted into categories by software, which makes mistakes. See the terms.