mcpField
N
Npmguard

Npmguard

本地服务
github.com/AyoubTadlaoui安全220 周前更新

关于 Npmguard

Npmguard 是用于安装前筛查 npm 包的 Rust 命令行工具和 MCP 服务,面向开发者及编码 Agent。它结合包风险评分与 Claude Code 钩子,可在命令执行前实施拦截。

主要功能

  1. 01安装前评估包风险
  2. 02检查 OSV 恶意软件和名称仿冒
  3. 03分析安装脚本
  4. 04输出文本或 JSON 判定
  5. 05Claude Code 命令钩子

适用场景

  1. 01安装前检查 npm 包
  2. 02拦截 Claude Code 的可疑安装
  3. 03在 CI 中查看包风险判定
  4. 04让编码 Agent 请求结构化风险检查

MCP 相关

MCP 服务提供 `install_package` 工具,返回 npm 包的结构化风险判定,并通过 stdio 与 MCP 主机通信。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

npmguard

我开发这个工具,是因为太多氛围编程者直接让 AI 以自动模式运行,任由它安装任何想安装的东西,这实在令人震惊。npmguard 会在任何安装脚本运行之前先进行筛查。

Claude Code、Cursor 和 Codex 会自主运行 npm install。没人会停下来问一句:“等等,supabase-mcp-helper 到底是不是真有这个包?”我开发了 npmguard,将其作为 MCP 服务和 CLI,为每个包打分(参考 OSV 恶意软件数据、检查拼写仿冒/slopsquat,以及分析安装脚本),并在生命周期脚本执行之前给出判定。

它以单个 Rust 二进制文件的形式发布,位于 npm 之外。这很重要:这个防护闸门不会被它要防范的供应链投毒。

CI Release Latest release License: MIT codecov

Claude Code 通过 npmguard 的 MCP 闸门拒绝安装已确认的恶意拼写仿冒包 lodahs(OSV MAL-2025-25502)。真实会话,atlas-ragnarok 主题。

npmguard install lodahs 是 lodash 的真实拼写仿冒包,npmguard 会在生命周期脚本运行之前拒绝安装:

npmguard 拒绝安装拼写仿冒包,atlas-ragnarok 主题

也提供 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 代表你运行 npm install 时拦截这些 AI 编码助手。

最后这一点正是我想解决的问题:在安装前进行风险评分,同时为 AI Agent 设置防护闸门,并以单个位于 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 方式可避免此问题;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)

所有预构建的二进制文件都列在 Releases 页面上。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 主机通过 stdio 通信。


快速入门: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)

所有标志:

标志默认值含义
--jsonfalse以 JSON 而非彩色文本输出判定结果
--no-colorfalse禁用 ANSI 颜色转义序列
--no-cachefalse跳过本地 SQLite 判定缓存
-v / -vvwarn提高日志详细程度
--yes(仅安装时)false自动接受警告级判定;阻止级判定仍会拒绝

快速入门:MCP

npmguard-mcp 通过 stdio 使用 Model Context Protocol。将二进制文件加入 PATH 后,请按照下方对应工具的说明为你的 Agent 注册它。

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

参考:Claude Code MCP 文档

Cursor

在配置中添加 mcpServers 块。使用全局文件以便在每个工作区启用,或使用项目文件将其限定在一个仓库中。

全局(~/.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 路径。

参考:Cursor MCP 文档

Codex CLI

Codex 通过 ~/.codex/config.toml 支持 stdio 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?),返回模型可据此采取行动的结构化判定:

{
  "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 hook)

MCP 仅提供建议,hook 则不然。

MCP 集成(npmguard-mcp)允许 Claude Code 在安装软件包前询问 npmguard。它效果很好:模型会看到风险判定,并据此采取行动。但它仍然只是提供建议。模型可以自行决定是否调用工具;注意力不集中的模型或被越狱的模型可能会跳过它。

hook 子命令则不同。Claude Code 的运行机制会在每次 Bash 工具调用时自动运行 PreToolUse hooks,在命令执行前。模型无法干预。它不能跳过、绕过 hook,也不能靠说辞逃过 hook。这正是阻止行为切实有效而非流于形式的原因。

设置(一个命令)
# 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。

移除 hook:

npmguard hook uninstall          # user-level
npmguard hook uninstall --scope project
hook 的作用
  1. Claude Code 想要运行一条 Bash 命令,例如 npm install some-package。
  2. 运行机制通过 stdin(JSON)将命令发送给 npmguard hook handle。
  3. npmguard 会解析命令,查找安装软件包的调用。非安装命令(ls、git、npm run build 等)会立即放行,不进行网络调用。
  4. 对每个检测到的软件包,都会运行现有风险引擎(信号和评分方式与 npmguard check 相同)。
  5. npmguard 会将决策 JSON 写入 stdout:
    • 阻止判定 → deny:Claude Code 会拒绝该命令,并告知模型原因。
    • 警告判定 → ask:Claude Code 会显示相关信号并询问用户是否确认。
    • 正常判定 → allow:命令会静默执行。
    • 网络错误 → ask,并附带警告消息。未经验证的软件包绝不会被静默放行;基础设施故障也绝不会导致硬性拒绝。
如实说明局限性
局限性状态
仅支持 Claude Code。 Cursor 和 Codex 尚未提供类似的工具调用前 hook API。在提供该 API 之前,它们仍然只能依赖 MCP 提供建议。v1
不拦截裸 npm install(不带软件包参数)。 恢复 lockfile(不带参数运行 npm install)会被视为直接放行。只检查包含显式软件包名称的命令。v1
可能在解析器层面被规避。 精心构造或经过混淆的命令(eval、shell 变量展开、heredoc 等)可以绕过命令解析器。要实现全面强制执行,需要 v0.2 的 npm-wrapper + sandbox 层;该层会包装 npm 本身,而不是解析 shell 字符串。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

风险信号

信号分值触发条件
LifecycleScripts30软件包定义了 preinstall、install 或 postinstall
PackageAge25 / 10版本发布于 < 7 / 30 天前
MaintainerChurn20版本发布前存在 > 180 天的发布间隔(休眠软件包重新启用)
SoleMaintainer10软件包恰好只有一位维护者
RepoHealth15 / 10关联的 GitHub 仓库已归档 / 没有星标且 6 个月内没有提交
Typosquat25名称与热门软件包仅相差一次 Damerau-Levenshtein 编辑操作(可检测像 lodahs↔lodash 这样的字符互换)
KnownCve80 / 50 / 20 / 10 / 5存在 OSV.dev 安全公告。如果是 MAL-*(OSV 用于确认恶意软件包的命名空间),则为 80。否则按 CVSS 严重 / 高 / 中 / 低级别计分(基础分根据安全公告的 CVSS 向量计算)。
Deprecated10npm 注册表将此版本标记为已弃用
ReleaseAnomaly40 / 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 + 按操作系统划分的沙箱 + 发布异常引擎(逐版本对比 package.json)+ Homebrew/Scoop/AUR/install.sh 分发
v0.3来源 / 签名验证 + 扫描器适配器(--with npm-audit、--with osv-lockfile、--with socket)+ SBOM 生成
v0.4npmguard.toml 策略文件 + CI 模式 + 豁免项
v0.5组织预设 + MCP 市场上架(Claude Code、Cursor、Smithery)
v1.0冻结的 Rust API、冻结的 MCP 工具架构、冻结的 JSON 输出、集成到 AI 助手默认文档中

运行时沙箱(npmguard run npm test)明确不在范围内。关于原因,请参阅 ROADMAP.md § Considered and kept out of scope。

范围限制(v0.1 尚未实现的内容)

诚实是我们的承诺。

**npmguard 无法证明软件包是安全的。**它可以拦截已知的恶意软件包(OSV MAL-*)、标记仿冒软件包、展示生命周期脚本 / 软件包年龄 / 维护者变动信息,并让 AI 编码 Agent 使用同一套判定机制。仅此而已。下方列出的所有功能最终都将在 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 成为它们之上的策略关卡,而不是一个重复的扫描器。
  • 不作任何保证。任何声称“安全”的工具都在撒谎。这个工具只说“缩小爆炸半径”,仅此而已。

参与贡献

欢迎提交 PR 和问题。简而言之:

cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
NPMGUARD_CORPUS=1 cargo test --test corpus -- --nocapture   # live network test

一切就绪后,提交 PR。


许可证

MIT。请参阅 LICENSE。


关于作者

Ayoub Tadlaoui(Atlas Kaisar)。来自摩洛哥,自 2016 年起从事软件开发。

“高性能从不接受兼职投入。”

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。