Keep your MCP server's dependencies healthy
What we checked
We resolved your package’s dependency tree from its registry, then looked at what that registry states plainly about each dependency we could resolve. Three facts count against a dependency:
| Fact | What it means |
|---|---|
| Deprecated | The maintainer has said, in writing, stop using this. On PyPI we read a yanked release the same way. |
| No recent release | Nothing published for over two years (730 days). |
| No source repository | The package declares no repository, so there is nothing to read and nowhere to report a bug. |
These are hygiene signals, not security ones. A deprecated dependency is a maintenance liability, not evidence of a compromise. Known vulnerabilities are a separate check, as is malware.
The result feeds Supply Chain Security. A dependency with none of the three is healthy; the finding on your server’s page reads as a count, for example “3 of 214 dependencies flagged as unhealthy (1 deprecated)”.
How the score works
Two details are worth knowing before you start fixing things.
Depth matters. Each dependency is weighted by 1 / depth, so a direct
dependency counts double a dependency of a dependency, and four times one that
sits four levels down. Fixing something you depend on directly moves the number
far more than chasing a transitive package you cannot control.
One bad dependency cannot cost more than one dependency. The penalties are 1.0 for deprecated, 0.5 for no recent release and 0.25 for no source repository, but a single dependency’s total is capped at 1.0. A package that is deprecated, stale and repo-less costs no more than one that is merely deprecated.
The signal is one minus the weighted average of those penalties, not a count of good dependencies against bad ones. A flagged dependency keeps whatever credit its penalty leaves: a tree in which every dependency is missing only its source repository scores 0.75, not 0. A large tree with a few flagged packages barely moves. That is deliberate, and it is why we never report this check as an outright failure on the counts alone.
How to fix it
Work down from the direct dependencies, and treat each of the three facts differently:
- Deprecated: migrate. A deprecation notice almost always names a successor. This is the one case where the maintainer has told you outright to move, so it carries the heaviest penalty and it is the clearest fix.
- No recent release: judge it. Two years of silence can mean abandonment, or it can mean a small library that is genuinely finished. Replace it when a maintained equivalent exists, and keep it when it does not. We would rather you kept a stable dependency than swapped it for a busier but less trustworthy one.
- No source repository: check for a newer version first. Many packages added repository metadata in later releases, so an upgrade can clear this without a migration.
The cheapest fix is often removal. If you pull in a whole package for one small function, inlining it removes a dependency, its issues and its own subtree at once.
When the tree is only partly resolved
Some trees cannot be walked all the way. A dependency may specify a git or file path rather than a registry version, a version may no longer be published, or the walk may hit a depth, fan-out or size bound. When that happens we assess what we resolved and say so, and the signal is capped by how much of the tree we could see. A partly resolved tree never scores as a complete one.
The usual causes you can act on are dependencies pointing at git URLs or local paths instead of published versions, and versions that have been unpublished from the registry.
When we cannot check at all
The signal is reported as unverified, rather than as a failure, when we could not resolve the tree. The common reasons are:
- We could not reach the registry, or the walk timed out. These are gaps on our side, and they clear on a later run.
- The package or the declared version is not published in its registry.
- The ecosystem is not supported. We resolve dependency trees for npm, PyPI, NuGet, MCPB bundles and OCI images. Anything else is out of scope for now.
- An OCI image ships no SBOM. We do not unpack images, so a container’s dependency list has to come from a software bill of materials attached to it. Publishing one lets us assess it. See build provenance for how to attach one.
An unverified signal is never counted as a pass. It scores zero for this check, so it is worth clearing the ones you control.
How we re-check
We re-resolve the tree on our next crawl of your package. Once a released version carries the updated dependencies, the counts move on the following score refresh. Publishing a fix does not need a rescore request.
Give this to your AI
Paste this into Claude Code (or any coding agent) from inside your server's repository. It states the failing signal, the outcome we re-check for, and the format the fix has to take.
Context: this repository publishes an MCP server. VerifyMCP resolved its dependency tree and flagged some dependencies as unhealthy. A dependency is counted unhealthy when its registry entry says it is deprecated, when it has had no release in over two years, or when it declares no source repository. Goal: fewer flagged dependencies in the tree, with every replacement a real, working one. Do this: 1. Read the finding on the VerifyMCP page for this server and list the named dependencies and which of the three issues each one has. 2. For each deprecated dependency, look up what its maintainer says to use instead and migrate to it. Deprecation notices usually name a successor. 3. For each dependency with no recent release, judge it rather than replacing it reflexively: a small, finished library can be stable rather than abandoned. Replace it when there is a maintained equivalent, and tell me when you think it should stay. 4. For each dependency with no declared source repository, check whether a newer version declares one before swapping it out. 5. Prefer removing a dependency outright over replacing it, where the code you use from it is small. 6. Run the full test suite after each migration. Rules: - Never publish a release yourself. Prepare the change, show me the diff, and let me publish it. - Never swap a dependency for an unmaintained or less popular package just to clear the flag; that trades a known issue for an unknown one. - Never pin to an old version to dodge the check. The check reads the registry's own record, not your lockfile. - Direct dependencies matter most: the check weights a dependency by how close it is to your package, so fixing a direct one is worth more than fixing something four levels deep. - Ask me before dropping a dependency that changes public behaviour. Report back: which dependencies you changed, what you replaced them with, which ones you judged should stay and why, and the test results. Reference: https://verifymcp.io/docs/packages/dependency-health