Npmguard について
Npmguardは、インストール前にnpmパッケージを検査するRust製コマンドラインツール兼MCPサーバーです。開発者やコーディングエージェント向けに、リスク評価とClaude Codeのフックによるコマンド実行前の制御を提供します。
主な機能
- 01インストール前のリスク評価
- 02OSVのマルウェアと名前詐称の検査
- 03インストールスクリプトの分析
- 04テキストまたはJSONでの判定
- 05Claude Codeのコマンドフック
活用シーン
- 01npmパッケージの導入前チェック
- 02Claude Codeによる不審な導入の遮断
- 03CIでのパッケージ判定の確認
- 04コーディングエージェントからの構造化チェック
MCP 対応
MCPサーバーは `install_package` ツールを公開し、npmパッケージの構造化されたリスク判定を返します。MCPホストとはstdioで通信します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
npmguard
AIを自動モードで動かし、好きなものをインストールさせているバイブコーダーがあまりにも多いのは驚くほどです。そのため、インストールスクリプトが1つでも実行される前にチェックできるよう、これを作りました。
Claude Code、Cursor、Codexは自律的にnpm installを実行します。「ちょっと待って、supabase-mcp-helperって本当に存在するの?」と確認する人はいません。そこで、すべてのパッケージを評価し(OSVのマルウェアデータ、タイポスクワッティング/スロップスクワッティング、インストールスクリプトの分析)、ライフサイクルスクリプトが実行される前に判定を返すMCP サーバー兼CLIとしてnpmguardを作りました。
npmの外部で動作する単一のRustバイナリとして提供されます。これが重要です。ゲートが、守ろうとしているサプライチェーンによって汚染されることはありません。

npmguard install lodahsは、lodashの実在するタイポスクワットであり、ライフサイクルスクリプトが実行される前に拒否されます。

GIFまたはMP4でもご覧いただけます。npmレジストリに対するライブ判定です。lodahsはOSVのマルウェア名前空間(MAL-2025-25502)に登録されています。テーマ:atlas-ragnarok。sh docs/_theme/gen.shで再生成できます(vhs、ffmpeg、webp、pillow、numpyが必要です)。
理由
2025年から2026年にかけて、npmエコシステムはワーム型のサプライチェーン攻撃に相次いで見舞われました。Shai-Hulud(2025年9月)、SHA1-Hulud(2025年11月)、Axiosの侵害(2026年3月)、Mini Shai-Hulud(2026年5月)です。いずれも、誰かがnpm installを実行した瞬間にpreinstall/install/postinstallスクリプト内で実行されました。勝敗はインストール完了後ではなく、その前に決まります。
既存のツールでは、私が気づいていたギャップを埋められません。
npq、safe-npm/socket npm、npm-riskはnpmパッケージとして提供されています。保護するはずのものそのものの上で動作します。ラッパーが侵害されたら、状況をさらに悪化させてしまいます。pnpm v10+、Bunはデフォルトでライフサイクルスクリプトを無効にしますが、それはすでにnpmから移行している場合に限られます。npmを使うユーザーの大半は、依然としてリスクにさらされています。- **
npm audit、Snyk、Dependabot、lavamoat/allow-scripts**は、CVEスキャンや許可リスト管理をうまく行います。一方で、プリインストール時のヒューリスティックなゲートとして機能することはなく、Claude Code、Cursor、CodexなどのAIコーディングアシスタントがユーザーに代わってnpm installを実行する際に、それを遮断できるものもありません。
私が解決したかったのは、まさに最後の点です。**AIエージェントにもゲートを設ける、インストール前のリスク評価を、npmの外部で動作する単一のバイナリとして提供することです。**照会先のレジストリ以外には、実行時依存関係はありません。
インストール
macOS(Apple Silicon、aarch64)
curl -L -o npmguard.tar.gz \
https://github.com/AyoubTadlaoui/npmguard/releases/latest/download/npmguard-v0.1.8-aarch64-apple-darwin.tar.gz
tar -xzf npmguard.tar.gz
# Edit the directory name below if the version has changed.
sudo mv npmguard-v0.1.8-aarch64-apple-darwin/npmguard-cli /usr/local/bin/npmguard
sudo mv npmguard-v0.1.8-aarch64-apple-darwin/npmguard-mcp /usr/local/bin/npmguard-mcp
隔離属性について:
curlではなくブラウザーからダウンロードした場合、macOS がバイナリを信頼できないものとして判定することがあります("cannot be opened…"またはKilled: 9)。展開後に属性を削除してください。xattr -dr com.apple.quarantine /usr/local/bin/npmguard /usr/local/bin/npmguard-mcp上記の
curlを使う方法では隔離フラグは設定されません。
macOS(Intel、x86_64)
curl -L -o npmguard.tar.gz \
https://github.com/AyoubTadlaoui/npmguard/releases/latest/download/npmguard-v0.1.8-x86_64-apple-darwin.tar.gz
tar -xzf npmguard.tar.gz
# Edit the directory name below if the version has changed.
sudo mv npmguard-v0.1.8-x86_64-apple-darwin/npmguard-cli /usr/local/bin/npmguard
sudo mv npmguard-v0.1.8-x86_64-apple-darwin/npmguard-mcp /usr/local/bin/npmguard-mcp
Linux(x86_64)
curl -L -o npmguard.tar.gz \
https://github.com/AyoubTadlaoui/npmguard/releases/latest/download/npmguard-v0.1.8-x86_64-unknown-linux-gnu.tar.gz
tar -xzf npmguard.tar.gz
# Edit the directory name below if the version has changed.
sudo mv npmguard-v0.1.8-x86_64-unknown-linux-gnu/npmguard-cli /usr/local/bin/npmguard
sudo mv npmguard-v0.1.8-x86_64-unknown-linux-gnu/npmguard-mcp /usr/local/bin/npmguard-mcp
Linux(aarch64)
curl -L -o npmguard.tar.gz \
https://github.com/AyoubTadlaoui/npmguard/releases/latest/download/npmguard-v0.1.8-aarch64-unknown-linux-gnu.tar.gz
tar -xzf npmguard.tar.gz
# Edit the directory name below if the version has changed.
sudo mv npmguard-v0.1.8-aarch64-unknown-linux-gnu/npmguard-cli /usr/local/bin/npmguard
sudo mv npmguard-v0.1.8-aarch64-unknown-linux-gnu/npmguard-mcp /usr/local/bin/npmguard-mcp
Windows(x86_64)
次の場所から zip をダウンロードします。
https://github.com/AyoubTadlaoui/npmguard/releases/latest/download/npmguard-v0.1.8-x86_64-pc-windows-msvc.zip
展開して、npmguard-cli.exe と npmguard-mcp.exe を %PATH% 内の場所(例:C:\tools\)に配置します。
特定のリリースを使う場合は、上記 URL のバージョン文字列を編集してください。
ソースからビルド(Rust ユーザー向け)
Rust 1.75 以降が必要です。
cargo install --git https://github.com/AyoubTadlaoui/npmguard --bin npmguard-cli
cargo install --git https://github.com/AyoubTadlaoui/npmguard --bin npmguard-mcp
インストール後、CLI バイナリの名前は npmguard-cli です。npmguard にしたい場合はエイリアスを設定してください。
# bash / zsh
echo 'alias npmguard=npmguard-cli' >> ~/.bashrc # or ~/.zshrc
展開する前に、公開されているチェックサムと照合してダウンロードを検証してください。
# Replace the filename to match your platform.
shasum -a 256 -c <(grep npmguard-v0.1.8-aarch64-apple-darwin.tar.gz SHA256SUMS.txt)
ビルド済みバイナリはすべてリリースページに掲載されています。Homebrew tap、Scoop bucket、curl … | sh インストーラーは、サンドボックスレイヤーとともに v0.2 で追加されます。
Docker(npmguard-mcp のみ)
docker pull ghcr.io/ayoubtadlaoui/npmguard-mcp:latest
docker run --rm -i ghcr.io/ayoubtadlaoui/npmguard-mcp:latest
Docker イメージは主に MCP カタログと CI 向けです。ローカルで使用する場合は、ネイティブバイナリをインストールしてください。このイメージに含まれるのは npmguard-mcp のみ(CLI は含まれません)で、非 root ユーザーとして実行され、ポートは公開されません。MCP ホストは標準入出力を介して通信します。
クイックスタート:CLI
# Evaluate the latest version, no install.
npmguard check axios
# Pinned version, JSON output (machine-readable for CI).
npmguard check --json @ctrl/[email protected]
# Install path: v0.1 prints the verdict and stops; v0.2 will run `npm install`
# inside the sandbox layer if the verdict allows it.
npmguard install [email protected]
# Auto-accept warn-level (still refuses block-level).
npmguard install --yes some-fresh-package
レジストリに対する実際の判定結果のサンプル出力です。
npmguard [email protected] → score 115 / 200 (block, thresholds warn=30 block=70)
10 pts SoleMaintainer single maintainer: adam_baldwin
25 pts Typosquat name 'lodahs' is 1 edit away from popular package 'lodash'
80 pts KnownCve 1 CONFIRMED MALICIOUS by OSV for this version: MAL-2025-25502
blocked: refusing to install lodahs (score 115 ≥ block threshold 70)
すべてのフラグ:
| フラグ | デフォルト | 説明 |
|---|---|---|
--json | false | 色付きテキストではなく、判定結果を JSON として出力します |
--no-color | false | ANSI カラーエスケープを無効にします |
--no-cache | false | ローカルの SQLite 判定キャッシュをスキップします |
-v / -vv | warn | ログの詳細度を上げます |
--yes(インストール時のみ) | false | warn レベルの判定を自動承認します。block レベルの場合は引き続き拒否します |
クイックスタート:MCP
npmguard-mcp は標準入出力を介して Model Context Protocol を使用します。バイナリを PATH に配置したら、以下のツールの手順に従ってエージェントに登録してください。
Claude Code
公式の claude mcp add CLI を使用します。JSON を手動で編集する必要はありません。
# Adds npmguard to your user-level config (~/.claude.json), available in all projects.
claude mcp add --transport stdio --scope user npmguard -- /usr/local/bin/npmguard-mcp
登録されたことを確認します。
claude mcp list
代わりに単一のプロジェクトに限定するには、プロジェクトルートの .mcp.json に保存します。安全にコミットできます。
claude mcp add --transport stdio --scope project npmguard -- /usr/local/bin/npmguard-mcp
Cursor
設定に mcpServers ブロックを追加します。すべてのワークスペースで有効にするにはグローバルファイルを、1 つのリポジトリに限定するにはプロジェクトファイルを使用します。
グローバル(~/.cursor/mcp.json):
{
"mcpServers": {
"npmguard": {
"command": "/usr/local/bin/npmguard-mcp"
}
}
}
プロジェクト単位(リポジトリルートの .cursor/mcp.json):
{
"mcpServers": {
"npmguard": {
"command": "/usr/local/bin/npmguard-mcp"
}
}
}
/usr/local/bin/以外の場所にインストールした場合は、commandのパスを編集してください。
Codex CLI
Codex は ~/.codex/config.toml を介した標準入出力の MCP サーバーに対応しています。[mcp_servers.npmguard] テーブルを追加します。
[mcp_servers.npmguard]
command = "/usr/local/bin/npmguard-mcp"
単一のプロジェクトに限定するには、リポジトリルートに同じブロックを含む .codex/config.toml を作成します(Codex が信頼済みとしてマークしたプロジェクトでのみ動作します)。
別の場所にインストールした場合は、
commandのパスを編集してください。参考: Codex MCP ドキュメント
MCP ツールが返す内容
npmguard-mcp は、モデルが判断に利用できる構造化された判定を返すツール install_package(name, version?) を1つ公開します。
{
"package": "lodahs",
"resolved_version": "0.0.1-security",
"level": "block",
"score": 115,
"signals": [
{ "kind": "SoleMaintainer", "points": 10, "detail": "single maintainer: adam_baldwin" },
{ "kind": "Typosquat", "points": 25, "detail": "name 'lodahs' is 1 edit away from popular package 'lodash'" },
{ "kind": "KnownCve", "points": 80, "detail": "1 CONFIRMED MALICIOUS by OSV for this version: MAL-2025-25502" }
],
"recommendation": "Block: do NOT install this package without explicit user override. Present the signals and ask the user to confirm."
}
モデルは推奨内容を自身のメッセージで受け取ります。そのため、ユーザーが 「必要なものは何でもインストールして」 と言った場合でも、アシスタントは構造化されたシグナルを受け取り、処理を止めて確認できます。
決定論的な強制(Claude Code フック)
MCP は助言を行います。フックは違います。
MCP 統合(npmguard-mcp)を使うと、Claude Code はパッケージをインストールする前に npmguard に「確認」できます。これは効果的です。モデルはリスク判定を確認し、それに基づいて動けます。しかし、あくまで助言にとどまります。ツールを呼び出すかどうかはモデルが決めるため、注意を欠いたモデルやジェイルブレイクされたモデルは確認を省略する可能性があります。
hook サブコマンドは異なります。Claude Code のハーネスは、すべての Bash ツール呼び出しで、コマンドが実行される前に PreToolUse フックを自動的に実行します。モデルに選択の余地はありません。フックを省略したり、回避したり、説得して無効にしたりすることはできません。これにより、ブロックが単なる理想ではなく、実際に機能します。
セットアップ(1つのコマンド)
# Installs into ~/.claude/settings.json, active in every Claude Code project.
npmguard hook install
# Or scope it to a single project (writes .claude/settings.json in the cwd).
npmguard hook install --scope project
その後、Claude Code を再起動してください(またはウィンドウを再読み込みしてください)。以降、Claude Code が実行しようとするすべての Bash コマンドは、まず npmguard hook handle を通過します。
フックを削除するには:
npmguard hook uninstall # user-level
npmguard hook uninstall --scope project
フックの動作
- Claude Code が Bash コマンド(例:
npm install some-package)を実行しようとします。 - ハーネスはコマンドを stdin(JSON)経由で
npmguard hook handleに送信します。 - npmguard は、パッケージのインストールを呼び出すコマンドを解析します。インストール以外のコマンド(
ls、git、npm run buildなど)は、ネットワーク呼び出しを行わずにすぐに通過します。 - 検出された各パッケージについて、既存のリスクエンジンが実行されます(シグナルとスコアリングは
npmguard checkと同じです)。 - npmguard は stdout に判定 JSON を書き込みます:
- ブロック判定 →
deny:Claude Code はコマンドを拒否し、その理由をモデルに伝えます。 - 警告判定 →
ask:Claude Code はシグナルを表示し、ユーザーに確認を求めます。 - 問題なし判定 →
allow:コマンドは何も表示せずに実行されます。 - ネットワークエラー → 注意メッセージ付きの
ask。未検証のパッケージを黙って許可することはなく、インフラ障害を理由に厳しく拒否することもありません。
- ブロック判定 →
制限事項について
| 制限事項 | 状況 |
|---|---|
| Claude Code のみです。 Cursor と Codex には、現時点で同等のツール実行前フック API がありません。対応するまでは、MCP による助言のみとなります。 | v1 |
引数を指定しない npm install は制御されません。 ロックファイルからの復元(引数なしの npm install)は、そのまま通過するものとして扱われます。明示的なパッケージ名を含むコマンドのみがチェックされます。 | v1 |
パーサーレベルでの回避が可能です。 意図的または難読化されたコマンド(eval、シェル変数の展開、ヒアドキュメントなど)は、コマンドパーサーを回避する可能性があります。完全に強制するには、シェル文字列を解析するのではなく npm 自体をラップする v0.2 の npm ラッパー+サンドボックスレイヤーが必要です。 | v1 |
認識されるのは npm/yarn/pnpm/bun のみです。 インストール(npm install/i/add、yarn add、pnpm add/install/i、bun add/install/i)と、その場で実行するランナー(npx、bunx、npm exec/x、pnpm dlx、yarn dlx、bun x)は制御されます。この一覧にないパッケージマネージャーは制御されません。 | v1 |
リスクシグナル
| シグナル | ポイント | 発動条件 |
|---|---|---|
LifecycleScripts | 30 | パッケージに preinstall、install、または postinstall が定義されている |
PackageAge | 25 / 10 | バージョンの公開から 7 日未満 / 30 日未満 |
MaintainerChurn | 20 | 180 日を超える公開間隔の後にバージョンが公開された(休眠パッケージの再公開) |
SoleMaintainer | 10 | パッケージのメンテナーがちょうど 1 人 |
RepoHealth | 15 / 10 | リンク先の GitHub リポジトリがアーカイブされている / スターが 0 で、6 か月間コミットがない |
Typosquat | 25 | 名前が人気パッケージの名前と Damerau-Levenshtein 距離で 1 以内(lodahs↔lodash のような文字の入れ替えを検出) |
KnownCve | 80 / 50 / 20 / 10 / 5 | OSV.dev のアドバイザリが存在する。80 は MAL-*(OSV の悪意あるパッケージが確認された場合の名前空間)の場合です。それ以外は CVSS のクリティカル / 高 / 中 / 低(アドバイザリの CVSS ベクターから基本スコアを計算)です。 |
Deprecated | 10 | npm レジストリがこのバージョンを非推奨としている |
ReleaseAnomaly | 40 / 30 / 25 / 15 | このバージョンが、乗っ取りを思わせる形で直前のバージョンと異なる:新たに追加されたインストールスクリプト(40)、インストールスクリプト内の難読化された高エントロピーのペイロード(30)、新しいトップレベルの依存関係(25)、または依存関係数が 50% を超えて増加(15) |
複合スコアは合計値です(上限 200)。デフォルトのしきい値:warn ≥ 30、block ≥ 70。設定ファイルでプロジェクトごとに調整できます(v0.2 で対応予定)。
重みは出発点であり、科学的なものではありません。 corpus/ を使って調整し、各リリースの一部として公開します。PR を歓迎します。
バージョン管理とリリース
npmguard はセマンティックバージョニングに従います。プロジェクトが 0.x の間は、次のとおりです。
- CLI はエンドユーザー向けに安定しているものとして扱います。フラグ名と終了コードは、メジャーバージョンを上げずに変更することはありません。
- MCP ツールのインターフェース(
install_packageの入出力スキーマ)には、0.xリリース間でマイナーな追加変更が加わる場合があります。破壊的変更は CHANGELOG.md に記載します。
タグ付きリリースでは、クロスプラットフォームの GitHub Actions マトリックスを介して、Releases ページにビルド済みバイナリ(macOS x86_64 + arm64、Linux x86_64 + arm64、Windows x86_64)を公開します。
メモ
v0.1 はリスクチェッカー + MCP 判定ゲートです。現時点では、本物の npm ラッパー、インストーラー、サンドボックスではありません。
npmguard checkとnpmguard installはどちらも判定を返します。実際のnpm installサブプロセスの実行とクロスプラットフォームのサンドボックスは v0.2 で提供されます。以下のロードマップを参照してください。
ロードマップ(詳しい理由と検討のうえ除外した範囲については ROADMAP.md を参照してください):
| フェーズ | 概要 |
|---|---|
| v0.1(リリース済み) | リスクエンジン + CLI + MCP サーバー + SQLite キャッシュ + GitHub Releases |
| v0.2 | 実際の npm install の実行 + OS ごとのサンドボックス + リリース異常検出エンジン(バージョンごとの package.json の差分)+ Homebrew/Scoop/AUR/install.sh による配布 |
| v0.3 | プロベナンス / 署名の検証 + スキャナーアダプター(--with npm-audit、--with osv-lockfile、--with socket)+ SBOM の生成 |
| v0.4 | npmguard.toml ポリシーファイル + CI モード + 例外許可 |
| v0.5 | 組織向けプリセット + MCP マーケットプレイスへの掲載(Claude Code、Cursor、Smithery) |
| v1.0 | 凍結された Rust API、凍結された MCP ツールスキーマ、凍結された JSON 出力、AI アシスタントのデフォルトドキュメントへの統合 |
ランタイムサンドボックス(npmguard run npm test)は意図的に対象外としています。その理由は ROADMAP.md § 検討のうえ対象外とした項目 を参照してください。
スコープの制限(v0.1 ではまだ対応していないこと)
誠実さがこのプロジェクトの約束です。
npmguard はパッケージが安全であると証明することはできません。 既知の悪意あるパッケージ(OSV
MAL-*)をブロックし、タイポスクワッティングを検出し、ライフサイクルスクリプト / パッケージの公開からの経過期間 / メンテナーの交代を明らかにし、AI コーディングエージェントを同じ判定プロセスに通すことはできます。それだけです。以下はすべて、v1.0 で最終的に追加される機能です。ROADMAP.md を参照してください。
v0.1 でまだ不足しているもの:
- すべてのヒューリスティックチェックを通過する攻撃は検知できません。
ReleaseAnomalyシグナルは各バージョンをその前のバージョンと比較し、一般的な乗っ取りの兆候、つまり新たに追加されたインストールスクリプト、新しい依存関係、または難読化されたインストールスクリプトのペイロードにフラグを立てるようになりました。ただし、明らかにエントロピーの高いデータを含まずに既存のインストールスクリプトの 内容 を巧妙に変更する乗っ取りや、インポートされたコードに悪意あるコードを平文で含める攻撃は、依然としてすり抜ける可能性があります。v0.2 で残っている課題は、本物のnpm installをラップし、実行されるスクリプトをサンドボックス化することです。 - npm のプロベナンス/パッケージ署名はまだ検証しません。 過去に存在したプロベナンス証明が突然なくなった場合、乗っ取りを示す強い兆候となります。この機能は v0.3 で対応します。
- ライフサイクルスクリプトのサンドボックス化や、本物の
npm installサブプロセスのラップにはまだ対応していません。 v0.1 は判定を提示して処理を停止します。v0.2 では、サンドボックス(landlock / sandbox-exec / Job Object)と--ignore-scriptsの強制、およびスクリプトごとの許可リストを提供します。 - インストール時ではなく インポート時 に実行される悪意あるコードからは保護しません。 インストール時には無害でも、インポート時に悪意ある動作をするパッケージの場合、このツールは介在しません。これはランタイムサンドボックスの問題であり、意図的に対象外です。ROADMAP.md を参照してください。
npm audit、Snyk、Socket、Dependabot、コードレビューに取って代わるものではありません。追加の保護レイヤーです。v0.3 では--with npm-audit/--with osv-lockfile/--with socketアダプターを追加し、重複するスキャナーではなく、それらの上位で npmguard がポリシーゲートとして機能するようにします。- 保証を提供するものではありません。「安全」を謳うツールはすべて嘘をついています。このツールが謳うのは「被害範囲を縮小する」ことだけです。
貢献
プルリクエストやイシューを歓迎します。簡単に言うと:
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
NPMGUARD_CORPUS=1 cargo test --test corpus -- --nocapture # live network test
問題がなければプルリクエストを作成してください。
ライセンス
MIT。詳細は LICENSE を参照してください。
作者について
Ayoub Tadlaoui(Atlas Kaisar)。モロッコ出身で、2016 年からソフトウェアを開発しています。
「高いパフォーマンスに、パートタイムの取り組みは通用しない。」
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。