关于 ExactGround
ExactGround 为编码 Agent 提供依赖安装拦截钩子,并通过托管 API 检查特定版本中的符号。钩子会在执行前检查受支持的 npm、PyPI 安装命令和依赖清单;API 静态分析已发布的包,不运行代码。
主要功能
- 01拦截不存在的包安装
- 02检查从未发布的包版本
- 03标记名称相似或有风险的包
- 04通过 Agent 钩子检查依赖清单
- 05按确切版本检查符号
- 06静态分析包内容,不执行代码
适用场景
- 01阻止 Agent 安装虚构的包
- 02检查项目清单中新添加的依赖
- 03确认特定版本是否包含某符号
- 04检查代码变更引入的导入项
MCP 相关
托管的版本精确检查 API 是 MCP 服务,提供 `check_symbols`、`check_packages` 和 `check_diff`。该服务需要 Apify API token;本地钩子式安装防护与此 MCP API 相互独立。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://dropin-apis--exactground-api.apify.actor/mcpclaude mcp add --transport http alidaram99-exactground https://dropin-apis--exactground-api.apify.actor/mcp{"mcpServers":{"alidaram99-exactground":{"type":"http","url":"https://dropin-apis--exactground-api.apify.actor/mcp"}}}在 Cursor 中打开{"servers":{"alidaram99-exactground":{"type":"http","url":"https://dropin-apis--exactground-api.apify.actor/mcp"}}}在 VS Code 中打开{"mcpServers":{"alidaram99-exactground":{"type":"http","url":"https://dropin-apis--exactground-api.apify.actor/mcp"}}}{"mcpServers":{"alidaram99-exactground":{"serverUrl":"https://dropin-apis--exactground-api.apify.actor/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://dropin-apis--exactground-api.apify.actor/mcp需要授权工具
详细介绍
ExactGround:阻止 AI 编码 Agent 安装不存在的软件包
ExactGround 会阻止 AI 编码 Agent 安装不存在的 npm 或 PyPI 软件包;其托管检查还能告诉你某个函数是否存在于你安装的确切版本中。
这款免费开源防护工具以钩子的形式运行于 Claude Code、Codex、Gemini CLI 和 Cursor 中。它会在命令运行之前,对照 npm 公共注册表和 PyPI 检查以下内容:
- 它能够解析的
npm/pnpm/yarn/bun/npx和pip/uv/poetry/pdm/pipx安装命令; - 写入
package.json、requirements*.txt或pyproject.toml的新依赖项。
它会拦截 AI 幻觉产生的软件包名称(slopsquatting 的根源)、从未发布过的版本、刚出现或使用较少的热门软件包仿冒品,以及 npm 安全占位符。零依赖、本地运行、MIT 许可。
威胁模型,直白地说: ExactGround 会拦截 Agent 在普通安装命令中凭空编造或拼错软件包名称。它是协作式防护措施,不是沙箱:Agent 若刻意试图绕过它(例如编写自己的脚本、编辑钩子看不到的文件,或以其他方式运行代码),就能避开它。若要限制你不信任的 Agent,请使用操作系统或容器沙箱。
有意不涵盖的范围: 以你的用户身份运行的 Agent 若刻意混淆命令(在运行时构造程序名称或文件路径、编写自己的脚本、对命令进行编码),就能绕过任何基于钩子的防护工具,包括本工具。ExactGround 会拒绝已知的混淆模式,但不会进一步处理此类情况。若你将 Agent 视为对抗对象,请在操作系统沙箱或容器中运行它,或使用无法写入 ExactGround 配置的独立操作系统用户运行它。请参阅 SECURITY.md。
它看不到的内容:
- 内嵌脚本(
node -e、python -c)、命令替换($(...))、eval/iex/Start-Process或-EncodedCommand中隐藏的安装无法检查,因此钩子会拒绝这些命令,并要求使用普通安装命令。通过变量调用的软件包管理器(n=npm; $n install x)、8.3 短文件名(NPM~1.EXE)、.cmd/.ps1后缀和完整路径都会被解析并检查。运行时构造的程序名称(& ('np'+'m')、for %I in (npm) do ...)和保存在变量中的软件包名称(npm install $p)都会被拒绝;cmd 插入的脱字符(np^m)会被移除并检查。使用字面量管理器的循环或调用(ForEach-Object { npx eslint $_ }、& $python -m pip install requests)会按常规解析并检查。 - 每次工具调用都会被检查:任何携带
command的工具都会被视为 shell;每个非只读工具的文件路径都会根据 ExactGround 自身的策略文件进行检查。在 Agent 之外运行的任何内容(CI、cron、其他程序)都不会被检测到。 - 钩子是防护措施,不是沙箱:Agent 若有其他运行代码的方式,就能绕过它们(见上文威胁模型)。
- 如果无法访问注册表,或检查器本身出错,钩子默认会拒绝。
· 网站:https://alidaram99.github.io/exactground/ · 托管 API:https://apify.com/dropin-apis/exactground-api
$ npx -y github:alidaram99/exactground#v0.1.5 check pypi:requests pypi:reqeusts pypi:huggingface-cli [email protected]
OK pypi:requests
BLOCK pypi:reqeusts — "reqeusts" does not exist on PyPI; did you mean "requests"? (it is 1 edit away)
BLOCK pypi:huggingface-cli — "huggingface-cli" does not exist on PyPI
BLOCK [email protected] — version 99.0.0 of "react" was never published (latest is 19.3.0)
这为何重要
- 包名幻觉很常见,而且会反复出现。 USENIX Security 2025 的研究 We Have a Package for You!(Spracklen 等人)让 16 个模型编写了 576,000 个代码样本。其中的 223 万条包推荐里,有 440,445 条(19.7%)提到了不存在的包,涉及 205,474 个唯一名称。在另一项测试中,作者将 500 条曾产生幻觉的提示词分别重新运行 10 次,其中 43% 的幻觉名称在全部 10 次运行中都再次出现(论文)。
- Slopsquatting 会将这种情况变成攻击:有人注册这个虚构名称并植入恶意软件,下一个运行
pip install <invented-name>的 Agent 就会安装它(Wikipedia;CSA 研究说明,2026)。上文的huggingface-cli就是典型例子:这是模型为真实的huggingface_hub[cli]虚构出的名称。 - Agent 会在无人查看的情况下安装。 在
CLAUDE.md或AGENTS.md中写上“不要虚构包名”之类的规则,只是模型可能会忽略的文本,尤其是在上下文压缩之后。钩子则是每次都会运行的代码。
快速开始
需要 Node.js 20 或更高版本。无需安装:
npx -y github:alidaram99/exactground#v0.1.5 check left-pad expresss pypi:numpy==1.26.4
npx -y github:alidaram99/exactground#v0.1.5 scan "npm i zod react-hook-formz && pip install -r requirements.txt"
npx -y github:alidaram99/exactground#v0.1.5 manifest package.json
对于钩子,请使用已标记版本的本地检出副本(速度更快、版本固定,且钩子运行时不会下载任何内容):
git clone --depth 1 --branch v0.1.5 https://github.com/alidaram99/exactground.git ~/tools/exactground
将其添加到你的编码 Agent
exactground init <agent> 会输出适用于你当前检出副本的完整配置,其中包含绝对路径。--write 会将配置合并到当前项目,并保留你现有的钩子。
Claude Code(插件)
claude plugin marketplace add alidaram99/exactground
claude plugin install exactground@exactground-marketplace
该插件会在 Bash|Write|Edit|MultiEdit 上注册 PreToolUse 钩子。
- 遇到被拦截的安装时,会拒绝执行并向 Claude 显示原因,例如:PyPI 上不存在 "reqeusts";你是不是想输入 "requests"?
- 警告不会阻止执行,而是作为上下文传递给 Claude。
手动替代方案:node ~/tools/exactground/bin/exactground.mjs init claude --write。
Codex
codex plugin marketplace add alidaram99/exactground --ref v0.1.5
安装插件后,在 /hooks 中检查并信任该钩子;Codex 只会运行受信任的钩子。手动替代方案:exactground init codex --write 会写入 .codex/hooks.json,并在 Bash 和 apply_patch 上设置 PreToolUse,因此也会检查向 package.json、requirements.txt 或 pyproject.toml 添加依赖的补丁。
Gemini CLI(扩展)
gemini extensions install https://github.com/alidaram99/exactground --ref v0.1.5
该扩展的 BeforeTool 钩子会监控 run_shell_command|write_file|replace。手动替代方案:exactground init gemini --write 会将相同的钩子添加到 .gemini/settings.json。
Cursor
exactground init cursor --write 会将 beforeShellExecution 钩子添加到 .cursor/hooks.json。Cursor 无法在文件编辑发生前拦截,因此 ExactGround 会改为拦截后续的 npm install/pip install/uv sync:裸安装会检查清单中所有尚未写入锁文件的依赖。
检查内容
| 情况 | 判定 |
|---|---|
名称不在 npm/PyPI 上(npm i reacct-dom、pip install reqeusts) | 阻止,并提示“你是不是想找……” |
固定版本从未发布([email protected]、numpy==9.9) | 阻止 |
npm 安全占位版本(0.0.1-security:恶意软件已被移除) | 阻止 |
| 与排名前 3,000 的软件包相似,且发布不足 180 天或周下载量不足 500 | 阻止 |
| 与广泛使用的老牌软件包相似 | 警告 |
| 发布不足 30 天、周下载量不足 500、已弃用或已撤回 | 警告 |
| 注册表无法访问 | Agent 钩子中为拒绝(钩子默认启用严格模式);手动 CLI 会发出警告,除非使用 --strict |
正在使用 --index-url/--extra-index-url(可能涉及私有软件包) | 仅对缺失名称发出警告 |
检查范围:
- 直接安装;
npx/pnpm dlx/bunx/uvx运行;pip install -r文件,包括嵌套的-r;- 裸命令
npm install/yarn/pnpm install/uv sync/poetry install(锁文件中缺失的依赖项); - 对
package.json、requirements*.txt和pyproject.toml执行Write/Edit; - Codex
apply_patch。
会去掉命令外层的 bash -lc "…"。
**配置:**可在项目根目录放置可选的 .exactground.json:
{ "allow": ["my-internal-lib", "pypi:corp-utils"], "privateScopes": ["@acme"], "newPackageDays": 30, "lowDownloads": 500 }
Agent 不能批准自己的例外:
- 钩子只有在你于终端中运行
exactground trust后,才会采用项目的.exactground.json。这会将该文件的 SHA-256 记录到项目之外的用户配置目录中。 - 之后的任何编辑都需要重新批准。用户级
config.json也采用相同处理方式:使用exactground trust --user批准。 - 任何写入
.exactground.json、批准记录或缓存的工具调用都会被拒绝。 - 所有项目的设置都可以放在
~/.config/exactground/config.json(Windows 上为%APPDATA%\exactground\config.json)中。
手动 CLI 会将查询结果缓存 24 小时,缓存位置为 ~/.cache/exactground。Agent 钩子始终会重新检查注册表,不会仅凭缓存允许安装。
版本精确的 API 检查(托管服务,按次付费)
**托管 API 状态:**自 2026-10-03 起,可在 Apify Store 上使用。调用需要 Apify API 令牌(未提供令牌的请求会收到 HTTP 401)。
大多数幻觉实际上是把真实软件包用错了:例如在 React 18 项目中使用 useActionState,或在 NumPy 2.0 移除 numpy.asfarray 后仍使用它。ExactGround API 会直接从已发布的软件包中回答这些问题:通过 TypeScript 编译器检查 npm .d.ts,并静态解析 Python wheel,不运行任何代码。它是一个 MCP 服务:
claude mcp add --transport http exactground https://dropin-apis--exactground-api.apify.actor/mcp --header "Authorization: Bearer $APIFY_TOKEN"
| 工具 | 价格 |
|---|---|
check_symbols | 每个符号 $0.002 |
check_packages | 每个软件包 $0.0005 |
check_diff | 每个差异 $0.01(更改新增的每个导入项) |
在 CLI 中使用:APIFY_TOKEN=… exactground api check_symbols '{"ecosystem":"pypi","package":"numpy","version":"2.1.0","symbols":["numpy.asfarray"]}'。
对比
| 工具 | 功能 | 能否阻止 Agent 在其中安装幻觉出来的包? | 是否进行精确到版本的 API 检查? |
|---|---|---|---|
| ExactGround | 在 Agent hooks 中检查注册表实际情况和仿冒包信号(免费);API 检查(托管版) | 可以,适用于它能够解析的安装命令和清单编辑(Claude Code、Codex、Gemini CLI、Cursor hooks) | 可以(托管版 API) |
| Socket Firewall | 在安装时拦截已确认的恶意软件 | 可以拦截恶意软件;不存在的名称只会导致安装失败(或者在仿冒包被确认之前安装新出现的仿冒包) | 不支持 |
| Context7 | 将特定版本的文档加入提示词 | 不支持;Agent 仍可能编造名称 | 不支持;提供的是文档文本,而非是/否检查 |
npm audit / pip-audit | 检查已安装包中的已知漏洞 | 不支持;它在安装后运行,且只检查已存在的包 | 不支持 |
类型检查器(tsc、pyright) | 在安装后检查类型化代码中精确到版本的 API | 不支持 | 支持,但需要代码和环境已经就绪 |
这些工具可以协同使用。ExactGround 是安装前成本低廉的把关工具,而 Socket 和审计工具则负责保障实际软件包的安全。
常见问题
如何阻止 Claude Code 安装幻觉出来的 npm 或 PyPI 包?
安装 ExactGround Claude Code 插件(如上所述,只需运行两条命令)。它的 PreToolUse hook 会检查可解析的 Bash 安装命令以及 package.json/requirements.txt/pyproject.toml 编辑中的包名;如果某个名称不存在,就会拒绝工具调用。无法解析的安装也会被拒绝。
什么是 slopsquatting?
注册 AI 模型幻觉出来的包名,以便信任该建议的 Agent 和开发者安装攻击者的代码。这个术语由 Seth Larson 创造;USENIX 2025 的研究测量了模型编造名称的频率。
ExactGround 会把我的代码发送到别处吗?
本地防护工具只会将包名发送到公共注册表(registry.npmjs.org、api.npmjs.org、pypi.org),与包管理器发出的请求相同。托管版 API 只会接收你发送给它的内容。
它会拦截我的私有包吗?
如果你在 .exactground.json 中列出这些包(使用 allow 或 privateScopes),并通过 exactground trust 信任该文件,就不会拦截。使用自定义 --index-url 时,缺失的名称只会发出警告。
它会拖慢 Agent 吗?
每个新包名只需发出一次缓存的 HTTP 请求,通常耗时 100–400 ms;对于不安装任何内容的命令,则不会产生额外开销。
Hook 是安全边界吗?
不是。Agent hooks 是防护措施。Claude Code 和 Codex 的文档说明,hooks 可能超时或被绕过;Codex 托管工具不会触发 hooks;Cursor 则无法在文件编辑发生前阻止编辑。默认情况下,ExactGround 的 hooks 会在内部错误和注册表中断时拒绝操作。设置 EXACTGROUND_FAIL_OPEN=1 可在发生内部错误时允许操作。还应使用锁文件、CI 检查和安装时扫描工具。
支持哪些生态系统?
npm(npm、pnpm、yarn、bun、npx)和 PyPI(pip、uv、poetry、pdm、pipx、uvx)。
开发
npm test # 27 offline tests: parser, policy, cache, all four hook formats, manifests, patches
热门包列表来自 npm-high-impact(MIT)和 top-pypi-packages(参见 data/)。
同一团队的更多工具
- DoneLatch:没有新鲜、对故障敏感的证据,Agent 就不能宣称“完成”。
- CanaryIndex:公开且定期重新运行的 Agent 工具评分卡。
- Waraq:免费的离线 Markdown 阅读器和编辑器,可在笔记本电脑和手机上查看 Agent 文件。
- 所有工具:https://alidaram99.github.io/
许可证
MIT。与 npm、PyPI、Anthropic、OpenAI、Google 或 Cursor 均无关联。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。