Skip to main content
Glama

Dep Bouncer

npm install, reimagined for AI agents.

Built with NitroStack MCP Live on NitroCloud tests 220 passing benchmark 5/5 hijacks blocked 0 false BLOCK on top 200 license MIT CI

Before vs after

Watch the 2:32 demo film

▶ Watch the demo film (2:32): https://youtu.be/w9Ax5KPUGD8

Try it in 30 seconds

Add this live URL as a remote MCP server in your client:

https://dep-bouncer-6ad22414-giberelin-heapify-global-community.app.nitrocloud.ai/mcp

Then ask: "Use the safe_install prompt, then add axios to this project."

Or replay the axios incident directly (Bash / zsh):

curl -X POST 'https://dep-bouncer-6ad22414-giberelin-heapify-global-community.app.nitrocloud.ai/mcp' \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -H 'mcp-protocol-version: 2025-06-18' \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"bouncer_replay_incident","arguments":{"incident":"axios"}}}'

Works with (tested on the live server):

  • NitroChat: verdict card rendered (screenshots below).

  • Claude Code as an MCP client: claude mcp add --transport http dep-bouncer <URL>; a real session called bouncer_check_package and bouncer_replay_incident, reported BLOCK with the evidence, and recommended a safe axios version.

  • Claude Code guard hook: blocked the agent's own npm install of a non-existent package (guard; Cursor hook config included).

  • Any Streamable-HTTP MCP client via the URL (e.g. Cursor, NitroStudio, ChatGPT developer mode).

Dep Bouncer is an MCP server an AI coding agent calls before it installs or upgrades an npm package. It compares the release with the package's own history (who published it, whether CI signed it, what runs at install time, which dependencies appeared, what code changed) and returns ALLOW / REVIEW / BLOCK with the evidence, plus the version to install instead.

  • Live MCP endpoint: https://dep-bouncer-6ad22414-giberelin-heapify-global-community.app.nitrocloud.ai/mcp

  • Demo video (2:32): https://youtu.be/w9Ax5KPUGD8

  • Track: Developer Tools · Product reimagined: npm (npm install / npm audit)

  • Built with NitroStack, deployed on NitroCloud.


Related MCP server: pkgtruth

The problem: agents install in seconds, advisories arrive in hours

AI coding agents now run npm install for us, mid-task, from the terminal. npm installs whatever was published a minute ago, and npm audit only knows about published advisories. For real hijacks, the free advisory database (OSV) needed hours to catch up:

Hijack

Weekly downloads (Oct 2026)

First OSV entry after publish

What npm audit said meanwhile

axios 1.14.1 (Mar 2026)

119 M

2.9 h (MAL-2026-2307)

found 0 vulnerabilities

keyv 6.0.0 (Aug 2026)

167 M

1.7 h (MAL-2026-11524)

found 0 vulnerabilities

chalk 5.6.1 (Sep 2025)

496 M

4.0 h (MAL-2025-46969)

found 0 vulnerabilities

@ctrl/tinycolor 4.1.1 (Sep 2025)

4.7 M

3.8 h (MAL-2025-47141)

found 0 vulnerabilities

nx 21.5.0 (Aug 2025)

10.8 M

18.2 h (MAL-2025-41443)

found 0 vulnerabilities

Lags measured from the npm registry's publish times and OSV's published field. Two of these attacks went straight for AI agents: nx's malware ran the victim's claude, gemini and q CLIs with permission checks disabled, and the keyv worm planted Claude Code SessionStart hooks.

Before / after

Before: agent + npm

After: agent + Dep Bouncer

axios@1.14.1, 30 min after the hijack

npm audit: found 0 vulnerabilities; postinstall of plain-crypto-js drops a RAT

BLOCK: published by a personal account instead of the project's CI; provenance gone; new dependency plain-crypto-js is 22 minutes old, copies the name crypto-js, runs a postinstall and is never imported by axios. Install axios@1.14.0 instead.

keyv@6.0.0 (valid provenance!)

installs; preinstall runs an obfuscated loader

BLOCK: new preinstall running a new file; obfuscated loader that spawns processes and downloads a runtime; 700 KB encrypted blob. Install 5.6.0.

chalk@6.0.1 today

installs

ALLOW: consistent with its own history

In a real agent (NitroChat, connected to the live server): "Replay the axios incident with Dep Bouncer and tell me what to install instead."

Dep Bouncer verdict card in NitroChat: BLOCK axios@1.14.1 with evidence What other checks say, and the safe version to install instead

Why this needs MCP

A verdict is not one lookup. For each request the agent's tool call makes Dep Bouncer gather the registry history (publishers, provenance, publish times), download and diff two tarballs, look up every newly added dependency, check the name against popular packages, and query OSV. Then the agent acts on the answer: it installs the safe version, asks the human (REVIEW), or refuses (BLOCK). The safe_install prompt teaches any agent that loop.

Tools, resources, prompt, widget

MCP surface

What it does

bouncer_check_package

Vet a release (or latest) before npm install. Verdict, evidence, what npm audit / OSV / a cooldown say, safe version.

bouncer_check_upgrade

Vet a version bump and show what changed between the two versions.

bouncer_safe_version

Newest version in a semver range that passes every check, and why newer ones were skipped.

bouncer_check_manifest

Vet every dependency of a package.json at the version npm would install today. Runs as an MCP Task with live progress.

bouncer_review_install_scripts

npm 12 asks you to approve install scripts but only shows the command. This explains each one: APPROVE / REVIEW / DENY.

bouncer_replay_incident

Replay a real hijack (axios, keyv, chalk, nx, tinycolor) as an agent met it, 30 minutes after publication.

bouncer://policy

Signals, weights and thresholds.

bouncer://stats

Live per-tool calls, errors, p50/p95 latency and verdict totals.

incidents://list

The replayable incidents and their OSV lag.

safe_install (prompt)

Rules that make an agent call Dep Bouncer before every dependency change and act on the verdict.

verdict-card (widget)

Visual verdict with evidence, the "what other checks say" panel and a one-click "use the safe version".

Agent guard: no install without a check

Agents forget to call tools. guard/ is a hook for Claude Code (PreToolUse) and Cursor (beforeShellExecution) that intercepts the agent's own terminal commands (npm i, pnpm add, yarn add, bun add, npx, pnpm dlx, ...), asks Dep Bouncer about each package, and denies BLOCK, asks the user on REVIEW, and emits no permission decision for ALLOW so the host keeps its own permission prompts.

Tested with a real headless Claude Code session asked to npm install react-codeshift-utils-pro chalk: the hook denied the command ("does not exist on npm"), the agent verified, did not work around the block, and installed only chalk.

{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [
  { "type": "command", "command": "node /path/to/dep-bouncer/guard/dep-bouncer-guard.mjs" } ] } ] } }

How it decides

Signal

Looks for

Caught

publisher-change

A personal account publishing where CI (npm trusted publishing) always did; a never-seen publisher

axios

provenance-drop

Previous releases were built and signed by CI; this one was not

axios, nx

install-script

A new or changed preinstall / install / postinstall

keyv, nx, tinycolor

new-deps

New dependencies that are days old, run install scripts, copy a popular name, or are never imported (phantom)

axios

code-diff

Code new to this release: obfuscation, process execution, credential paths, exfiltration hosts, wallet hooks, AI-agent abuse (--dangerously-skip-permissions, SessionStart hooks), persistence, packed payloads

chalk, keyv, nx, tinycolor

release-timing

Published in the last 24 h; bursts of versions

all (weak alone)

name-check

Look-alikes of ~2,400 popular names with few downloads or a recent creation date

typosquats, hallucinated names

known-advisory

OSV MAL- entries for the exact version

anything already reported

Weights: warn 15, high 35, critical 70. Any critical finding blocks; otherwise the sum decides: < 30 ALLOW, 30–69 REVIEW, ≥ 70 BLOCK. Versions with incomplete checks require at least REVIEW and are excluded from safe-version suggestions. Packages that don't exist (hallucinated names), versions npm removed, and npm's -security placeholders are blocked outright.

Benchmark

npm run bench replays the five hijacks and checks the latest release of the 200 most downloaded npm packages (presumed healthy; list in bench/packages.txt) to measure false positives. Latest run (bench/RESULTS.md):

  • Replayed hijacks: 5 / 5 BLOCK, none of which OSV knew about at the replay time.

  • 200 popular releases: 199 ALLOW, 1 REVIEW, 0 BLOCK. The REVIEW is TypeScript 7, a full rewrite published by a new account: exactly the kind of release a human should glance at. REVIEW means "ask the human", not "block". (An earlier 60-package sample also caught fresh webpack/next/vitest releases as REVIEW; results move as npm does.)

Live endpoint smoke test: node scripts/smoke.mjs calls every tool, resource and prompt on the deployed server, plus 17 hostile inputs (path traversal, __proto__, broken JSON, oversized bodies, unknown versions). GitHub Actions runs it hourly and after every push; latest live run passes all must-checks (p50 0.4 s, p95 2.3 s).

How we got here: the first run flagged webpack and vitest as BLOCK (bundlers rename chunk files every release). Two independent security reviews found 16 issues in the first review and 10 in the second (Oct 17); all findings were fixed. The fixes include line-based code diffs, guard decisions limited to deny/ask while preserving host permission prompts, parsing wrapped commands and subshells, checking every package, API-key support, REVIEW for incomplete checks (excluded from safe-version suggestions), resolving npm aliases, flagging git/URL specs, and always checking packages even when publisher names match. Numbers will move as npm does; CI re-runs the replays on every push.

How it compares (honestly)

Tool

When it acts

Gap Dep Bouncer fills

npm audit, Dependabot, OSV

After an advisory is published

Advisories arrived 1.7–18 h after these hijacks

Socket Firewall Free, Aikido Safe Chain

At install, against the vendor's malware feed

Blocklists: they block once the vendor has flagged a package. Dep Bouncer judges the release from its own history, explains why, and names the version to use. Complementary.

Cooldowns (min-release-age, pnpm 11 default)

Hold every release for N hours

Would have held all five hijacks, and every urgent security fix too. Dep Bouncer lets clean fresh releases through and shows cooldown status.

npm 12 script blocking

Skips install scripts until approved

Approval without explanation; does nothing for code that runs on import (chalk).

Provenance

Proves where a release was built

keyv 6.0.0 had valid provenance.

Socket GitHub app

On pull requests

Agents install from the terminal, not through PRs.

Socket MCP depscore, slopsquat checkers

Scores, fake names

Scores without evidence or a safe version; fake names only.

Replayed incidents are labelled reconstructions

npm removed the malicious versions. Each replay uses the real last-good release (manifests, files, publish times, fetched from the registry by scripts/build-fixtures.mjs) plus the documented changes of the bad release, with benign stand-in code that only mimics the structure of the attack. Every stand-in file starts with /* Dep Bouncer reconstruction: benign stand-in, not real malware. */, and every replay result says what is real and what was reconstructed, with sources. No malware was downloaded or stored.

Architecture

flowchart LR
  Agent[AI coding agent] -- MCP --> Tools[bouncer tools / resources / prompt / widget]
  Tools --> Bouncer[BouncerService]
  Bouncer --> Registry[NpmRegistryService\npackuments, downloads]
  Bouncer --> Tarball[TarballService\nin-memory tar.gz, size caps]
  Bouncer --> OSV[OsvService]
  Bouncer --> Analysis[AnalysisService]
  Analysis --> Signals[8 signals] --> Verdict[verdict engine]
  Bouncer --> Incidents[IncidentsService\nreplay fixtures]
src/
  modules/registry/    npm registry, downloads, OSV clients; tar.gz parser; semver; TTL cache
  modules/analysis/    signal contract, signals/*, code patterns, name similarity, verdict
  modules/incidents/   reconstructed incident fixtures + replay service
  modules/bouncer/     MCP tools, resources, prompt; orchestration service
  health/              system, npm registry and OSV health checks
  widgets/app/verdict-card/   the verdict widget
scripts/               build-fixtures, build-popular, benchmark, copy-assets
test/                  node:test suites (signals, parser, replays, semver, ...)

NitroStack features used: DI modules and @Injectable, @Tool / @Resource / @Prompt, @Widget, @RateLimit, @Cache, an interceptor (MetricsInterceptor), guards (ApiKeyModule + @UseGuards), MCP Tasks (taskSupport, progress, cancellation), @HealthCheck (system, npm registry, OSV), and the bouncer://stats resource for live per-tool latency, errors and verdict totals.

Safety: Dep Bouncer never executes package code; tarballs come only from registry.npmjs.org and are parsed in memory (25 MB compressed, 60 MB extracted, 5,000 files, path-traversal checks), with byte-budgeted caches, a 4-way download semaphore and redirect checks. No user data stored; metrics hold no request contents or IPs.

Authentication: the public demo is open on purpose (read-only, public data, rate-limited, so judges and agents can try it). Set DEP_BOUNCER_API_KEYS=key1,key2 to require an API key (NitroStack ApiKeyModule; clients send it in MCP _meta.apiKey). See .env.example.

Use it

Any MCP client (Claude, ChatGPT, Cursor, NitroChat): add a remote MCP server with the URL above. Cursor ~/.cursor/mcp.json:

{ "mcpServers": { "dep-bouncer": { "url": "https://dep-bouncer-6ad22414-giberelin-heapify-global-community.app.nitrocloud.ai/mcp" } } }

Then ask: "Use the safe_install prompt, then add axios to this project."

Run locally:

npm install
npm run build
npm test            # 220 tests, offline (CI on Node 22 and 24)
npm run bench       # replays + false-positive scan (needs network)
npm run dev         # stdio, for NitroStudio

No environment variables are required. Optional (see .env.example): MCP_TRANSPORT_TYPE (stdio / http / dual), PORT, NITRO_LOG_LEVEL.

Limitations and roadmap

  • Heuristics: a determined attacker can write code that avoids the patterns; the publisher, provenance, script and dependency signals still apply. Tarballs over 25 MB (e.g. next) skip the code diff and require REVIEW for incomplete coverage.

  • npm only. Next: PyPI, lockfile/CI mode, org policies (e.g. "always REVIEW new publishers").

Team

Harsha B S (team Giberelin, Heapify Global Community) · MIT License · Architecture walkthrough

Available Tools

7 tools
bouncer_check_manifestA
Read-only

Checks every dependency in a package.json at the version npm would install for its range today (the newest match), e.g. before running npm install in a cloned repo. Runs as an MCP Task with live progress; returns BLOCK/REVIEW first, each with the reason and a safe version.

NameRequiredDescriptionDefault
includeDevNoAlso check devDependencies
packageJsonYesThe full text of package.json (up to 90 KB)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint; the description adds meaningful behavioral context: it runs as an MCP Task with live progress, and the return payload leads with BLOCK/REVIEW entries each carrying a reason and a safe version. That output-ordering and async-execution detail is real value beyond annotations, though it doesn't cover latency, result size, or what REVIEW implies operationally.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose and scope, then the usage cue and return contract. No filler, and every clause contributes information the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so partially — it names BLOCK/REVIEW, ordering, reasons and safe versions. What BLOCK versus REVIEW means for the caller's next action, and whether the result also lists passing dependencies, is left implicit, which is the only real gap for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both parameters documented inline (including the 90 KB cap and the includeDev devDependencies behavior). The description adds no parameter-level detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Checks every dependency in a package.json') plus a precise scope qualifier — the version npm would install for the range today, i.e. newest match. This distinguishes it from siblings like bouncer_check_package and bouncer_check_upgrade, which operate on different inputs or questions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete triggering scenario — 'before running `npm install` in a cloned repo' — so the agent knows the intended moment of use. It does not, however, name an alternative sibling or state when not to use it, which keeps it short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_check_packageA
Read-only

Call this BEFORE npm install <pkg> or adding a dependency. Compares the release with the package's own history (publisher, provenance, install scripts, new dependencies, code diff, name) and returns ALLOW, REVIEW or BLOCK with evidence, what npm audit/OSV say, and a safe version to install instead when blocked.

NameRequiredDescriptionDefault
nameYesnpm package name, e.g. "axios" or "@ctrl/tinycolor"
versionNoExact version, dist-tag or range. Defaults to "latest".

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint; the description goes well beyond that by disclosing the output shape (ALLOW/REVIEW/BLOCK with evidence), the fact that it cross-references npm audit/OSV, and that it recommends a safe alternative version when blocked. It omits latency/rate-limit or data-source freshness caveats, but the behavioral disclosure is substantially richer than the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with the imperative trigger before the mechanism and return values. Every clause contributes (trigger, comparison basis, verdicts, evidence, audit cross-check, fallback suggestion); the parenthetical signal list is long but information-bearing rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly carries the burden of explaining returns — verdict categories, supporting evidence, audit results, and a suggested safe version. Combined with the 100%-covered input schema and the read-only annotation, an agent has enough to call and interpret the tool correctly; only sibling disambiguation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — both `name` and `version` are documented in the schema, including format examples and the "latest" default. The description adds no parameter-level detail (e.g., how a range behaves vs. a dist-tag), so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action (compare a release against the package's own history) and enumerates the exact signals inspected — publisher, provenance, install scripts, new dependencies, code diff, name. It clearly positions itself as the broad entry-point check, which implicitly distinguishes it from narrower siblings like bouncer_diff_release and bouncer_review_install_scripts, though it never names them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Call this BEFORE `npm install <pkg>` or adding a dependency" gives an explicit, unambiguous trigger for when to invoke the tool. It does not, however, contrast itself with the sibling bouncer_check_upgrade or say when the granular tools (diff_release, review_install_scripts) are preferred over this aggregate check.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_check_upgradeA
Read-only

Call this before bumping a dependency from one version to another. Returns the verdict on the new version plus what changed between the two (publisher, provenance, install scripts, dependencies).

NameRequiredDescriptionDefault
toYesVersion the agent wants to upgrade to
fromYesVersion currently installed
nameYesnpm package name, e.g. "axios" or "@ctrl/tinycolor"

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, openWorldHint), so the bar is lower. The description still adds real behavioral value by promising a "verdict" and enumerating the change categories surfaced (publisher, provenance, install scripts, dependencies) — exactly the kind of context an agent needs before a version bump.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both earning their place: the first gives the call trigger, the second the return content. The most actionable instruction (when to call) is front-loaded with no preamble.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does describe the result (verdict + changed fields). It leaves the verdict's possible values or thresholds undefined, which is a modest gap for a gate-style tool but not a fatal one.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter (name, from, to) is documented in the schema itself. The description restates the from→to relationship but adds no syntax, format, or constraint detail beyond what the schema already provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (check) and a specific resource (a dependency upgrade from one version to another), and the from→to framing distinguishes it from sibling bouncer_check_package, which presumably inspects a single version. It never names the siblings explicitly, so the differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Call this before bumping a dependency from one version to another" gives an explicit trigger point (pre-upgrade gate), which is clear operational guidance. It does not say when NOT to use it or name alternatives such as bouncer_safe_version or bouncer_check_package, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_diff_releaseA
Read-only

Raw evidence for humans: what changed between two versions of a package (publisher, provenance, install scripts, dependencies, files added/removed/changed, and risky code patterns new in this release). Use it to explain a REVIEW or BLOCK.

NameRequiredDescriptionDefault
toYesNewer version
fromYesOlder version
nameYesnpm package name, e.g. "axios" or "@ctrl/tinycolor"

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds that output is 'raw evidence for humans' and lists the data categories returned, which is useful, but it discloses nothing about cost, rate limits, or bulk/verbosity behavior for a tool that fetches a full package diff.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence, front-loaded with the 'Raw evidence for humans' framing followed by the enumerated contents and the usage call-to-action. No filler, though the parenthetical list is dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so by enumerating the diff's contents. Combined with annotations covering the safety profile, an agent has enough to call and interpret it, though the human-vs-machine output distinction could be clearer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with name/from/to all documented in-schema (including the npm scoped-name example), so the baseline of 3 applies. The description adds no syntax, ordering, or range guidance beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (diff two versions of a package) and enumerates the exact dimensions covered: publisher, provenance, install scripts, dependencies, file changes, risky code patterns. It is distinguishable from generic checks, though it never names an overlapping sibling like bouncer_check_upgrade or bouncer_check_package.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The closing clause 'Use it to explain a REVIEW or BLOCK' gives a real usage context tied to sibling outputs, but there is no when-not guidance and no explicit alternative named among the six siblings that could also surface version-change data. Usage is implied rather than prescribed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_replay_incidentA
Read-only

Replays a real npm hijack through Dep Bouncer, as an agent would have met it 30 minutes after publication, before any advisory existed. Incidents: axios (2026), keyv (2026), chalk (2025), nx (2025), tinycolor (2025). The malicious versions were removed from npm, so the bad release is a clearly labelled reconstruction with benign stand-in code.

NameRequiredDescriptionDefault
incidentYesWhich incident to replay

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose readOnly and closed-world behavior, and the description adds meaningful context beyond them: the data is a labelled reconstruction with benign stand-in code because the real malicious versions were pulled from npm. It does not cover latency, auth, or exactly what is returned, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core purpose, and the reconstruction caveat is well placed at the end where it is most relevant. The incident enumeration overlaps the schema enum but the appended years give it enough extra value to be defensible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only tool this is mostly sufficient, and the simulation framing is clear. However with no output schema the description never indicates what a replay returns, which an agent would reasonably want to know before invoking it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and one enum governs the single parameter, so the baseline is 3. The description restates the enum values and adds years (axios 2026, keyv 2026, chalk 2025, nx 2025, tinycolor 2025), which is contextual flavor but does not change how the parameter is supplied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific action (replays a real npm hijack) and the exact artifacts involved, and its scenario/simulation nature cleanly separates it from the check_* siblings. The verb 'replays' is slightly ambiguous about what the caller actually receives, keeping it out of 5 territory.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The framing 'as an agent would have met it 30 minutes after publication, before any advisory existed' implies the intended scenario (seeing pre-advisory behavior), but there is no explicit when-to-use, when-not-to-use, or pointer to the check_* siblings for real-world verdicts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_review_install_scriptsA
Read-only

npm 12 skips dependency install scripts until they are approved (npm approve-scripts), but only shows the command. Pass the packages it lists; for each one this returns the scripts, why, and APPROVE / REVIEW / DENY. Also useful on npm 11 to see which dependencies run code at install time.

NameRequiredDescriptionDefault
packagesYesPackages whose install scripts need a decision (max 15)

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description usefully adds that the tool returns the actual scripts, the reasoning behind each verdict, and a tri-state decision value — meaningful behavioral context given there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the npm 12 rationale before the action and the npm 11 fallback use. The npm context sentence is justified because it explains why the tool exists, and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only tool with no output schema, the description covers the workflow trigger, what it returns, and an alternate use case. It leaves minor gaps around output shape and limits (max 15), but those are handled by the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the `packages` array with name/version fields. The description only echoes this ('pass the packages it lists') without adding format or selection guidance, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: it reviews dependency install scripts and returns scripts, rationale, and APPROVE/REVIEW/DENY verdicts. It differentiates from siblings by narrowly scoping to install-script approval rather than general package checks, though it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear triggering context — use it on the packages npm 12's `approve-scripts` lists, and note it works on npm 11 to reveal which deps run install-time code. It does not name alternative sibling tools or state exclusions, so it stops short of a full when/when-not guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bouncer_safe_versionA
Read-only

Returns the newest version of a package (optionally within a semver range such as "^1.14.0") that passes every Dep Bouncer check, and which newer versions were skipped and why. Use it to pick what to install instead of a blocked release.

NameRequiredDescriptionDefault
nameYesnpm package name, e.g. "axios" or "@ctrl/tinycolor"
rangeNoSemver range, e.g. "^5.0.0". Defaults to any stable version.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety and network-touching profile is covered. The description adds genuinely new behavioral detail: it reports which newer versions were skipped and the reason, which an agent could not infer from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler, and the core behavior (what is returned) is front-loaded before the usage hint. Nothing is redundant or buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining returns and does so well (newest passing version plus skipped versions and reasons). It stops short of specifying the exact return shape or how version ordering/range edge cases are handled, which is a minor but real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented in the schema, including the semver range example and the default of any stable version. The description merely echoes the range concept, adding little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (returns the newest version of a package) and a precise scope (only versions passing every Dep Bouncer check, optionally constrained by a semver range). This is clearly distinguishable from sibling check-style tools because it resolves to a concrete installable version rather than a verdict.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use it to pick what to install instead of a blocked release" gives explicit context for when this tool is the right choice. It does not name a specific alternative sibling (e.g. bouncer_check_upgrade) or state exclusions, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool update
    • Changedbouncer_check_manifest2 fields changed
      • changedInput schema / properties / packageJson / description
        Previous value: -"The full text of package.json"New value: +"The full text of package.json (up to 90 KB)"
      • changedInput schema / properties / packageJson / maxLength
        Previous value: -200000New value: +90000
  2. 7 tool updatesv1.0.0
    • First observedbouncer_check_manifest
    • First observedbouncer_check_package
    • First observedbouncer_check_upgrade
    • First observedbouncer_diff_release
    • First observedbouncer_replay_incident
    • First observedbouncer_review_install_scripts
    • First observedbouncer_safe_version

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation4/5

The three check tools (check_package, check_upgrade, check_manifest) target related but distinct contexts (single install, version bump, full manifest), and the descriptions explicitly state when to call each. review_install_scripts, safe_version, diff_release, and replay_incident are clearly separate purposes, though the check trio could still be confused at a glance.

Naming Consistency4/5

All tools use a consistent bouncer_ prefix with snake_case and mostly verb_noun form (check_package, diff_release, replay_incident, review_install_scripts). safe_version is a minor deviation lacking a verb, but the overall pattern is predictable.

Tool Count5/5

Seven tools is well-scoped for a dependency-security verdict server, with each tool earning its place across pre-install checks, version selection, evidence, and install-script review.

Completeness4/5

The surface covers the core lifecycle: checking packages, upgrades, and manifests, plus safe-version selection, raw diffs, and install-script review. It lacks obvious config/allowlist management or bulk/CI scan operations, but the primary agent workflows are covered with no hard dead ends.

Maintenance

ActivityNo data
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to automatically verify npm packages against the live registry before installation, flagging hallucinated, slopsquatted, or otherwise suspicious packages with risk verdicts.
    2 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI coding agents and CI to vet npm dependencies before they reach the lockfile, flagging hallucinated, slopsquatted, or otherwise risky packages with evidence-backed verdicts.
    3
    101 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to verify, compare, and safely upgrade npm packages by scoring packages from public signals and sandboxed co-installation, detecting breaking API surface changes, and rewriting code that upgrades break.
    86 npm
    8
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables developers and AI coding agents to vet npm packages before installation by checking existence, lookalike names, package age, install scripts, maintainers, downloads, and advisories, returning GO, RISKY, FAKE, or MISSING. It also scans a project's package.json for worst-first dependency verdicts and can run as a CLI or stdio MCP server.
    MIT