Skip to main content

package-upgrade-mcp

An MCP server that helps an LLM plan dependency upgrades without drowning in changelog text. Point it at a manifest file and it tells you what's outdated, how risky each upgrade looks, and — only for the packages worth worrying about — pulls the actual breaking-change notes.

Supported manifests: package.json (npm), requirements.txt (PyPI), pubspec.yaml (pub.dev), Cargo.toml (crates.io).

No API keys required — every registry it talks to (npm, PyPI, pub.dev, crates.io, GitHub) is public.

Why it's split into stages

Fetching full release notes for every dependency in a real project would burn a huge amount of context for basically no benefit, since most upgrades are patch/minor bumps with nothing breaking in them. So the server does the boring, deterministic part itself and only reaches for text when it's actually warranted:

  1. Cheap and always called — scan_manifest / check_upgrades return current vs. latest version, the semver delta, and a risk level computed from version math plus registry metadata (deprecated/yanked flags). No changelog text, just one registry lookup per dependency.
  2. Targeted, only for what's flagged — get_breaking_change_excerpts fetches changelog or release-note text and runs it through a heuristic filter that keeps the parts that look like breaking-change announcements (## Breaking, BREAKING CHANGE:, removed/renamed/ deprecated notes, migration guides) and throws away routine feature/fix entries. get_raw_changelog is there too, for the rare case the filtered excerpt isn't enough.

The server never decides "this will take 3 days" or writes the upgrade plan itself — that synthesis is left to whichever LLM is calling it. Its job ends at handing over small, pre-digested findings instead of a wall of release notes.

Install

With Claude Code:

claude mcp add package-upgrade-mcp -- uvx package-upgrade-mcp

With OpenAI Codex CLI:

codex mcp add package-upgrade-mcp -- uvx package-upgrade-mcp

With Gemini CLI:

gemini mcp add package-upgrade-mcp -- uvx package-upgrade-mcp

Or add it to your MCP config by hand with uvx (no clone or install step — uvx fetches the package from PyPI on first run):

{
  "mcpServers": {
    "package-upgrade-mcp": {
      "command": "uvx",
      "args": ["package-upgrade-mcp"]
    }
  }
}

This package hasn't been published to PyPI yet, so uvx package-upgrade-mcp won't resolve until it is. Until then, run it from a clone — see Developing locally below, it takes about a minute.

Everything above is optional to configure — the server works with zero setup. If you want to raise GitHub's unauthenticated rate limit (60 requests/hour, which you can hit if you check a lot of packages in one session) or tune HTTP timeouts and cache TTL, copy .env.example to .env and fill in what you need; see the table in Configuration below.

Tools

Tool Stage What it does
scan_manifest(path) 1 Parse a manifest into a flat dependency list. Pure parsing, no network.
check_upgrades(path) 1 Scan + resolve latest versions + static risk analysis (semver delta, deprecated/yanked).
get_versions_between(ecosystem, package, from_version, to_version) 2 List every published version in a range.
get_breaking_change_excerpts(ecosystem, package, from_version, to_version) 2 Fetch changelogs and return only the excerpts that look breaking.
get_raw_changelog(ecosystem, package, from_version, to_version) 2 Full, unfiltered changelog text (opt-in fallback).

ecosystem is one of npm, pypi, pub, cargo.

Usage

You don't call these tools directly — you talk to your agent and it reaches for them based on what you ask. A few examples of what that looks like in practice:

"What's outdated in this project, and how risky does it look?" → triggers scan_manifest + check_upgrades against your package.json (or whichever manifest you point it at). A real run against a small project looked like this:

check_upgrades("package.json") →
  left-pad     1.3.0 → 1.3.0   delta=none   risk=medium  (deprecated)
  lodash       4.17.21 → 4.18.1 delta=minor  risk=medium
  jest         29.0.0 → 30.4.2  delta=major  risk=high
  my-local-pkg (file: dependency, skipped — not resolvable against a registry)

"What actually broke between jest 29 and 30 that could affect my tests?" → once a package is flagged risky, this triggers get_breaking_change_excerpts("npm", "jest", "29.0.0", "30.4.2"), which pulls GitHub release notes and hands back just the migration-relevant bits instead of every release's full changelog.

"Show me the raw changelog for X, the summary you gave me wasn't enough" → falls back to get_raw_changelog for the same version range.

A couple of things worth knowing:

  • check_upgrades never fetches changelog text — it's the cheap first pass. Point the agent at specific packages afterward if you want detail; asking it to explain every dependency up front will make it fan out to get_breaking_change_excerpts for all of them, which is slower and uses more context than necessary.
  • Dependencies pinned via file:, path:, git:, or workspace: specs show up in scan_manifest/check_upgrades but are marked unresolvable — there's no registry to check them against.
  • Results are cached in memory for the life of the server process, so asking about the same package twice in one session doesn't refetch it.

Configuration

All optional, all in .env.example:

Variable Default What it's for
REQUEST_TIMEOUT_SECONDS 15.0 HTTP timeout for registry/changelog requests
CACHE_TTL_SECONDS 3600 How long registry/changelog lookups stay cached
HTTP_USER_AGENT package-upgrade-mcp (contact.hasil@gmail.com) Sent on every request — crates.io in particular rejects requests without one
GITHUB_TOKEN unset Optional; raises GitHub's release-notes rate limit above the unauthenticated 60/hr

Developing locally

uv sync
cp .env.example .env   # optional
uv run package-upgrade-mcp

Point your MCP config at the local checkout instead of uvx:

{
  "mcpServers": {
    "package-upgrade-mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/package-upgrade-mcp",
        "run",
        "package-upgrade-mcp"
      ]
    }
  }
}

Development

uv run pytest -v            # test suite (all HTTP mocked, no network needed)
uv run ruff check .          # lint
uv run ruff format .         # format
uv run mypy src              # type check

To poke at it against real registries instead of through an agent conversation, use the MCP Inspector:

npx @modelcontextprotocol/inspector uv run package-upgrade-mcp

Metadata

Release files for package-upgrade-mcp 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for package-upgrade-mcp 0.1.1
File Size Uploaded
package_upgrade_mcp-0.1.1.tar.gz 15.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for package-upgrade-mcp 0.1.1
File Interpreter ABI Platform
package_upgrade_mcp-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 40.0 kB

Release files / package_upgrade_mcp-0.1.1.tar.gz

Download URL package_upgrade_mcp-0.1.1.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8a58169ba92a2b02390008d5ad90e2a8a23f198b68cce8daf6540154f72d7668
BLAKE2b-256 checksum
How to use checksums
1b0b02a6069c10cf5fcfecfd5444e222730b718288bd485c15f80f0dbebda02f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release files / package_upgrade_mcp-0.1.1-py3-none-any.whl

Download URL package_upgrade_mcp-0.1.1-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11b51dddca1a6514d1ee07b79813166b5f4f5475b6f340cc47735938f670be77
BLAKE2b-256 checksum
How to use checksums
3602eceafa0cea732e46490e477e9785f2095c5c88872108a01b95b053a897ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page