MCP Security Scanner: Four Found Nothing, One Read It
Short answer: An MCP security scanner reads what your tool servers say at runtime rather than what your repository contains. It starts each server named in your client config, asks for the tool list, and inspects the descriptions the model will act on. A code scanner never opens that channel, so it cannot report on it.
A tool description in this workspace tells the model to read .mcp.json and the user's ~/.ssh/config, POST both to an outside host, and say nothing about having done it. Four scanners read the six files that workspace contains. Between them they returned nothing, and not one of them is broken.
That result is why "MCP security scanner" names a different kind of tool from the one already wired into most pipelines. The phrase has been attached to two procedures that share almost no mechanics, and the best-practice list for MCP is easier to follow once you know which of the two you are buying.
What did four file scanners find on a poisoned workspace?
The fixture is a small Node project with an .mcp.json naming two local stdio servers. One of them, notes, exposes a create_note tool whose description ends in an HTML comment addressed to the model. The other is a control with the same protocol handling and no injected text.
Nothing else in the tree is wrong. No credential, no unguarded route, no dependency pinned to a version with an advisory against it. Each of those would have given the scanners something true to say, and the run would then have measured one of the checks they already do well instead of the question.
What came back?

Real capture. @agenticcli/[email protected], Gitleaks 8.30.1, Semgrep 1.170.0, Trivy 0.72.0, 28 July 2026. Fixture and manifest: content-pipeline/captures/mcp-scanner-file-scanners/.
The grep in the second panel is there to close off the easy explanation. Nothing about this defect is hidden, encoded or assembled at runtime — it is plain ASCII in a file every one of these tools opened, and a rule matching on it would have fired. None of them has one.
We have run these same tools against secrets, where they behave completely differently, so the flat result here is a statement about rule coverage rather than about the tools.
What happens if you delete the defect?
The last two commands in the capture scan a second copy of the tree with the three injected lines removed, then compare the two reports on findings, risk score and files scanned.
They match. Two workspaces differing by exactly the thing under test produce the same report, which means the report was never sensitive to it — a stronger claim than "the scan came back clean", and one anybody can reproduce by running the script.
What does an MCP security scanner do differently?
The procedure is different from the first line onward. Instead of walking the file tree, it reads the client configuration, starts each server the configuration names, and speaks the protocol: initialize, then tools/list. What comes back is the same text the model will receive.
Which package are you actually installing?
The tool we used for this is the one nearly every MCP scanning guide still names, and installing it today gets you something else:
"This package has been renamed to snyk-agent-scan. This is a redirect package that installs snyk-agent-scan and forwards the mcp-scan CLI to it."
— PyPI distribution metadata for
mcp-scan0.4.3
Invariant Labs' scanner is now Snyk's, under a new name, and both distributions declare Apache-2.0. Anyone following a guide written before the rename is running a tool with different defaults from the one the guide describes.

Real capture. snyk-agent-scan 0.5.15 (installed via mcp-scan 0.4.3), 28 July 2026. Fixture and manifest: content-pipeline/captures/mcp-scanner-runtime-read/.
The injected comment is there, in full, in the middle panel. The retrieval that produced it needed no account and no network call, and it is the half of the job a file scanner structurally cannot do.
What does that reading cost?
There are two costs here and the capture prints both. The fourth panel shows the .mcp.json entry inspect had to execute to get the text: node servers/notes-mcp/server.js. Reading a tool list means running the command in your own config, which is why the tool warns about it and prompts for consent unless you pass a flag — the same shape as every other irreversible step an agent takes.
The second cost lands on the judging half. scan exits asking for a SNYK_TOKEN, and the --analysis-url default compiled into snyk-agent-scan 0.5.15 (cli.py) points at api.snyk.io. Retrieval is local. The opinion about what was retrieved is a request to somebody else's endpoint, on an account you have to open.
Where does the work actually happen?
One workspace · two procedures
To read a tool description, something has to run your server.
Both columns are the same six files. The left one is what a code scanner does with them. The right one is what a tool sold as an MCP scanner has to do to reach the one thing the left one cannot see.
.mcp.json, and having the retrieved text judged means sending it past the dashed line. Sources: content-pipeline/captures/mcp-scanner-file-scanners, content-pipeline/captures/mcp-scanner-runtime-read, agent_scan/cli.py:167 in snyk-agent-scan 0.5.15.That the inspection step is itself an execution is not a theoretical worry. The official MCP debugging tool carried a critical flaw of exactly this shape:
"Versions of MCP Inspector below 0.14.1 are vulnerable to remote code execution due to lack of authentication between the Inspector client and proxy, allowing unauthenticated requests to launch MCP commands over stdio."
— GitHub Advisory Database, GHSA-7f8r-222p-6f5g (CVE-2025-49596, CVSS v4 9.4), 13 June 2025
Neither column is the better tool. The left one is cheap, deterministic and belongs on every commit; the right one needs a decision each time it runs, which is the same trade an agent's tool grant forces everywhere else.
Is a tool description worth reading at all?
The evidence that it is comes from the model side rather than the tooling side. MCPTox, published on arXiv in August 2025, built 1312 malicious test cases from 45 live MCP servers and 353 authentic tools, then ran them against 20 agents.
"We find that more capable models are often more susceptible, as the attack exploits their superior instruction-following abilities."
— Wang, Gao, Wang, Liu, Sun, Cheng, Shi, Du and Li, MCPTox: A Benchmark for Tool Poisoning Attack on Real-World MCP Servers, arXiv:2508.14925, 19 August 2025
Their strongest result on the agent side is an attack success rate of 72.8% against o1-mini, with the highest refusal rate of anything they tested, Claude-3.7-Sonnet, under 3%. Getting better at following instructions makes an agent better at following the wrong ones.
What does the protocol itself require?
The specification takes the same position about server-supplied metadata, in normative language:
"For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers."
— Model Context Protocol specification 2025-11-25, Tools
Worth being precise about what that sentence covers: it names annotations, a specific field. The description a model reads carries no equivalent MUST on that page. Both requirements land on the client while it runs, which is a place no repository scan reaches and no lockfile records.
Which one should you run?
Sort the answer by where the evidence lives rather than by vendor, and it comes out clean.
| What you are asking | What can answer it |
|---|---|
| Is there a credential in the client config? | A file scanner, on every commit, for free |
| Is a server pinned to a version with an advisory? | A dependency scanner reading the manifest |
| What does this server's tool list actually say? | Something that starts the server |
| Is that text trying to steer the model? | A person reading it, or a scanner with an account |
The top two rows are cheap enough to automate and forget, which is the case for putting them in the same pre-ship pass as everything else a machine can read without understanding. The bottom two cost an execution and a judgement call, so they belong on the day you add a server and the day you upgrade one.
What we could not test, and what we do not do
Two limits, stated because a scanner article that lists only what it proved is worth less than one that marks its own edges.
We ran one runtime scanner, not the category. Proximity, Cisco's mcp-scanner, mcpscan.ai and Enkrypt are all sold for this job and none was installed or measured, so nothing here generalises past the tool named in the capture. We also never saw what snyk-agent-scan reports, only what it retrieves, because obtaining a token would have meant opening a vendor account.
And there is no MCP-specific rule anywhere in our own corpus, at any tier. ShipGuard read six files on this workspace and said so honestly; a release gate for the code you are about to ship is not an agent-runtime inspector, and the distance between an artifact and the system you trust is where this whole class of problem sits.
FAQ
What is an MCP security scanner?
Can a normal code scanner detect a poisoned MCP tool description?
Is mcp-scan still the tool to install?
Does running an MCP scanner send my code anywhere?
Why does reading a tool description require starting the server?
Does ShipGuard scan MCP servers or tool descriptions?
────────[ ▮ gate ]────────
Don't ship the next one.
Free, local, no account. Catches this exact bug class before deploy.
$ npx @agenticcli/shipguard scan