Skip to main content
← Writing
MCP SecurityAug 12, 20266 min read

What an MCP Security Scan Can Prove, and What It Cannot

MCP security reviews have an evidence problem before they have a tooling problem. A useful scan names what it observed without upgrading a static clue into a runtime fact.

Abanoub Rodolf Boctor

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.

  1. Create a randomly named evidence directory with mode 0700.
  2. Capture scanner stdout and stderr into files with mode 0600.
  3. Parse the machine-readable report locally.
  4. Emit only a fixed-schema summary such as counts, byte length, and a digest.
  5. 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"/*
Capture only: this block does not validate the report. A separate fixed-schema validator must inspect 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

  1. Inventory the exact client configurations and server entries in scope.
  2. Run the static scanner into restricted evidence storage.
  3. Validate the report structure before interpreting findings.
  4. Separate declared scope from operating-system and client authority.
  5. Inspect source or package evidence for the highest-risk findings.
  6. Gather runtime evidence only where it changes the decision.
  7. 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.

Work with ThynkQ

Need help shipping the real thing?

Start with the free discovery call if the scope is still fuzzy. If the problem is already clear, ThynkQ can usually tell you whether this should be an audit, a build, or an engineering retainer.

Book the free discovery call