A scanner can find a credential-shaped value, a broad filesystem root, or a remote endpoint in a configuration file. That matters. It is not the same as proving that the running server can read every file, that a request left the machine, or that a tool result reached a model without another control stopping it.
Teams often turn a scanner result into one of two bad conclusions: “the scan is clean, so the server is safe,” or “the scan found a risky string, so exploitation is confirmed.” Neither conclusion follows from static evidence alone.
Start by naming the evidence layer
Use three labels in an MCP review:
- Static configuration evidence: a value exists in a client configuration, package manifest, or declared server setting.
- Verified source evidence: the reviewed implementation contains the relevant behavior or control.
- Confirmed runtime evidence: a saved protocol response, log, network trace, or permission check proves what the running system did.
These labels stop a report from quietly upgrading a possibility into a fact. A configured filesystem root of /, for example, is a high-risk declaration. It does not prove the process can bypass operating-system permissions, container boundaries, or client enforcement.
Treat raw scan output as sensitive evidence
MCP configuration can contain API keys, URLs with credentials, shell arguments, local paths, publisher-controlled metadata, and instruction-like descriptions. Printing the entire result into an agent conversation can expose the exact material the review is supposed to protect.
- Create a randomly named evidence directory with mode
0700. - Capture scanner stdout and stderr into files with mode
0600. - Parse the machine-readable report locally.
- Emit only a fixed-schema summary such as counts, byte length, and a digest.
- Use a controlled local viewer for raw human inspection when necessary.
umask 077
EVIDENCE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/mcp-review.XXXXXXXX")"
chmod 700 "$EVIDENCE_DIR"
MCP_CONFIG_PATH="/absolute/path/to/mcp-config.json"
set +e
npx --yes mcp-scan@2.0.2 scan \
--config "$MCP_CONFIG_PATH" \
--severity low \
--json \
> "$EVIDENCE_DIR/scan.json" \
2> "$EVIDENCE_DIR/scan.log"
scan_status=$?
set -e
chmod 600 "$EVIDENCE_DIR"/*scan.json before an agent receives any summary. The free preflight below demonstrates the top-level validation pattern; production review should add the target-count and per-result checks described next.Keep the evidence only for the approved retention period. Delete the restricted directory when it is no longer needed.
An exit code is not a report
mcp-scan@2.0.2 returns exit code 1 when a report contains critical or high findings. Some invocation and operational failures can also return 1. Treating every status of zero or one as a completed scan can therefore turn a broken command into false reassurance.
Require both an allowed status and a valid report structure. For the 2.0.2 JSON report, validate the top-level object, results, non-negative severity counts, and the findings array for every result. Require totalScanned to equal the nonzero number of targets you intended to scan. A zero-target, missing, or malformed report is an operational failure, not evidence that the target is clean.
Static scans cannot close runtime questions
A configuration scan can show that a server declares an HTTP endpoint. It cannot prove that the server contacted it during the reviewed session. A schema inspection can show suspicious text in a tool description. It cannot prove what a later tool call will return.
Runtime questions need runtime evidence: a protocol capture, an approved proxy trace, a direct permission check, or a test against an isolated instance. If that evidence is unavailable, state the gap instead of filling it with confidence language.
A practical review order
- Inventory the exact client configurations and server entries in scope.
- Run the static scanner into restricted evidence storage.
- Validate the report structure before interpreting findings.
- Separate declared scope from operating-system and client authority.
- Inspect source or package evidence for the highest-risk findings.
- Gather runtime evidence only where it changes the decision.
- Fix the smallest effective control, then re-scan and record the difference.
The result is less dramatic than a single “safe” score, but more useful. A buyer, maintainer, or security reviewer can see what was observed, what was inferred, and what remains unknown.
Reusable resources
The free preflight is intentionally limited. It demonstrates the evidence boundary and report-validation pattern without presenting a static scan as a complete security review.