blast-scope-mcp

blast-scope-mcp

A consequence engine for shell commands. Blast Scope scores what a command would actually do before an AI agent runs it.

Category
访问服务器

README

Blast Scope

<!-- mcp-name: io.github.Atharva-Jayappa/blast-scope -->

A consequence engine for shell commands. Blast Scope scores what a command would actually do — before an AI agent (or you) runs it. It doesn't pattern-match syntax into a blocklist; it figures out the command's real target, observes that target with a safe, read-only probe, and returns a structured risk score with evidence.

The whole point is contextual blast radius. The same command gets a completely different score depending on what it would actually hit:

COMMAND                            SEVERITY   WHY                                          ADVICE
─────────────────────────────────  ────────   ──────────────────────────────────────────  ───────
rm -rf ./logs                      LOW        0 importers · regenerable · outside src      proceed
rm -rf ./config                    CRITICAL   8 modules import it · high PageRank hub      block
git reset --hard   (clean tree)    LOW        nothing uncommitted to discard               proceed
git reset --hard   (4 dirty files) HIGH       would throw away 4 files of uncommitted work confirm
git push --force   (protected)     CRITICAL   would orphan commits on a protected branch   block
docker volume rm cache  (absent)   LOW        volume doesn't exist — nothing to remove     proceed
docker volume rm pgdata (in use)   CRITICAL   holds data · in use · no image to rebuild    block
pip uninstall flask     (uv.lock)  LOW        regenerable — exact version pinned in lock   proceed
DROP TABLE users        (42 rows)  CRITICAL   schema + 42 rows · irreversible              block
DELETE FROM logs        (in txn)   HIGH       no WHERE — but inside a txn, ROLLBACK-able    confirm

Two commands can be byte-identical and score four bands apart. That gap is the product.

Not a blocklist. Not a replacement for Shellfirm. Not a syscall monitor. It scores structural consequence — advisory, never blocking — and for the rare critical command it captures an undo snapshot first.


How it works

A command flows through a cheap funnel: almost everything is recognized as non-destructive in microseconds and exits silent. Only a flagged destructive candidate pays for a probe.

  shell command
      │   split chains (&& || ; |) · de-alias PowerShell · parse flags/targets
      ▼
  ┌──────────────────────────────────────────────────────────────────────┐
  │  STAGE 1 · triage  (near-free regex — runs on every command)          │
  │     which class?   git · docker · pip/uv · sql · else filesystem       │
  │     destructive?   `git status` → no.   `git reset --hard` → yes ↓     │
  └───────────────────────────────┬──────────────────────────────────────┘
                    destructive candidate │   (everything else exits here, silent)
                                          ▼
  ┌──────────────────────────────────────────────────────────────────────┐
  │  ELIGIBILITY FILTER   safe read-only probe?   AND   undo authorable?   │
  └──────────────┬──────────────────────────────────────┬─────────────────┘
         yes, probe it │                       no probe here / now │
                       ▼                                           ▼
   STAGE 2 · safe probe (read-only)                    heuristic estimate
     git  status · reflog · rev-list                   from a static per-class
     docker  inspect · ps · ls                          table — and LABELED
     sqlite  SELECT count(*)  [mode=ro]                  "(estimated)" so you
     pip/uv  read lockfiles                              know it wasn't probed
                       │                                           │
                       └─────────────────────┬─────────────────────┘
                                              ▼
        blast radius  ×  reversibility   (combined PER CLASS — no global formula)
        filesystem also folds in: dependency-graph centrality + recoverability
                                              ▼
              score 0.0–1.0  →  severity (low / medium / high / critical)
                                              ▼
        PreToolUse hook:  silent (low/med) · advise (high) · advise + snapshot (critical)

The eligibility filter is the design boundary. A command class earns a live probe only when both hold: (1) its impact is observable by a strictly side-effect-free read (HTTP-GET sense — never mutate state to assess state), and (2) its undo story is well-known enough to encode in a static table. When a probe can't run here and now (no docker daemon, no DB driver, no creds), the tool degrades to a labeled estimate — it never guesses silently, and it never blocks.

See docs/heuristics.md for the per-class tables, the exact filesystem formula, and calibration.

The five command classes

Class Destructive ops it scores Safe (read-only) probe Reversibility signal
Filesystem rm -rf, mv, > truncate dependency graph + git status git-tracked? regenerable? secret? precious?
Git reset --hard, push --force, branch -D, clean -fdx status · reflog · rev-list · rev-parse @{u} reflog window · remote ahead · protected branch
Docker volume rm, system prune -a, rm -f volume inspect · ps -a · volume ls volume → none · container → recreatable from image
pip / uv pip uninstall, uv pip uninstall read lockfile / manifest (no subprocess) lockfile present → fully regenerable
SQL DROP, TRUNCATE, DELETE without WHERE SQLite: SELECT count(*) mode=ro; transaction check inside a transaction? backup posture?

New classes drop in behind one protocol (triage / assess) in src/blast_scope/classes/; each class confines assess to strictly side-effect-free reads.


Status

Calibrated multi-class guardrail with command resolution and a precise dependency graph.

Capability Module
Flag/operand-sensitive command model (POSIX and PowerShell) command_effects.py, command_parser.py
Command resolution — env/tilde/brace/glob expansion, unset-var hazards, script transparency (sh -c, npm run + pre/post hooks, script files, Makefile targets), read-only $(...) substitution resolution.py
Dry-run oracles — git clean -n exact lists, reset divergence, checkout clobber preview, find -delete→-print rewrite, sqlite scoped-DELETE counts, rsync --dry-run; oracle targets feed the undo snapshot classes/git.py, classes/find.py, classes/rsync.py, classes/sql.py
Recoverability classification (git state, secrets, regenerable, precious data) recoverability.py
Dependency graph + weighted PageRank centrality, incremental indexing graph_resolver.py, centrality.py
Two-axis, evidence-based filesystem scoring risk_scorer.py
Command-class probes — git / docker / pip·uv / SQL, behind one protocol classes/
Out-of-graph path analyzers (infra / config-by-path) + git base consequences.py, vcs.py, infra.py, config_refs.py
PreToolUse hook + tarball snapshot/undo hook.py, snapshot.py
Eval harness + labeled corpus + calibration eval.py, tests/fixtures/eval_corpus.jsonl

Calibration. Two harnesses, both run-it-yourself:

  • In-repo corpus (tests/fixtures/eval_corpus.jsonl, 58 cases spanning every recoverability category, git working-tree state, infra/config, rm -rf .git, a graph-indexed central module, the git/docker/pip/SQL classes, and the resolution layer — unset-var collapses, glob/env-var targets, sh -c payloads, npm pre-hooks, opaque wrappers, mass destruction of tracked source) — 58/58 exact severity, gate F1 1.00, pinned by tests/test_eval.py with headroom so changes can't silently regress.
  • SABER — 716 real coding-agent workspaces. Against ~1725 safe commands, blast-scope's false-positive rate is 0.58%; on its core competency (data_destruction) it catches 82.4% of injected attacks on realistic workspaces — on the fast hook path, no graph required, thanks to command resolution (env/glob binding + script transparency). Wrapper transparency also lifts code_tampering from ~0% to 50%. The per-category recall is deliberately uneven, and the table says so: blast-scope scores destructive consequence — filesystem/data loss plus git/docker/pip/SQL state. Network exfiltration and persistence are a different threat model, out of scope by design — not an unfinished corner. That's the boundary, drawn on purpose. See bench/.
uv run python -m blast_scope.eval                 # in-repo corpus
python bench/saber_eval.py --tasks <saber>/dataset/data/tasks.jsonl   # SABER

Installation

The fastest path for any MCP client is zero-install via uvx (no clone, no venv):

uvx blast-scope        # runs the MCP server on stdio

Claude Code users — one line wires up both the MCP tools and the advisory hook:

/plugin marketplace add Atharva-Jayappa/blast-scope
/plugin install blast-scope

For development, or to pin a checkout:

git clone https://github.com/Atharva-Jayappa/blast-scope.git
cd blast-scope && uv sync --all-extras

Usage

As an MCP server

Add to your MCP client config (e.g. Claude Code settings.json):

{
  "mcpServers": {
    "blast-scope": { "command": "uvx", "args": ["blast-scope"], "type": "stdio" }
  }
}

Tools exposed:

Tool Purpose
assess_command(command, cwd?, project_root?) Score a (possibly chained) command. Returns score, severity, rationale, evidence, recoverability, affected nodes, and a per-segment chain breakdown.
index_project(project_root) Force a dependency-graph rebuild (auto-built on first use otherwise).
list_snapshots(project_root) List undo snapshots, newest first.
restore_snapshot(snapshot_id, project_root) Undo a risky command by restoring its snapshot.

As a PreToolUse hook (tiered advice + auto-snapshot)

Intercept Bash commands before they run — advisory, never blocking. Volume scales with stakes: silent on low/medium, advise on high, advise + snapshot on critical. The snapshot skips what's already recoverable (git-clean, regenerable) and warns rather than tars anything over a hard size cap, so the undo net stays fast and trustworthy. Add to .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "python -m blast_scope.hook" }] }
    ]
  }
}

Full details and the undo flow: docs/hook.md.


Example output

A filesystem command, scored against the dependency graph:

// assess_command("rm -rf ./config", project_root="/proj")
{
  "score": 0.93,
  "severity": "critical",
  "recommendation": "block",
  "recoverability": "untracked",
  "rationale": "rm targets config. 8 direct importer(s), 14 total affected. not git-tracked. recursive deletion. CRITICAL risk.",
  "evidence": [
    "8 importer(s), 14 affected node(s)",
    "high centrality (PageRank 0.91) — a hub other code routes through",
    "untracked — not in git history",
    "recursive — applies to every file underneath"
  ],
  "affected_nodes": [ /* ... */ ],
  "chain": [ /* per-segment breakdown */ ]
}

A command class that couldn't probe — note the labeled estimate (no Postgres driver, server possibly remote, so the tool refuses to guess silently):

// assess_command('psql -c "DROP TABLE users"')
{
  "score": 0.9,
  "severity": "critical",
  "recommendation": "block",
  "evidence": [
    "drops users — its schema and all rows, irreversible (estimated — no read-only probe for postgres)"
  ]
}
// the same DROP against a local SQLite file probes for real:
//   "drops users — its schema and 42 row(s), irreversible"   (estimated: false)

Development

uv sync --all-extras
uv run pytest -q              # full suite
uv run python -m blast_scope.eval   # scoring accuracy report

Project structure

blast-scope/
├── src/blast_scope/
│   ├── server.py            # MCP server + tools (assess, index, snapshots)
│   ├── command_parser.py    # shell → structured intent (POSIX + PowerShell)
│   ├── command_effects.py   # command/flag/operand → intent + weight
│   ├── recoverability.py    # path → how recoverable if destroyed
│   ├── graph_resolver.py    # paths → dependency-graph impact (+ PageRank)
│   ├── centrality.py        # pure-Python weighted PageRank
│   ├── risk_scorer.py       # signals → score + severity + evidence
│   ├── classes/             # command-class probes behind one protocol
│   │   ├── __init__.py      #   Candidate · ConsequenceClass · registry
│   │   ├── git.py           #   reflog / upstream-divergence / protected branch
│   │   ├── docker.py        #   volume / container / system-prune probes
│   │   ├── packages.py      #   pip·uv uninstall vs. lockfile presence
│   │   └── sql.py           #   DROP/TRUNCATE/DELETE — SQLite probe + estimates
│   ├── consequences.py      # coordinator: class probes + path analyzers
│   ├── vcs.py / infra.py / config_refs.py   # git base + path analyzers
│   ├── hook.py              # PreToolUse advisory hook
│   ├── snapshot.py          # tarball snapshot / restore / list
│   ├── eval.py              # evaluation harness + metrics
│   └── vendor/crg/          # vendored from code-review-graph (MIT)
├── tests/                   # 298 tests incl. eval regression guard
│   └── fixtures/eval_corpus.jsonl   # labeled calibration corpus
└── docs/
    ├── heuristics.md        # scoring model + per-class tables + calibration
    └── hook.md              # hook registration + undo

Roadmap

  • Lift recall on the destruction classes (glob targets over tracked files, find-based deletion variants) — the SABER per-category table is the worklist.
  • Optional live probes for Postgres/MySQL (in-process, read-only) once a driver policy is settled — today those engines degrade to labeled estimates.
  • PowerShell-shell awareness in the hook path (the MCP tool already supports it).
  • Optional richer interception modes beyond advisory.

See CLAUDE.md for the full spec, contracts, and design rules.


License

Apache 2.0 (versions ≤ 0.3.1 were MIT). The vendored code-review-graph sources remain MIT under their upstream notice — see NOTICE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选