Releases: jaimenbell/mcp-security-scanner
Release list
v0.3.0 -- recall wave + capability-claim correction
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_posturefrom 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)
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,RegExpvschild_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 — stablefinding_ids,
scan_metaembedding,triage.tomlverdict 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 ownSECURITY.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).