Let me tell you about the event-stream incident.
In 2018, a popular npm package with 2 million weekly downloads was handed off to a new maintainer. That new maintainer embedded a payload inside it targeting Bitcoin wallets. Nobody noticed for weeks. Not because developers were sloppy — because they trusted a package name they recognized.
The MCP ecosystem is walking into the same trap. And in some ways, it's set up to fall harder.
What is typosquatting, exactly?
It's simple. Someone registers a package name that looks almost identical to a legitimate, well-known one. One character swapped. A hyphen added. A zero where an "o" should be. The goal is that you — or an automation script, or an AI assistant — installs the wrong one.
In a typical npm workflow, this is already a serious risk. In the MCP ecosystem, it's worse.
When you install a malicious MCP server, you're not just running some code in a build step. You're handing a live process access to your filesystem, your environment variables, your shell. The consequences are not a broken build. They're a backdoor.
Why MCP is a particularly good target right now
A few things make this ecosystem unusually exposed.
There's no central registry. Unlike PyPI or npm, there's no authoritative place to look up MCP packages with verified ownership. Packages are scattered across npm, PyPI, Docker Hub, and raw GitHub repos with no unified trust model.
A huge chunk of MCP installs come from AI recommendations. Someone asks Claude or ChatGPT "what MCP server should I use for X?" and copies whatever gets suggested. LLMs can hallucinate package names. They can produce plausible-sounding names that are one transposition away from the real thing. When the discovery mechanism itself can be fooled, you're in trouble.
Most installs are copy-paste. You read a README, copy the install command, run it. If a malicious blog post or a GitHub fork with a subtly modified name is your source, you'll miss it.
And new publishers have almost no reputation signal. On npm, a package from an account with years of history and thousands of dependents gives implicit trust. Most MCP publishers are individuals with two repos and a week of activity. There's no signal to differentiate legitimate from malicious.
What the attacks actually look like
Take @modelcontextprotocol/server-filesystem — a legitimate, official package. An attacker might register:
-
@m0delcontextprotocol/server-filesystem(zero instead of the letter o) -
@modelcontextprotocol/server-filesytem(one character dropped) -
modelcontextprotocol-server-filesystem(no scoped namespace)
Or in the mcp- space:
-
mcp-githubvsmcp-qithub(g → q) -
mcp-filesystemvsmcpfilesystem(dropped hyphen) -
mcp-browser-usevsmcp-browzer-use
Once installed, the malicious package has exactly the same permissions as the real one. If you gave mcp-github filesystem access, the typosquatted version gets those same grants. No extra prompting. No warning.
What these packages do once they're in
The payload varies, but the patterns we see most:
Credential harvesting. On first startup, the package reads your environment variables — API keys, AWS credentials, database passwords — and ships them to an attacker-controlled endpoint. MCP servers legitimately need environment access, so this goes unmonitored.
Persistent callbacks. The package opens a connection to a command-and-control server and keeps it alive. MCP servers are long-running processes. This can persist for days without triggering any obvious alert.
Exfiltration through the tool interface itself. The cleverest attacks don't make obvious outbound calls. They encode stolen data in tool responses, relaying it back through the AI agent. No suspicious network traffic to log.
Backdoored-but-functional behavior. The package does exactly what it advertises — just also runs a secondary payload quietly in the background. Your workflows keep working normally while the attack proceeds.
How we detect it at MCPSafe
When we scan a package, we run several checks specifically targeting typosquatting.
Every package name gets compared against a reference list of known legitimate MCP packages using edit distance analysis. A package with an edit distance of 1 or 2 from a popular one, published by a different account, is a strong signal.
We cross-reference the publishing identity against the known publishers of the legitimate package. A scoped package like @modelcontextprotocol/... from an account with no connection to that namespace gets flagged.
We check metadata consistency. Legitimate packages have coherent metadata — homepage URLs matching the publisher, READMEs referencing the right repository. Typosquatted packages often have copied or mismatched metadata.
We look at dependency chains. Supply chain attacks frequently use unpinned subdependencies — the primary package looks clean but pulls in something malicious downstream.
What you can do right now
Pin exact versions. Don't install mcp-github@latest. Pin to a specific version string. It won't protect you from a package that was malicious from day one, but it prevents silent upgrades to a version that was clean when you installed it.
Verify publishers. Before installing anything, look up the publishing account. Check the linked GitHub organization. Make sure the package history is what you'd expect.
Don't treat AI package recommendations as commands. They're suggestions. Look them up before running them.
Scan before you install. MCPSafe runs typosquatting analysis — edit distance checks, publisher verification, dependency chain inspection — as part of every free scan.
Typosquatting is a solved problem where security controls exist for it. In MCP, those controls are still being built. Until the ecosystem catches up, manual diligence and automated scanning are your main defenses.
Scan any MCP package before you install it: mcpsafe.io/scan
Top comments (0)