Supply Chain
MCP Supply-Chain Attacks: Why 'npm install for agents' is the new risk surface
MCP servers are distributed the same way npm packages were a decade ago: by name, often without signatures, often without reproducible builds. Three scanning tools shipped in early 2026 (Vett, Golf Scanner, MCP-Scan) all found the same thing: the registries are full of servers that should not be auto-installed.
How MCP servers actually get installed
The default flow looks like: the user reads a tutorial or asks the agent to "set up a tool for X." The recommendation is "install some-mcp-server." The user runs an install command (npx, uvx, pip install, sometimes git clone + run). The server is now active and the agent has access to its tools.
Where the package came from is rarely verified. Whether it is signed is rarely checked. Whether the published code matches what is on the linked GitHub repo is almost never confirmed. The agent ends up with new capabilities, and a new piece of code is running with at least the agent's privileges and often the user's.
This is the same trust model npm shipped with in the early 2010s. The same attacks landed on npm at scale (event-stream, ua-parser-js, colors.js). MCP is at the same vulnerable point in the curve, and is just early enough that the major incidents have not happened publicly yet.
Three real incident shapes from 2025-26
1. Typosquatting against popular servers
A user wants @modelcontextprotocol/server-filesystem. They install modelcontextprotocol-server-filesystem (different namespacing) or mcp-server-filesystem (dropped prefix) or one of a dozen lookalikes. Some of these are squatters who registered before the canonical author got around to it. Some are intentionally malicious. The user, the agent, and the install tool all accept the typo silently.
2. Compromised maintainer accounts
A real, useful MCP server has been published by a real developer. The maintainer's npm or PyPI account is compromised (phishing, leaked token, password reuse). The attacker publishes a new version, 1.0.4, that adds a post-install script. Users on auto-update pick it up. The agent's environment is now compromised wherever the server runs.
3. Sleeper code in legitimate-looking servers
The Smithery scan of 100 servers in April 2026 found 22 with security issues, and a subset of those contained code that was active code (not just sloppy permissions). The pattern: the server does its advertised job, but also makes outbound calls to telemetry endpoints the user did not consent to, or exposes a "debug" tool that lets the agent read arbitrary files. Not all of those are intentional supply-chain attacks; some are just bad hygiene. From the user's perspective the impact is similar.
What scanning tools can catch
By mid-2026 there are three publicly available MCP scanners worth running. Each catches a different slice:
mcp-scan: static analysis of the server's manifest and code. Flags unsafe shell construction, missing input validation, secret leakage through tools. Misses prompt-injection-in-metadata.
Golf Scanner: built around discovery and inventory of installed MCP servers. Identifies what is installed, where, and at what version. Useful for ongoing audit; not designed for vulnerability detail.
Vett: signature-and-verification focused. Lets a server publisher sign their releases, and an installer verify the signature against the publisher's identity. Closer to npm-signed-packages or PyPI Trusted Publishing.
None of the three catch a determined adversary. They raise the bar enough that opportunistic attacks and obvious bad hygiene get filtered. Together they roughly approximate what npm's combination of audit, provenance, and registry verification provides today.
What good distribution looks like
If you are publishing an MCP server in 2026:
- Sign your releases. Use OIDC-based provenance (sigstore, npm provenance) so users can verify the artifact came from your repo's CI, not from an attacker who got your publishing token.
- Pin and publish a SHA-of-source. The published artifact's hash and the source-repo tag's hash should be reproducible. A user who cares should be able to check.
- Document required permissions. Be explicit about what files, network endpoints, and environment variables your server reads. This is the analogue of an Android permissions manifest.
- No post-install scripts. Or if you must have them, make them pure (no network, no credential reads). Most installs do not need them.
- Versioned tool schemas. Do not silently expand the set of tools your server exposes between minor versions. Users adopt your tools by their schema; they should not get new ones without consent.
If you are installing MCP servers in 2026:
- Pin exact versions. No
latest, no caret-range. - Verify provenance where the publisher provides it. Where they do not, treat the server as community code that needs a manual read.
- Run servers in least-privilege accounts. Not as the developer user. Not with $HOME mounted. Not with cloud credentials in the environment.
- Audit egress. Log outbound network for the first hour after install. Anything contacting a domain you did not expect deserves an investigation.
- Keep an installed-server manifest. Know what you installed, when, at what version, with what hash. Auditable.
Pattern recognition: the MCP ecosystem in 2026 is at the same stage npm was around 2014. The vulnerabilities are not exotic. They are the predictable consequence of optimizing for capability and ease of distribution at the expense of trust infrastructure. The fix is the same trust infrastructure that npm eventually built; the question is how much pain happens first.
What to test before adopting a server
A focused pre-adoption pentest of an MCP server takes an afternoon and consistently produces findings:
- Read the install instructions. Note every command. If it includes
curl | sh, you already have a finding. - Check the package's provenance. Does the registry page link to a real GitHub repo? Does the latest tag match what is published? Is there a signature?
- Skim the source. Specifically the tool implementations and any post-install or post-build scripts. Look for shell-out patterns and outbound HTTP.
- Read the tool descriptions. Anything that looks like an instruction to the LLM ("if the user asks X, always do Y") is a red flag.
- Install in a sandbox first. Container, dedicated user, throwaway VM. Run the agent against the server. Watch network and file activity for 30 minutes.
- Confirm and adopt, or reject and find a different server.
Most teams will not do all six steps for every install. That is realistic. The minimum to do for every install is steps 1, 2, and the network watch in step 5.
Related
- Auditing MCP servers covers the per-server vulnerability classes in detail.
- Coding agents with shell access covers the host-side threat surface that compromised servers exploit.
- The 2026 LLM security checklist includes the supply-chain controls in the tool-use category.