Skip to main content

pkgguard

Vet the packages and repos your AI assistant recommended — before you install them.

CI PyPI Python License: MIT No API key Ecosystems


Your AI coding assistant just gave you a pip install line or a list of "recommended libraries." Some of those names don't exist. Some are one keystroke away from a popular package. Some are real but AGPL-licensed, abandoned, riddled with CVEs, or propped up by bought stars. Installing them is how modern supply-chain attacks start.

pkgguard checks every name in one command and tells you which are safe — across PyPI, npm, crates.io, Go, RubyGems, Packagist, NuGet and pub.dev — with no API key and without executing a single line of the packages it inspects.

$ pkgguard requests reqeusts beautifulsoup-4 django==3.0.0 super-fake-pkg-zzz

      ✅ OK      requests           Exists on PyPI · 1.6B downloads/mo · Apache-2.0
      ⚠️ WARN    django             31 known CVEs in 3.0.0 — upgrade
      ❌ DANGER  reqeusts           Resembles 'requests' but does not exist — slopsquat bait
      ❌ DANGER  beautifulsoup-4    Hallucination — real package is 'beautifulsoup4'
      ❌ DANGER  super-fake-pkg-zzz Not found on PyPI or npm — likely invented

1 ok  1 warn  3 danger  0 unknown          # exit code 2 → fails your CI

Existing tools (Snyk, Socket, OSV) scan dependencies you've already chosen. pkgguard answers the newer, earlier question: "the thing the LLM just told me to install — is it even real, and should I trust it?"


🩸 Why this matters: the slopsquatting epidemic

LLMs invent package names. A peer-reviewed USENIX Security 2025 study generated 2.23M code samples and found:

  • 19.7% of AI-generated samples referenced a package that does not exist (up to ~33% for some models).
  • When the same prompt was repeated, 43% of hallucinated names appeared every single time — they are predictable.

That predictability is the attack. An adversary asks an LLM what it hallucinates, pre-registers those exact names on PyPI/npm with malware inside, and waits for the next developer to copy-paste the assistant's answer into a terminal. Security researchers named it slopsquatting, and it is already happening in the wild.

As AI assistants become the default way developers discover dependencies, the moment an AI hands you a package list is now a front-line security boundary. pkgguard guards exactly that moment.


⚡ What it checks

Every package/repo runs through an ordered pipeline of 11 checks. The worst finding sets the verdict, so a single command gives you one clear answer per item.

Check What it catches
Existence Names that don't exist on any registry — the core hallucination / slopsquat signal
Typosquat + homoglyph 1–2 edits from a popular package (reqeustsrequests) and digit/letter look-alikes (dj4ng0django)
Known vulnerabilities Open CVEs/advisories for the resolved version via OSV.dev (GHSA / PyPA / RustSec / RubySec…)
Source malware scan (opt-in --scan) Statically inspects the package archive for install-time code execution, obfuscated payloads, child_process/os.system, credential access — without ever running it
License traps AGPL / SSPL / BUSL / CC-BY-NC / fair-code / "no license" — and custom / NOASSERTION non-commercial licenses (reads the raw LICENSE text; common for AI model repos). Detects restrictions in 25 languages, not just English — see below
Maintenance Archived, disabled, deprecated, or long-abandoned projects
Popularity Download counts as a legitimacy signal
Fake stars (opt-in --deep) Star-count inflation — with reputable-owner / real-adoption suppression so normal viral growth isn't flagged
Purpose / policy (opt-in --policy) Tools whose purpose is ToS-abuse/attack (account farms, bypass, DDoS) — a heuristic lens, backs off for defensive/detection tooling
Repo health GitHub stars / last commit / license / archived state for the upstream repo
Malware metadata npm install scripts, freshly-registered look-alikes, packages with no auditable source

Supported ecosystems: PyPI · npm · crates.io · Go modules · RubyGems · Packagist · NuGet · pub.dev — plus GitHub repos.


🌍 License checks work in 25 languages

Open source is global; LICENSE files are not always in English. GitHub's classifier returns NOASSERTION for a hand-written license in Korean, Spanish or Russian — and an English-only scanner then reads that as "unclassifiable" and passes it as ✅. That is the worst possible outcome for a tool whose whole job is answering "can I use this commercially?".

A real example: a Korean LICENSE that explicitly bans resale and paid-service bundling graded ✅ OK before v0.2.0.

⚠️  WARN  lbiz-partners/hometax-doum
    License trap: custom / restrictive (non-commercial signals)
    GitHub couldn't classify the license (SPDX=NOASSERTION), but the LICENSE
    (written in Korean) contains restrictive terms — likely non-commercial /
    research-only, unsafe for a commercial product without a separate license.
    Evidence: "...유지한 비상업적 공유 (링크 공유 권장) ## 금지 - 본 스킬 모음 또는 그 수정본의 재판매,..."

Supported: Arabic, Chinese, Czech, Dutch, English, French, German, Greek, Hebrew, Hindi, Indonesian, Italian, Japanese, Korean, Persian, Polish, Portuguese, Romanian, Russian, Spanish, Swedish, Thai, Turkish, Ukrainian, Vietnamese.

How it works. Word order is the real problem, not vocabulary. Korean lists the prohibited acts first and negates once at the end; German splits the verb; Arabic and Hebrew read right-to-left. So instead of matching phrases, pkgguard looks for two concepts co-occurring in a short window — a commercial-use term and a prohibition term, in either order. Adding a language means adding two short word lists, not encoding its grammar.

It also catches gated commercial use ("commercial use requires a separate license"), which is legally a gate rather than a ban but answers "can I ship this for free today?" the same way.

On false positives. Calling MIT non-commercial would be worse than missing a restriction — it trains you to ignore ⚠️. Every language ships a paired test asserting its permissive phrasing is not flagged ("상업적 이용을 허용합니다", "Die kommerzielle Nutzung ist gestattet", …), and the suite is validated against the real LICENSE files of React, Kubernetes, Rust, Django, PyTorch and others: 0 false positives.

Findings are written in English. The detection is multilingual; the report is not yet localised. If you'd like localised output, open an issue — it is a deliberate scope call, not an oversight.

📦 Install

pip install pkgguard-cli            # core — zero dependencies, no API key
pip install "pkgguard-cli[rich]"    # + prettier coloured tables
pip install "pkgguard-cli[mcp]"     # + MCP server for AI assistants

The PyPI distribution is pkgguard-cli; the command it installs is pkgguard. Requires Python 3.9+. The core engine is stdlib-only.

🚀 Quick start

# a few names
pkgguard requests numpy pandas

# a manifest — auto-detected: requirements.txt, package.json, Cargo.toml, Gemfile, go.mod
pkgguard requirements.txt
pkgguard package.json Cargo.toml          # several at once

# 🌟 the headline trick: paste whatever ChatGPT / Claude told you
pkgguard --stdin < chat.txt
pbpaste | pkgguard --stdin                # macOS

# go deeper
pkgguard requirements.txt --scan          # download + statically scan source
pkgguard some/repo --deep                 # add fake-star analysis
pkgguard some/repo --policy               # flag abuse/attack-purpose tools

pkgguard mines free text for pip install … / npm i … commands, GitHub links, inline `code spans` and bullet lists — and is careful not to flag plain English prose as packages. Names whose ecosystem isn't stated are checked against both PyPI and npm.

Machine-readable output & CI

pkgguard -f requirements.txt --json               # JSON to stdout
pkgguard -f requirements.txt --markdown -o report.md
pkgguard -f requirements.txt --fail-on warn       # non-zero exit gates your pipeline

Exit codes: 0 clean · 1 a warning (--fail-on warn) · 2 a danger.


🔌 Integrations

pre-commit hook
# .pre-commit-config.yaml
- repo: https://github.com/Highcrypto7/pkgguard
  rev: v0.1.0
  hooks:
    - id: pkgguard          # auto-runs on requirements*.txt and package.json
GitHub Action
# .github/workflows/pkgguard.yml
- uses: Highcrypto7/pkgguard@v1
  with:
    files: "requirements.txt package.json"
    fail-on: danger

🤖 Use it through your AI assistant (MCP)

The highest-leverage way to run pkgguard is to not run it yourself. Register the MCP server and the assistant vets a package before it ever recommends it — slopsquatting stops at the source instead of at your terminal.

pip install "pkgguard-cli[mcp]"

Then add it to your assistant's MCP config:

Claude Codeclaude mcp add pkgguard -- pkgguard-mcp

Claude Desktop (claude_desktop_config.json) / Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "pkgguard": {
      "command": "pkgguard-mcp"
    }
  }
}

Two tools are exposed:

Tool Use
vet_packages(text) Pass names, a requirements.txt / package.json body, or free text — including the assistant's own draft answer. Returns a verdict per item with reasons.
is_safe_to_install(name) Fast yes/no gate for one package or owner/repo.

A useful standing instruction for your agent:

Before recommending or installing any package, call pkgguard. Do not suggest anything that comes back danger, and surface the reason for anything warn.

It is language-neutral on input. Paste an assistant's answer in any language — the parser reads structure (install commands, owner/repo slugs, code spans, bullet lists), not English prose, so nothing is lost in Korean, Japanese, Spanish, Russian or Arabic, and prose words don't leak in as fake package names:

> 웹 스크래핑에는 requests를 쓰세요:
>   pip install requests
> 3D 좌석 시야는 github.com/thebuggeddev/football-stadium 참고하세요.

⚠️ WARN  thebuggeddev/football-stadium  License trap: custom / restrictive
   … the LICENSE contains restrictive terms — unsafe for a commercial product
✅ OK    requests                        Exists on PyPI (latest 2.34.2)

🥊 How it compares

Other tools are excellent at scanning dependencies you've already chosen. pkgguard is the fast first gate at the moment an AI (or a teammate) hands you a list.

pkgguard sloppy-joe depscope GuardDog Snyk / Socket
Hallucination / existence ~
Typosquat + homoglyph ~ ~
Known CVEs (OSV)
Static source malware scan
License traps (AGPL / NC / …) ~
Maintenance / dead repo ~ ~
Fake-star inflation
Paste a chat answer (free text)
MCP self-check for assistants
Ecosystems 8 2 19 5 many
Open source · No key · Offline-degraded partial

pkgguard's edge: the widest set of checks in a single zero-key OSS gate, framed around AI output — including license and fake-star checks the others skip, and a "paste the chat answer" workflow nobody else has. Honest gap: GuardDog/Snyk/Socket do deeper source-level malware analysis; run them alongside pkgguard for defence in depth.


📊 Proof

  • Benchmark: 100% accuracy on a labeled set of 30 PyPI/npm packages (15 real, 15 hallucinated/typosquat). Reproduce: python benchmark/run_benchmark.py. See BENCHMARK.md.
  • Zero false positives when vetting the 50 most popular real PyPI/npm packages.
  • 67 automated tests, deterministic and offline.

🧭 Verdicts

  • OK — exists and nothing concerning found.
  • ⚠️ WARN — usable, but read the caveat (license, CVE, staleness, look-alike…).
  • DANGER — doesn't exist, or a strong risk signal. Don't install without verifying.
  • UNKNOWN — couldn't determine (offline / rate-limited). Honest about what it didn't check.

🔐 Design principles

  • No API key, ever. Public registry/GitHub metadata over HTTPS. Set GITHUB_TOKEN only to raise rate limits.
  • No code execution. The source scan parses with ast and pattern-matching; it never imports or runs package code, and extracts archives in-memory with strict size/path guards.
  • Honest by default. "Couldn't check" is ❔, never a silent ✅.
  • Fast & offline-friendly. On-disk response cache; a previous run answers even with no network.

⚠️ Limitations

  • Heuristics, not proof. A ✅ means "no red flags found," not a security guarantee.
  • The typosquat reference list is a curated set of popular packages, not all of every registry.
  • Fake-star and source-scan checks are opt-in and intentionally conservative — they complement, not replace, dedicated tools (StarScout, GuardDog).
  • Unauthenticated GitHub is limited to ~60 requests/hour; set GITHUB_TOKEN for large runs.

🗺️ Roadmap

  • More ecosystems (Maven, Hex, CPAN)
  • Large-scale benchmark against the trendmicro/slopsquatting dataset
  • VS Code extension
  • Deeper static source analysis

🤝 Contributing

Issues and PRs welcome — a new ecosystem is just a registry adapter, and a new check is a single module (see src/pkgguard/checks/). Run pytest before submitting.

📄 License

MIT — see LICENSE. Built to make the AI coding era a little safer.

Release files for pkgguard-cli 0.2.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 pkgguard-cli 0.2.1
File Size Uploaded
pkgguard_cli-0.2.1.tar.gz 85.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pkgguard-cli 0.2.1
File Interpreter ABI Platform
pkgguard_cli-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 170.4 kB

Release files / pkgguard_cli-0.2.1.tar.gz

Download URL pkgguard_cli-0.2.1.tar.gz
Size 85.6 kB
Tags Source
SHA-256 checksum
How to use checksums
cfd63e5313020a3f31f9298d1889c02eb2ebac20b973403ba094f88efbc914b4
BLAKE2b-256 checksum
How to use checksums
1bc0193160bd900e27b02bf47c491e0cc6320625f13f496b0d16153160bac0a4
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 27, 2026.

Transparency log

Release files / pkgguard_cli-0.2.1-py3-none-any.whl

Download URL pkgguard_cli-0.2.1-py3-none-any.whl
Size 84.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3ad35c93566585d709c5dd5864b3d38a19eaf0a22241e1c50f6e26ea7257d4df
BLAKE2b-256 checksum
How to use checksums
d51c9b7628905c80c60f9955ad8b9c835f0477dd76e3f4799333f560d6c4221e
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 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

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