Research

The state of MCP security

The Model Context Protocol turned “let an agent use a tool” into a one-line install. That’s the appeal and the risk: an MCP server runs with real access — files, network, shell, credentials — and until recently there was no way to tell a careful one from a careless one before you wired it in. So we graded all of them.

This is a snapshot of the whole registry: 17,896 servers, each scored A–F across six security checks — prompt-injection surface, supply-chain provenance, credential hygiene, permission scope, version-to-version drift, and transport/auth. Here is what the numbers say.

The distribution

Grade Servers Share
A 331 1.8%
B 10,846 60.6%
C 2,567 14.3%
D 373 2.1%
F 40 0.2%
insufficient 3,739 20.9%

Three things stand out.

Almost nothing earns an A. Only 1.8% of servers score high and expose enough to stand behind the grade. An A isn’t just “no problems found” — it requires enough of the server to be inspectable that a clean result actually means something. Most projects never clear that bar, not because they’re unsafe, but because there’s little to verify against.

The ecosystem is a wall of B. Six in ten servers land at B: clean on the checks that ran, but not enough was visible to certify an A. This is the honest majority — a manifest that looks fine, a package that installs without red flags, but a coverage ceiling that holds the grade. “Probably fine” is the modal state of MCP.

One in five can’t be graded at all. 20.9% come back insufficient — too little could be inspected to say anything. These aren’t failures; they’re blind spots. A remote server behind auth, a local server that needs a running process to reveal its tools. We treat that as a distinct state, never a silent pass — and closing it is where runtime analysis comes in (below).

The tail that matters

413 servers grade D or F — the ones where a check that ran actually failed. The patterns repeat:

  • Secrets as tool parameters. Servers that declare an api_key (or token, or password) as a tool input — meaning the model is expected to hold and pass the credential. Credentials belong in the environment, never in the model’s context.
  • Dynamic code execution. eval() and equivalent in tool handlers — arbitrary code paths reachable through a tool call.
  • Injection prose in tool descriptions. Imperatives aimed at the model sitting in the one field the model always reads — IMPORTANT: instructions, “ignore previous,” and in a few cases data-exfiltration URLs. A tool description is an attack surface, and some are already being used as one.

None of these require a sophisticated adversary. They’re in shipped, installable packages today.

Why so much is invisible

Three of the six checks want a server’s live surface — its actual tool list — which only exists when the server is running. Static analysis of a package and manifest can’t see it, which is why so much of the registry caps at B or insufficient.

So we pair static analysis with runtime probing: remote servers are connected to live, and local servers are booted inside an isolated sandbox to read their real tool inventory. That turns “we can’t see the tools, hold at insufficient” into a real grade for every server that boots cleanly. It’s how the blind spot shrinks over time — honestly, without ever guessing at what a server does.

What this means

The MCP ecosystem isn’t on fire — most servers are unremarkable, and the genuinely dangerous ones are a small minority. But “most are probably fine” is not a security posture, and the 20% you can’t see plus the 400+ that fail are exactly the servers an agent shouldn’t install blind. The point of a grade isn’t to shame a maintainer; it’s to give you — and your agents — an honest signal before trust is extended.

Every server’s grade, the findings behind it, and the full methodology are public at mcpgrade.dev. Grades reflect facts, not intent, and every one is disputable.

Snapshot taken July 2026. Numbers shift daily as the registry is re-crawled; the live figures are on the register.

← All research