Skip to content

Releases: jaimenbell/mcp-security-scanner

v0.3.0 -- recall wave + capability-claim correction

Choose a tag to compare

@jaimenbell jaimenbell released this 31 Jul 00:55

21 commits since v0.2.0. Two things happened here.

Recall

Three slices moved the held-out baseline off zero:

  • tool-registry extraction for the five registration idioms real MCP servers actually use
  • un-gated auth_posture from the Python AST
  • un-gated secret_handling's name branch from the Python AST

Against the five pinned third-party targets, findings went from 0 to 88.

Honesty

The README had been claiming a 0/53 precision figure that described the pre-recall state, with no record of the recall wave at all. The CI count-gate was also RED on a drifted test count. Both corrected.

Read the 88 carefully. 2 were hand-audited as true positives, and the honest read is 1 -- only airtable src/main.ts:54 has real-world consequence, and even that is opt-in and already disclosed upstream. The other is a credential upstream deliberately committed as a read-only public-data test token.

2/88 is a low precision figure. A rising test count is not evidence of capability either, and the JS/TS precision layer still does not exist.

Tests

648 passed, 9 skipped. The 9 skips are the dogfood self-audit tests, which need MCP_SCANNER_FLEET_ROOT pointed at real repos and skip cleanly in a fresh clone.

v0.2.0 -- Honest pinnable release (FP-hardening since v0.1.0)

Choose a tag to compare

@jaimenbell jaimenbell released this 24 Jul 13:32

v0.2.0 — Honest pinnable release

This is the first tag cut since v0.1.0. If you pinned v0.1.0 (or the SHA our onboarding
doc previously pointed at), you should move to v0.2.0 — everything below shipped after
that pin and you have not had it.

What changed (50 commits since v0.1.0, grouped by arc):

  • False-positive hardening, waves 1+2 (29 commits). The bulk of this release. A recurring
    class of noisy findings — fake test tokens, placeholder secrets, self-signed test certs,
    pagination-cursor field names, RegExp vs child_process.exec() receiver confusion, and
    now (wave 2) in-body confirm gates on destructive job/wrapper actions — demotes to low
    confidence instead of firing at full severity. Alongside that, the tool-scope-creep detector's
    sink classification moved from name/syntax matching to resolved-callee classification (a
    helper merely named like a dangerous call is no longer misclassified as the call itself).
    Every fix went through at least one round of N-vote adversarial review, several through two or
    three, specifically hunting for the failure mode where a demotion rule could be tricked into
    hiding a real secret or exec — none were found live, but the regression suite now pins every
    case that was checked. One rule holds throughout: nothing is ever fully suppressed by a
    target's own markers, only demoted and tagged (destructiveHint included).
  • Low-level MCP SDK awareness (7 commits). The scanner now understands the low-level
    Server()/list_tools()/call_tool() registration shape, not just the decorator-style
    @mcp.tool() shape — reachability grading now decides the CLI-only/uncalled class (instead of
    falling back to UNKNOWN) for both SDK styles, and detector 5 (tool-scope-creep) and detector 6
    (secret-leak-via-tool-response) both attribute findings correctly across low-level dispatch
    branches, per-module-scoped so a repo with more than one dispatcher can't claim a bogus root.
  • Wave-4 test-path confidence demotion (2 commits). A hardcoded-secret finding on a
    test-looking path now demotes — but only pair-only (path and shape both have to look
    test-like); a real value-shaped secret on a bare test path still flags at full confidence.
  • New: mcp-scan report (8 commits). An 8-section, client-ready deliverable (exec summary,
    evidence appendix, ranked fix plan) generated straight from a scan — stable finding_ids,
    scan_meta embedding, triage.toml verdict joins, byte-stable golden HTML/MD renders, and a
    zero-external-URL self-containment gate.
  • New: mcp-scan ecosystem-scan (4 commits). A repeatable, read-only v2 pipeline for
    batch-scanning a fleet of MCP-server repos, with built-in responsible-disclosure rails —
    PRIVATE-marked notes surface only a target's own SECURITY.md, never invent a contact channel
    or auto-publish.
  • Test suite grew from ~202 (v0.1.0) to 439 (430 passing / 9 self-audit-only skips, live
    re-verified 2026-07-24 in the repo's system Python 3.12 / pytest 9.0.3) across this window, all
    regression-pinned — every false-positive class fixed above has a permanent fixture so it can't
    silently regress. The README's CI count-gate (scripts/check_readme_counts.py) passes against
    this exact junitxml run.

Who should care: anyone who pinned v0.1.0 or the pre-release SHA our onboarding doc
pointed at — you're running the pre-hardening scanner, which is measurably noisier than
every proof artifact (self-audit table, ecosystem-scan report, case study) we publish, all of
which run on the hardened engine. Re-pin to v0.2.0.

Nothing about the detector list, CLI flags, or output shape changed in a breaking way
this is a hardening/precision release, not a rewrite. Existing integrations keep working; you
just get fewer false positives and two new subcommands (report, ecosystem-scan).