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~/.sshand~/.aws. - A
GITHUB_TOKENpasted straight intoclaude_desktop_config.json. defaultMode: bypassPermissionsset once for a demo and never removed.- A skill from a gist that reads credentials and
curls them somewhere on every run. - A
fetchserver (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 reach — untrusted-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 toapi.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.
blastradiusflags 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.
--cionly 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
--fixmode 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.
npx blastradius