Local-first supply-chain security gate for npm/pnpm/bun: typosquat, release age, provenance checks
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
SafeInstall
Supply-chain security for the AI-agent era.
The install gate for npm, pnpm, and bun β for the humans who type install, the AI agents that run it for them, and the config that programs those agents.
Policy runs first. Then your package manager. Not the other way around.
Local-first Β· No cloud Β· No account Β· MIT Β· Free forever
SafeInstall runs your policy before your package manager β locally, blocking by default. One tool, three layers of defense:
safeinstall pnpm add axios. Policy runs, then pnpm. Release age, install scripts, untrusted sources, typo-squats, and cryptographic provenance are checked before anything touches disk.AI coding tools suggest packages in seconds. They don't check publish dates. They don't read install scripts. They don't verify the source. You type "yes" and move on.
SafeInstall is the gate between suggestion and execution.
No dashboard. No account. No cloud. One command prefix β policy runs locally, blocks by default, then invokes the real tool.
A valid Sigstore signature is not enough. An attacker who compromises an npm maintainer account can publish a malicious version of a package you already trust, and the attestation on that malicious version will cryptographically verify β signed by a GitHub Actions workflow the attacker controls in a fork of the real repository.
SafeInstall catches this. Pin the expected source repository with provenance.trustedPublishers and any build that comes from anywhere else is blocked, even if the signature is valid:
This is the only check of its kind in an install-time policy gate. CVE scanners look for known vulnerabilities. Content analyzers look for suspicious code. SafeInstall enforces that the cryptographic chain of trust points at the repository you agreed to trust β and refuses anything else, no matter how legitimate it looks.
SafeInstall itself is published with a Sigstore attestation. You can eat your own dog food: enable provenance verification, pin safeinstall-cli to Mickdownunder/SafeInstall, and watch SafeInstall verify its own trust chain against the public Sigstore transparency log.
Node.js >=20 Β· macOS, Linux, Windows Β· Command:
safeinstall
No registry proxy. No tarball rewriting. No cloud dependency.
| Rule | Default | Block message |
|---|---|---|
| Release age | 72 hours minimum | Blocked: release too new |
| Lifecycle scripts | preinstall, install, postinstall blocked | Blocked: install script present |
| Source types | registry, workspace, file, directory allowed | Blocked: untrusted source |
| Trust downgrade | Detects registryβgit/url or new scripts on update | Blocked: trust level dropped |
| Typo-squat detection | Off by default; opt in via typoSquat.mode | Blocked: suspected typo-squat |
| Provenance verification | Off by default; opt in via provenance.mode | Blocked: attestation missing/invalid/publisher mismatch |
| Transitive dependencies | Off by default; opt in via transitive.mode | Blocked: transitive install script / untrusted source |
| Provenance continuity | Off by default; opt in via continuity.mode | Blocked: provenance downgrade / identity discontinuity |
All rules are configurable. Ambiguous or incomplete metadata blocks instead of allowing.
This is SafeInstall's most distinctive check, and the one no other consumer-side tool does. npm verifies provenance at publish time and binds a package to a source repository β but it does not enforce continuity between versions. A compromised maintainer account can publish a new version with no attestation (from a stolen token), or from a different repository, and npm raises no alarm. This is the signature of the 2026 attack wave (Mastra, the dormant-account republishes).
Continuity learns a per-package trust baseline from the provenance identity of recent versions, then blocks deviations:
provenance-downgrade β recent versions were attested, this one isn't. The fingerprint of an account-compromise publish from a personal token. (This is the Mastra case.)identity-discontinuity β this version is attested from a different source repository than the established baseline.Because the baseline is learned per package, there are no false positives on the large majority of packages that never adopted provenance β they simply have no baseline and the check stays silent. No global "require provenance" sledgehammer.
It reads npm's published attestation metadata, so it works without the optional sigstore package. Opt in with continuity.mode set to "warn" or "block".
Honest limit: continuity does not catch an attack that comes through a legitimately-compromised CI workflow with valid provenance from the real repository (e.g. the Shai-Hulud worm class). There is no identity discontinuity to detect there. SafeInstall raises the bar against the dominant 2026 attack pattern; it does not close every door.
By default SafeInstall evaluates direct dependencies. Most supply-chain attacks, though, reach you through a transitive dependency β a package you never chose, pulled in several levels deep. Enable transitive mode to walk the full lockfile tree.
Two checks run transitively, both read directly from the lockfile with zero extra registry calls:
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/safeinstall)<a href="https://allmcps.com/mcp/safeinstall"><img src="https://allmcps.com/api/badge/safeinstall?style=directory" alt="Safeinstall on AllMCPs" /></a>