harrisahmad.dev

Open source · MIT

BlastRadius

Cross-repo infrastructure memory for coding agents. It knows who else depends on an artifact before you change it, and watches those pins for vulnerabilities while nobody is asking.

Result39/39 artifacts found · 39/39 version specs intact · 0 false positivesplanted 6-repo corpus

pip install blastradius-mcp

01problem

The problem

A coding agent is excellent inside one repository and blind across many. Bump a base image, retag a GitHub Action, move a Terraform module — nothing tells you the four other repositories pinning the same thing. The knowledge exists. It just isn’t anywhere the agent will look.

This is not a code graph. Excellent tools already index functions, classes and imports. BlastRadius indexes the other half — the infrastructure artifacts — and answers the question a single session cannot: if I bump this, who breaks?

02decision

The idea: hooks, not tools

An MCP server can expose a perfect tool and the model can simply not call it. Nothing errors, nothing is misconfigured — the information just doesn’t arrive, and you cannot tell “no impact found” from “never asked.”

Hooks invert that. The harness runs them, so what they return lands in context whether the model wanted it or not. That single distinction decided the architecture.

  1. Agent reads package.jsonthenPreToolUseinjectthenCross-repo impact, unprompted
  2. Session endsthenStopcapturethenIndex learns this repo
Tradeoff

The tradeoff is real: you spend context on every matching tool call, deterministically. So the cost is measured rather than assumed — blastradius cost reports what every injection spends — and it stays silent unless something is genuinely shared.

Architecture — When the agent reads, edits or runs a command on a manifest, a PreToolUse hook looks up the local SQLite index and injects which other repos depend on that artifact and how tightly each pins it (blue path). At Stop, a second hook lists manifests the index hasn’t seen, and the agent records them through the MCP server, which reads exact versions from lockfiles. Outside the session (dashed), a launchd/systemd watcher syncs OSV advisories into the same index and can post new ones to Slack.
03in practice

What it does unasked

Open a repo, ask for something ordinary — “bump react to 19” — and before the agent reads a line of package.json, a hook has already told it:

acme/checkout (a separate repo) also depends on react@^18.2.0, and lodash here is shared with acme/notifications and acme/checkout too.

Two repositories that were not open, not mentioned, and have no trace in the working directory. The agent never called a tool to find them.

04output

And what it produces

  • 43advisories from OSV
  • 9that apply to your pinned versions
[CRITICAL] vitest                 CVE-2026-47429
           When Vitest UI server is listening, arbitrary file
           can be read and executed
           reaches: 3.2.4  (installed version)
           in:      acme/checkout
[HIGH    ] lodash                 CVE-2021-23337
           lodash vulnerable to Code Injection via `_.template`
           reaches: 4.17.21, ^4.17.21

Advisories are matched against what your pins can actually resolve to. A manifest saying ^5.2.0 permits a vulnerable 5.2.0; the lockfile saying 5.4.19 permits none of them. For vite alone that is the difference between 13 alerts and 6. Anything unknowable — a floating tag, a digest, a git ref — stays flagged, because hiding a real vulnerability is far worse than showing one that turns out not to apply.

05result

Measured, not asserted

Extraction is scored against a planted corpus of six repositories with the hard cases put there on purpose: multi-stage build aliases, ARG-templated base images, a FROM inside a heredoc, relative module sources, workspace: protocols, and a registry with a port that looks like a tag.

  • 39/39artifacts found
  • 39/39version specs intact
  • 0false positives
  • 6planted repositories
Note

The second number is the one that matters. A model that quietly normalises ^18.2.0 to 18.2.0 scores full recall while destroying the entire signal — the range operator is the information. Recall alone would report 100% on output that is worthless.

06install

Install

Everything is local: one SQLite file at ~/.blastradius/index.db. No account, no server, no API key, nothing leaves your machine.

pip install blastradius-mcp

blastradius install     # wire hooks + MCP server into Claude Code
blastradius doctor      # verify — by running the hooks for real
blastradius index ~/code  # bootstrap from repos you already have

Or as a Claude Code plugin:

/plugin marketplace add harris-ahmad/blastradius-mcp
/plugin install blastradius@blastradius
Bootstrap

That last bootstrap step matters more than it looks. Capture runs when a session ends — after the reads — and cross-repo impact needs a second indexed repository before it has anything to say. Without it the tool is correct and completely silent for days.

Source

376 tests across 3.6K lines in 16 modules, run on Python 3.11–3.13. MIT licensed.