npm.io
0.3.2 • Published yesterdayCLI

@metanolabs/blastradius

Licence
MIT
Version
0.3.2
Deps
0
Size
130 kB
Vulns
0
Weekly
0

blastradius

Find out what your AI agents can actually reach.

You installed a coding agent. Then an MCP server. Then a skill a colleague shared. Each one asked for a little access. Nobody kept the running total.

blastradius computes that total — it maps every agent, MCP server, and skill on a machine or in a repo to the credentials, files, and systems it can touch, then draws the blast radius of a single compromised prompt.

npx blastradius

No install. No account. No network. Nothing executes. It reads config files and does math.


Why this exists

The security question for the last decade was "who is this user and what are they allowed to do?" Identity, SSO, RBAC — a mature stack answers it.

Agents broke the question in two. An agent is an identity (it has credentials) and it takes actions on its own, chaining tools at machine speed. So the real question is now: if one instruction in a web page, an email, or a GitHub issue hijacks this agent, how far does the damage go?

That's the blast radius. And almost nobody can answer it for their own laptop, because the access was assembled one harmless-looking config edit at a time:

  • A filesystem MCP server rooted at ~ — which quietly includes ~/.ssh and ~/.aws.
  • A GITHUB_TOKEN pasted straight into claude_desktop_config.json.
  • defaultMode: bypassPermissions set once for a demo and never removed.
  • A skill from a gist that reads credentials and curls them somewhere on every run.
  • A fetch server (reads untrusted web content) sitting in the same agent as a database server (reads private data) and a webhook tool (sends data out) — the lethal trifecta, wired together by accident.

Each is defensible alone. Together they're a pre-assembled exfiltration path. blastradius is the running total nobody was keeping.

What you get

  blastradius  ·  agent reach map
  ─────────────────────────────────────────────

  Discovered  2 agents  ·  7 MCP servers  ·  1 skill

  ◆ Claude Code (claude-code)
      filesystem [filesystem,private-data]
      fetch [untrusted-input,exfil]
      github [code-write,exfil]
      shell [filesystem,exec,private-data]
      postgres-prod [exfil,private-data]
      ⚠ approval bypassed

  ◆ Cursor (cursor)
      slack [untrusted-input,exfil]

  ─────────────────────────────────────────────
  Blast radius score  100/100   grade F
  █████████████████
  7 critical  4 high  6 medium  0 low

Then one finding per problem, each with the exact file, the reason it matters, and the fix.

Run it yourself against a bundled (safe, fake) example:

npx blastradius --demo

What it looks at

blastradius auto-discovers agent configuration wherever it lives, then reads it. It never starts a server, never runs a skill, never makes a network call.

Agent MCP servers Skills Hooks / permissions
Claude Code
Claude Desktop
Cursor
Windsurf
VS Code / Copilot
Gemini CLI
Codex CLI
OpenClaw / Moltbot
Amp
Goose

The checks

Every server and skill is classified by what it can reachuntrusted-input, private-data, filesystem, exec, exfil, code-write, infra — and then rules fire on dangerous combinations and configurations:

ID Severity What it catches
BR001 critical Plaintext credential (token / key / password) sitting in an agent config
BR002 critical / high Human approval disabled, or tools auto-approved with wildcards
BR003 medium Unpinned MCP server (npx -y …@latest) — silent supply-chain swap
BR004 high Filesystem server rooted at your whole home directory
BR005 critical Agent scoped directly into a credential store (~/.ssh, ~/.aws, …)
BR006 critical Secret committed to a project-scope config that ships with the repo
BR007 high Shell-capable server (command execution = RCE if input is untrusted)
BR008 critical Lethal trifecta — one agent that reads untrusted input, holds private data, and can send data out
BR009 high / low Lifecycle hooks, flagged hard when they contain curl / eval / raw shell
BR010 critical / high Skills combining risky primitives — network + credential reads + encoded blobs
BR011 critical / high / med Known-vulnerable dependency — MCP server launches a package with OSV.dev advisories (needs --osv)
BR012 critical Malicious package — a dependency in an agent's install tree is flagged malicious by OSV.dev (needs --osv)
BR013 high / med Third-party-hosted MCP endpoint — a remote server you don't control, whose supply chain can't be scanned locally

The lethal trifecta (BR008) is the one most people can't see by eye, because the three legs live in three different config files. blastradius correlates across all of them.

Output formats

npx blastradius                 # human-readable terminal report (default)
npx blastradius .               # this repo only (project-scope configs)
npx blastradius --html > r.html # self-contained shareable report (screenshot-friendly)
npx blastradius --json          # machine-readable, everything
npx blastradius --sarif         # SARIF 2.1.0 → GitHub code scanning
npx blastradius --agentbom      # an AgentBOM inventory artifact (see below)
npx blastradius --osv           # also check dependencies against OSV.dev (networked; see below)
npx blastradius --ci            # exit 1 on any high/critical — drop into a pipeline
Supply-chain check (--osv)

MCP servers are usually installed from public registries — npx @scope/server, uvx some-tool — which means every agent quietly pulls a tree of packages that run code on your machine with the agent's full reach. The dangerous ones are rarely the package named in the config; they're the transitive dependencies buried under it.

--osv reads the actually-installed dependency tree off your filesystem — the npx cache (~/.npm/_npx), project lockfiles, global npm installs, and pipx / uv virtualenvs — resolves exact versions (including transitive), and checks every one against OSV.dev, which covers npm, PyPI, and flagged malicious packages (the MAL- advisories):

npx blastradius --osv

Before trusting the check, verify detection on your machine — this lists everything the collector can see, offline:

npx blastradius --deps

What the collector reads (Windows, macOS, and Linux):

Ecosystem Sources
npm npx cache; global installs (honoring .npmrc/npm_config_prefix, nvm, fnm, Homebrew, %APPDATA%\npm); project package-lock.json, yarn.lock, pnpm-lock.yaml, node_modules
PyPI pipx venvs, uv tool installs, user site-packages; project poetry.lock, Pipfile.lock, uv.lock, requirements.txt, .venv/venv

It never runs a package manager — it parses lockfiles and installed metadata directly, so it's read-only and works offline for the discovery step.

  • BR012 (critical) — a package anywhere in an agent's install tree is flagged malicious (typosquat, hijacked release, backdoored postinstall). This catches transitive packages, not just the one in the config.
  • BR011 — a package with known CVEs, severity from the advisory. Findings name the offending package and trace it back to the server that pulled it in.

Three cases, three answers:

Where the code lives What blastradius does
Installed locally (npx cache, venv, lockfile) Reads the real tree, checks every package against OSV — including transitive deps
Named in config but not yet cached Falls back to checking the top-level package by name
Hosted by a third party (remote url:) Can't scan it — the tree lives in their environment. Raises BR013 instead: a trust-boundary finding naming the host, its reach, and whether you're handing it a token

This is the one networked feature. Everything else is offline. When you pass --osv, package names, ecosystems, and versions are sent to api.osv.dev — never credentials, file contents, or paths. Dependency discovery is fully local (reading files); only the OSV lookups use the network. If OSV is unreachable (air-gapped, timeout), the check is skipped with a warning and the offline scan still completes.

AgentBOM

An AgentBOM is a portable inventory of every agent capability in a scope, deliberately shaped like an SBOM so it can sit next to CycloneDX in a supply-chain pipeline. It answers "what can our agents reach?" in a diffable, checkable artifact. With --osv it also records each server's package coordinates and any known vulnerabilities:

npx blastradius --agentbom > agentbom.json        # inventory + reach
npx blastradius --agentbom --osv > agentbom.json  # + supply-chain vulns

Commit it. Diff it in PRs. When a new server or skill widens the blast radius, the diff shows it before it merges.

Use it in CI

Fail a build when someone widens the blast radius or commits a secret to an agent config:

# .github/workflows/blastradius.yml
name: blastradius
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npx blastradius . --ci

Or upload SARIF so findings show up in the Security tab:

      - run: npx blastradius . --sarif > blastradius.sarif
        continue-on-error: true
      - uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: blastradius.sarif }

Design principles

  • Read-only, offline by default, zero-dependency. It reads files and does arithmetic. Auditing it takes ten minutes — the whole point is that a security tool for AI agents shouldn't itself widen your blast radius. Compare that to scanners that need an account, an API token, or that phone tool descriptions home.
  • Local by default. No telemetry, no bootstrap request, no "share your tools for research." What's on your machine stays on your machine — unless you opt into --osv, which sends only package names/versions to OSV.dev and nothing else.
  • Reach, not signatures. It doesn't look for known-bad strings. It models what each component can do and flags dangerous combinations — which is where real agent incidents come from.

How it compares

Static MCP scanners (e.g. mcp-scan) do a great job on one axis: is a given tool description malicious (prompt injection, tool poisoning, rug pulls)? That's necessary and complementary.

blastradius answers a different question — the aggregate reach across every agent, server, skill, hook, and permission on the box, and the cross-config combinations (the lethal trifecta, credentials + broad filesystem, exec + untrusted input) that no single-tool scan can see. Run both.

Scope & limits

Being explicit about what a local scanner can and can't see:

  • It reads what's on disk. The supply-chain check reflects the dependency tree currently installed (npx cache, venvs, lockfiles). A dependency that gets pulled fresh at the next launch, with nothing cached yet, isn't visible until it lands on disk.
  • Hosted MCP servers are out of reach by design. If a server runs in a third party's environment, its code and dependencies live there — no local tool can inventory them. blastradius flags the trust boundary (BR013) and leaves the dependency posture to the provider's own SBOM. Ask them for it.
  • It reasons about reach, not proven exploits. A finding means a dangerous path exists (a capability, a combination, a known-bad package), not that it has been exploited. Treat the score as an exposure estimate, not a breach probability.
  • --ci only sees what's committed. A build-time gate catches configs in a repo. The riskiest configs often live on laptops (~/.claude.json) and never reach CI — which is the gap that argues for runtime enforcement, not just static scanning.

Roadmap

  • More agents (JetBrains AI, Zed, Continue, Aider) and remote/HTTP MCP transports
  • A --fix mode that scopes filesystem roots and migrates inline secrets to ${ENV}
  • Toxic-flow tracing across agent-to-agent delegation chains
  • A shared, versioned reach-classification ruleset (agent-rules) so the community can add servers

PRs welcome — especially new agent config locations and server capability mappings. See src/discover.js and src/parsers.js; both are small and commented.

FAQ

Does it send my configs anywhere? By default, no — it makes zero network calls and reads a few hundred lines of dependency-free code you can audit in bin/blastradius.js and src/*.js. The one exception is opt-in: if you pass --osv, it sends package names and versions (not credentials, not file contents) to api.osv.dev to check for malicious and vulnerable dependencies. Without that flag, nothing leaves your machine.

Will it break anything? It can't. It only reads files. It never launches a server or runs a skill.

Why Node with no dependencies? So npx blastradius just works, and so the supply chain of a security tool is exactly zero third-party packages.

Who made this? Metano Labs. We build runtime security for AI agents. This is the free, offline, "know your exposure" front door to that problem. If you want runtime enforcement and cross-agent correlation once you've seen your blast radius, that's what we do.


MIT licensed · nothing leaves your machine · npx blastradius

Keywords