Overview
It targets MCP revision 2025-06-18. It also answers a client that asks for 2025-03-26 or 2024-11-05. Messages are JSON-RPC 2.0, one per line, on stdin and stdout. Nothing else is written to stdout.
Part 1
Register it #
Claude Code:
$ claude mcp add blastradius -- br mcpWithout installing br first, through npm:
$ claude mcp add blastradius -- npx -y @jondot/blastradius mcpUse one client's index by setting BR_HOME in the server's environment:
$ claude mcp add blastradius -e BR_HOME=$HOME/clients/acme -- br mcpAny client with a JSON config (Claude Desktop, Cursor, Zed and others):
{ "mcpServers": { "blastradius": { "command": "br", "args": ["mcp"], "env": { "BR_HOME": "/home/me/.blastradius" } } } }Build the index first with br init; the server reads it and never builds one.
Part 2
Tools #
| Tool | Arguments | Returns |
|---|---|---|
hunt | indicators (array) or advisory; path, repo, owner, host, now, only, window | A one-line summary (verdict, findings, places, gaps) and the JSON br hunt --format json prints |
status | all, owner | A summary line and br status output: how fresh each source is |
advisory_show | id | br advisory show output for an advisory the index or your notes hold |
hosts | none | br hosts list output |
evidence_summary | file | The claim, verdict, counts and gaps of an evidence file already written, and the result of checking its seal |
claimcheck | path, repo, org, max_names (0 or more, the CLI default is 400), as_of | Which of your package names are FREE, SQUATTED or SCOPE UNCLAIMED on the public registries, with the flags and where each name was seen. Makes read-only GETs to public registries; writes nothing |
Every result has a summary block first, then the output. A hunt with no findings says CLEAR WITH GAPS and the number of sources not checked: an agent must pass that on, not say "clear".
A hunt that finds something is a normal answer (isError is false). isError is true when br itself fails, such as no index (exit 5) or a bad indicator, and the text carries br's message and hint. Bad arguments (an unknown field, a value that starts with -) are also tool errors. An unknown tool name is JSON-RPC error -32602 and an unknown method -32601.
Part 3
What it never does #
- It does not scan, init, import, write a note, notify, fix, purge or write evidence. Those stay in the CLI, and none is a tool.
claimcheckis the one tool that uses the network: it makes read-only GETs to the public registries (npmjs.org, pypi.org, crates.io, proxy.golang.org) and, withoutpath, reads the index's repos through the GitHub API (needs a token). It writes nothing: no index, no cache, no BR_HOME, and it cannot pass--record, so it never stores a snapshot. Itsmax_namesis the CLI's (0 or more, default 400). It never publishes or claims a name. An unreachable registry is a gap, not a clear answer.- Apart from
claimcheck, it does not ask OSV or any network: an advisory id must already be in the index or your notes (br advisory note), or be a local file. A miss comes back as a tool error. This is because a lookup caches the record in the index, and this server writes nothing. - It cannot be given a flag: arguments are fixed fields, and any value starting with
-is refused.--liveand--yaraare not reachable. - Each tool starts
bragain with fixed arguments (the same binary), so a tool answers exactly as the CLI does.
Part 4
Try it by hand #
$ printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"me","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"hunt","arguments":{"indicators":["npm:left-pad@1.3.0"]}}}' | br mcp