Skip to main content
Glama

Package Truth

CI npm downloads OpenSSF Scorecard License: MIT

Stops coding agents from installing packages that do not exist, are deprecated, or have known vulnerabilities, across npm, PyPI, Go, Maven, Cargo, NuGet and RubyGems.

Language models invent package names. In a USENIX Security 2025 study of 16 code models, 19.7% of the packages they recommended did not exist, and attackers now register those invented names ("slopsquatting"). Package Truth checks every dependency before it is installed and gives each one a verdict an agent can act on:

Verdict

Meaning

does_not_exist

No such package, no such version, or no version matching the range: do not install

risky

The version that would be installed is deprecated or has known advisories

verify

Published under 90 days ago or has at most two versions: a possible squat, check before use

ok

No problem found in deps.dev at query time (not a security guarantee)

Give it a whole manifest (package.json, requirements.txt, pyproject.toml, Cargo.toml, go.mod, Gemfile, *.csproj, pom.xml) and it resolves each range to the version an install would pick today, checks it, and lists problems first. No account, no key.

Built and maintained by Arhan Canli. Data from deps.dev (Open Source Insights).

Install

Install in Cursor Install in VS Code Install in Goose

Needs Node.js 20 or newer. No account or key.

Claude Code

claude mcp add package-truth -- npx -y package-truth-mcp

Claude Desktop: download package-truth-mcp-<version>.mcpb from the latest release and open it. The bundle is signed; verify it with gh attestation verify <file> --repo arhancanli/package-truth-mcp.

Any other client (Windsurf, Zed, Cline, Continue and others), in its MCP config file:

{
  "mcpServers": {
    "package-truth": {
      "command": "npx",
      "args": [
        "-y",
        "package-truth-mcp"
      ]
    }
  }
}

Docker

docker build -t package-truth-mcp https://github.com/arhancanli/package-truth-mcp.git && docker run -i --rm package-truth-mcp

Hosted (Streamable HTTP): node src/server.mjs --http serves stateless MCP at POST /mcp (port from PORT, default 3000).

Related MCP server: pkg-oracle

Example

An agent calls check_packages with:

{
  "ecosystem": "npm",
  "packages": [
    {
      "name": "express"
    },
    {
      "name": "request"
    },
    {
      "name": "express",
      "version": "4.17.1"
    },
    {
      "name": "express",
      "version": "99.0.0"
    },
    {
      "name": "left-pad-hallucinated-zz9"
    }
  ]
}

and gets back (recorded from the live server on 2026-09-26):

{
  "ecosystem": "npm",
  "counts": {
    "does_not_exist": 2,
    "risky": 2,
    "verify": 0,
    "ok": 1
  },
  "results": [
    {
      "name": "express",
      "version": "99.0.0",
      "latest": "5.2.1",
      "verdict": "does_not_exist",
      "flags": [
        "version_not_found"
      ],
      "note": "Version 99.0.0 was never published. The latest is 5.2.1."
    },
    {
      "name": "left-pad-hallucinated-zz9",
      "verdict": "does_not_exist",
      "flags": [
        "not_found"
      ],
      "note": "The registry has no package with this name. It may be misspelled or hallucinated; do not install it."
    },
    {
      "name": "request",
      "version": "2.88.2",
      "latest": "2.88.2",
      "verdict": "risky",
      "flags": [
        "deprecated",
        "vulnerable",
        "no_release_in_3_years"
      ],
      "deprecated_reason": "request has been deprecated, see https://github.com/request/request/issues/3142",
      "advisories": [
        "GHSA-p8p7-x288-28g6"
      ],
      "license": "Apache-2.0",
      "first_published": "2011-01-22",
      "latest_published": "2020-02-11",
      "version_count": 126
    },
    {
      "name": "express",
      "version": "4.17.1",
      "latest": "5.2.1",
      "verdict": "risky",
      "flags": [
        "vulnerable"
      ],
      "advisories": [
        "GHSA-qw6h-vgh9-j6wx",
        "GHSA-rv95-896h-c2vc"
      ],
      "latest_advisory_count": 0,
      "license": "MIT",
... (16 more lines)

Tools

Tool

What it does

check_manifest

Checks every dependency in a manifest file's text (package.json, requirements*.txt, pyproject.toml, Cargo.toml, go.mod, Gemfile, *.csproj, pom.xml). Pinned versions are checked exactly; ranges at the version an install would pick today. Problems are listed first.

check_packages

Checks up to 100 packages in one registry: exists, latest version, deprecated, known advisories, licence, age. Verdict each: does_not_exist, risky, verify (new or tiny: possible squat) or ok. Omit version for the latest.

get_advisories

Lists the known security advisories for one package version (latest if omitted): id, title, CVE aliases, CVSS 3 score and link, plus how many affect the latest version.

How it behaves

  • Read-only: no tool changes anything outside this process. Manifests are parsed as text; nothing in them is executed or fetched.

  • Ranges are resolved like the package manager would (npm and Cargo caret, tilde, x and hyphen ranges; PyPI specifiers including ~= and ==1.2.*; RubyGems ~>). Prereleases are never picked. Maven and NuGet ranges are checked at the latest version and flagged as such.

  • Network: HTTPS only, to the hosts listed in package.json under factory.allowHosts, with a deadline, a size cap and bounded retries. Nothing else is contacted, and nothing is logged except unexpected failures (to stderr, without your inputs).

  • Results are compact JSON with a matching output schema. Lists say how many items were left out.

Benchmark

Measured 2026-09-26 with gpt-5.4-mini, 10 fixed tasks graded by fixed checks (bench/tasks.json, raw results in bench/results/).

Server

Correct

Input tokens

Output tokens

Tool calls

Median time

This server

10/10

13226

545

10

3.3 s

package-version-check-mcp, the best maintained alternative

7/10

28734

531

10

2.9 s

Performance

Measured 2026-09-26 from Dubai, home connection against the live upstream, Node 24.19.0 (bench/perf.json, scripts/perf.mjs in the factory).

Call

First call

Repeat

Result size

check_packages: 5 npm packages (missing, deprecated, vulnerable, clean)

1556 ms

1.1 ms

1,290 chars

check_packages: 1 PyPI package

1358 ms

0.4 ms

455 chars

check_packages: 1 Go module

1721 ms

1.9 ms

277 chars

check_manifest: package.json, 5 entries

1779 ms

4.4 ms

1,270 chars

check_manifest: requirements.txt, 4 lines

1526 ms

0.8 ms

926 chars

get_advisories: express 4.17.1

2137 ms

0.3 ms

462 chars

First call: a fresh server process, including the TLS connection and the upstream's own time. Repeat: the same call again, answered from the in-process cache, so it shows this server's own overhead.

Tool definitions the model reads on every turn (name, description, input schema): 1,806 characters, against 5,496 for package-version-check-mcp, the best maintained alternative. The full tool list, with the output schemas and annotations clients use to validate results, is 3,899 characters (8,487 for the alternative).

More MCP servers by Arhan Canli

  • End of Life: Is this version still supported? EOL dates, latest patch and upgrade target for 470+ products.

  • Internet Standards: RFC sections, status, obsoleted-by chains, errata and IANA registries for coding agents.

  • Citation Check: Verifies citations: finds fabricated or mismatched references and retractions, returns clean BibTeX.

  • Drug Label: FDA drug label answers with section citations, RxNorm name resolution, recalls and shortages.

  • Recall Check: One recall check across CPSC, FDA and NHTSA: match by name, model number, UPC or VIN.

  • Satellite Imagery: Find the clearest Sentinel-2, Landsat, Sentinel-1 or NAIP scene for any place, with band links.

  • The whole collection

License

MIT, Copyright (c) 2026 Arhan Canli.

Available Tools

3 tools
check_manifestCheck a dependency manifestA
Read-onlyIdempotent

Checks every dependency in a manifest file's text (package.json, requirements*.txt, pyproject.toml, Cargo.toml, go.mod, Gemfile, *.csproj, pom.xml). Pinned versions are checked exactly; ranges at the version an install would pick today. Problems are listed first.

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesThe file's full text
filenameYesFile name, e.g. package.json

Output Schema

ParametersJSON Schema
NameRequiredDescription
countsYes
resultsYes
skippedNo
ecosystemYes
truncatedNo

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare read-only, open-world, idempotent, and non-destructive behavior, so the description need not restate those. It adds useful behavioral detail beyond annotations: exact pins are checked exactly, ranges are resolved to today's install-pick version, and problems are listed first.

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

Conciseness5/5

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

Two tight, front-loaded sentences: the first names the action and scope, the second states version-resolution semantics and output ordering. Every sentence earns its place with no filler or repetition of the schema.

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

Completeness5/5

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

For a two-parameter read-only tool with a 100%-documented schema, rich annotations, and an output schema, the description provides everything needed to call it correctly: input expectations, version-checking semantics, scope, and result ordering. No critical behavioral gap remains.

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, but the description adds value by listing the accepted manifest filename patterns (package.json, requirements*.txt, pyproject.toml, etc.) and clarifying that content is the full file text. This goes beyond the schema's generic 'e.g. package.json' example.

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 description clearly states the tool checks every dependency in a manifest file's text and enumerates supported manifest formats, giving a specific verb and resource. It does not explicitly distinguish itself from the sibling check_packages, though the 'manifest file's text' framing makes the scope inferable.

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

Usage Guidelines2/5

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

There is no explicit guidance about when to use this tool versus get_advisories or check_packages. The supported-format list implies it is for manifest-file inputs, but no alternative is named or excluded, leaving the agent to infer the decision.

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

check_packagesCheck packages before installingA
Read-onlyIdempotent

Checks up to 100 packages in one registry: exists, latest version, deprecated, known advisories, licence, age. Verdict each: does_not_exist, risky, verify (new or tiny: possible squat) or ok. Omit version for the latest.

ParametersJSON Schema
NameRequiredDescriptionDefault
packagesYes
ecosystemYesRegistry

Output Schema

ParametersJSON Schema
NameRequiredDescription
countsYes
resultsYes
ecosystemYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds valuable behavioral context beyond these: the 100-package limit, the specific checks performed, the verdict categories, and the version-omission behavior. No contradiction with annotations.

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

Conciseness5/5

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

The description is two sentences with no filler. It front-loads the core action and scope, then lists verdicts, and ends with a concise parameter tip. Every sentence 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?

Given the annotations, output schema, and the description's coverage of limits, verdicts, and version behavior, the tool is sufficiently specified for an agent to invoke correctly. The only notable gap is the lack of explicit routing guidance relative to sibling tools, but this does not block correct usage.

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 description coverage is only 50%, with only ecosystem described as 'Registry.' The description compensates by clarifying that packages are checked for existence, latest version, deprecation, advisories, licence, and age, and by explaining that omitting version checks the latest. This adds meaning beyond the raw schema.

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 description clearly states a specific action ('Checks up to 100 packages in one registry') and enumerates the checks performed and verdicts returned. It is easy to understand what the tool does, though it does not explicitly differentiate itself from sibling tools like check_manifest or get_advisories.

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 title 'Check packages before installing' implies when the tool should be used, and the description adds operational guidance like 'Omit version for the latest.' However, there is no explicit statement of when to prefer this tool over siblings or when not to use it.

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

get_advisoriesAdvisories for a package versionA
Read-onlyIdempotent

Lists the known security advisories for one package version (latest if omitted): id, title, CVE aliases, CVSS 3 score and link, plus how many affect the latest version.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
versionNo
ecosystemYesRegistry

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
latestYes
versionYes
advisoriesYes
latest_advisory_countYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description only needs to add behavioral context. It does so by stating the version default ('latest if omitted') and enumerating the response contents, including advisory metadata and the count affecting the latest version. No contradiction with annotations is present.

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

Conciseness5/5

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

The description is a single sentence that packs in the action, scope, default behavior, and output contents without filler. Every clause earns its place and the most important scoping detail appears early.

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?

The output schema exists, so return-value details are already structured, and annotations cover the safety profile. The description adds the key usage nuance (version defaults to latest) and the advisory fields returned. A minor gap is that it does not explicitly distinguish when this tool should be preferred over check_manifest or check_packages, but the overall definition is sufficient for correct invocation.

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 only 33%, so the description carries some burden for parameter meaning. It adds genuinely useful semantics for the version parameter ('latest if omitted') and describes output fields, but it does not clarify the meaning of name or ecosystem beyond what the schema's enum and property name already imply. This is partial compensation rather than full coverage.

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?

The description uses a specific verb ('Lists') with a clear resource ('known security advisories') and scopes it to one package version, defaulting to latest when omitted. It also enumerates the returned fields, making its purpose distinct from the sibling tools, which appear to target manifest or package checks.

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 description clearly conveys when the tool applies: when a caller needs security advisories for a specific package version, with latest as the default. It does not explicitly state when not to use it or name alternatives, but the context is strong enough for an agent to select it correctly.

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. 3 tool updatesv0.1.0
    • First observedcheck_manifest
    • First observedcheck_packages
    • First observedget_advisories

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation4/5

The three tools are clearly distinct: check_manifest validates dependency files, get_advisories provides detailed advisory info for a specific package version, and check_packages performs bulk registry checks. While both check_manifest and check_packages can surface advisories, their inputs and purposes differ (file text vs. registry list), so ambiguity is minimal.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with snake_case: check_manifest, get_advisories, check_packages. The verbs (check, get) are descriptive and the nouns (manifest, advisories, packages) clearly indicate the target.

Tool Count5/5

Three tools is ideal for the server's focused purpose of package verification and security. Each tool serves a distinct need (manifest scanning, bulk checking, advisory lookup) without unnecessary overlap or bloat.

Completeness5/5

The server covers the core domain comprehensively: manifest validation, bulk package checks (existence, latest, deprecated, advisories, license, age), and detailed advisory queries. For a read-only package truth service, there are no obvious missing operations or dead ends.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables users to look up package versions, scan for vulnerabilities, and analyze dependencies across multiple registries (npm, Maven, PyPI, etc.) using exact version recommendations for security.
    4
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that verifies npm and PyPI packages before installation, checking for existence, known vulnerabilities, OpenSSF scorecard, and typosquatting, returning an ALLOW/WARN/BLOCK verdict.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to automatically verify npm packages against the live registry before installation, flagging hallucinated, slopsquatted, or otherwise suspicious packages with risk verdicts.
    7 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI coding agents and CI to vet npm dependencies before they reach the lockfile, flagging hallucinated, slopsquatted, or otherwise risky packages with evidence-backed verdicts.
    3
    48 npm
    4
    MIT