---
title: "19 typosquatted npm packages, one new attack surface: the AI agent's MCP configuration"
date: 2026-06-08
summary: "Mini Shai-Hulud (May 12) compromised 160+ packages including TanStack, Mistral AI, and UiPath. SANDWORM_MODE shipped 19 typosquatted AI-coding packages. The April 4 MCP Connector Poisoning disclosure named the new payload: a rogue MCP server injected into the agent's IDE configuration. No agent-side exploit required — the trust model breaks at step 5."
slug: agent-supply-chain-mcp-injection
author: "Damiën Semler"
hero_glyph: spiral
---

[Five days before this
post](https://orca.security/resources/blog/tanstack-npm-supply-chain-worm/),
on May 12, 2026, a supply chain worm dubbed Mini Shai-Hulud
compromised TanStack, Mistral AI, UiPath, and 160-plus other npm and
PyPI packages, exfiltrating credentials and self-propagating through
the ecosystem. A separate campaign in February,
[SANDWORM_MODE](https://www.securityweek.com/new-sandworm_mode-supply-chain-attack-hits-npm/),
published 19 typosquatting npm packages impersonating Claude Code,
OpenClaw, and other AI-coding tools. An April 4 disclosure,
[MCP Connector
Poisoning](https://earezki.com/ai-news/2026-04-04-mcp-connector-poisoning-how-compromised-npm-packages-hijack-your-ai-agent/),
named the specific payload these packages now carry: a rogue Model
Context Protocol server injected into the user's IDE configuration.
Once installed, the malicious MCP server runs inside the agent's
trust boundary and is treated by the agent as a legitimate source
of tools, prompts, and resources.

This is the agent-web supply chain attack pattern, and it is no
longer hypothetical. The npm parallel has caught up.

## How the attack chain works

<svg viewBox="0 0 640 320" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;height:auto;display:block;margin:28px auto" role="img" aria-labelledby="sc-title sc-desc">
  <title id="sc-title">Agent supply chain attack chain: typosquat to MCP injection</title>
  <desc id="sc-desc">A horizontal five-step attack chain. Step 1: attacker publishes a typosquatted package on npm impersonating a popular tool. Step 2: developer installs the package thinking it is the legitimate dependency. Step 3: post-install script runs with the developer's credentials. Step 4: script modifies the IDE's MCP configuration file to add a rogue MCP server. Step 5: when the AI agent next starts, it loads the new server and treats it as trusted. Arrows connect each step left to right. The final box is rendered with a pink outline to indicate the load-bearing failure point.</desc>
  <style>
    .lb { fill: none; stroke: var(--c-fg-3, #6b7280); stroke-width: 1.4; }
    .lp { fill: none; stroke: var(--c-pink, #F472B6); stroke-width: 1.8; }
    .lt { font-family: 'Geist', system-ui, sans-serif; font-size: 12px; fill: var(--c-fg, #0a0a0a); font-weight: 600; }
    .lc { font-family: 'Geist', system-ui, sans-serif; font-size: 10px; fill: var(--c-fg-2, #404040); }
    .ll { font-family: 'Geist Mono', ui-monospace, monospace; font-size: 10px; fill: var(--c-fg-4, #9ca3af); letter-spacing: 0.14em; }
    .arrow { stroke: var(--c-fg-3, #6b7280); stroke-width: 1.4; fill: none; marker-end: url(#arrSC); }
  </style>
  <defs>
    <marker id="arrSC" markerWidth="9" markerHeight="9" refX="8" refY="3" orient="auto">
      <polygon points="0 0, 9 3, 0 6" fill="#6b7280"/>
    </marker>
  </defs>
  <text x="0" y="18" class="ll">ATTACK CHAIN · TYPOSQUAT → MCP INJECTION</text>

  <!-- Step 1 -->
  <rect x="0" y="60" width="115" height="120" rx="4" class="lb"/>
  <text x="57" y="84" text-anchor="middle" class="lt">1</text>
  <text x="57" y="105" text-anchor="middle" class="lc">attacker</text>
  <text x="57" y="120" text-anchor="middle" class="lc">publishes</text>
  <text x="57" y="135" text-anchor="middle" class="lc">typosquat</text>
  <text x="57" y="156" text-anchor="middle" class="lc" style="font-style:italic">claude-code-cli</text>
  <text x="57" y="170" text-anchor="middle" class="lc" style="font-style:italic">vs claude-code</text>

  <line x1="117" y1="120" x2="138" y2="120" class="arrow"/>

  <!-- Step 2 -->
  <rect x="140" y="60" width="115" height="120" rx="4" class="lb"/>
  <text x="197" y="84" text-anchor="middle" class="lt">2</text>
  <text x="197" y="105" text-anchor="middle" class="lc">developer</text>
  <text x="197" y="120" text-anchor="middle" class="lc">installs</text>
  <text x="197" y="135" text-anchor="middle" class="lc">via npm</text>
  <text x="197" y="156" text-anchor="middle" class="lc" style="font-style:italic">npm i</text>
  <text x="197" y="170" text-anchor="middle" class="lc" style="font-style:italic">claude-code-cli</text>

  <line x1="257" y1="120" x2="278" y2="120" class="arrow"/>

  <!-- Step 3 -->
  <rect x="280" y="60" width="115" height="120" rx="4" class="lb"/>
  <text x="337" y="84" text-anchor="middle" class="lt">3</text>
  <text x="337" y="105" text-anchor="middle" class="lc">post-install</text>
  <text x="337" y="120" text-anchor="middle" class="lc">script runs</text>
  <text x="337" y="135" text-anchor="middle" class="lc">w/ creds</text>
  <text x="337" y="156" text-anchor="middle" class="lc" style="font-style:italic">user-level</text>
  <text x="337" y="170" text-anchor="middle" class="lc" style="font-style:italic">filesystem</text>

  <line x1="397" y1="120" x2="418" y2="120" class="arrow"/>

  <!-- Step 4 -->
  <rect x="420" y="60" width="115" height="120" rx="4" class="lb"/>
  <text x="477" y="84" text-anchor="middle" class="lt">4</text>
  <text x="477" y="105" text-anchor="middle" class="lc">writes new</text>
  <text x="477" y="120" text-anchor="middle" class="lc">MCP server</text>
  <text x="477" y="135" text-anchor="middle" class="lc">to IDE config</text>
  <text x="477" y="156" text-anchor="middle" class="lc" style="font-style:italic">~/.cursor/</text>
  <text x="477" y="170" text-anchor="middle" class="lc" style="font-style:italic">~/.claude/</text>

  <line x1="537" y1="120" x2="558" y2="120" class="arrow"/>

  <!-- Step 5: load-bearing failure -->
  <rect x="560" y="60" width="80" height="120" rx="4" class="lp"/>
  <text x="600" y="84" text-anchor="middle" class="lt" style="fill:var(--c-pink,#F472B6)">5</text>
  <text x="600" y="105" text-anchor="middle" class="lc">agent loads</text>
  <text x="600" y="120" text-anchor="middle" class="lc">malicious</text>
  <text x="600" y="135" text-anchor="middle" class="lc">MCP server</text>
  <text x="600" y="156" text-anchor="middle" class="lc" style="font-style:italic">as trusted</text>

  <text x="320" y="220" text-anchor="middle" class="ll">FIVE STEPS, ALL UNDER USER PERMISSIONS</text>
  <text x="320" y="240" text-anchor="middle" class="lc" style="font-style:italic">no exploit needed in the agent or the IDE</text>
  <text x="320" y="280" text-anchor="middle" class="lc" style="fill:var(--c-pink,#F472B6); font-weight:600">step 5 is where the agent's trust model breaks</text>
</svg>

Notice what the chain does not require. There is no zero-day in the
agent's code, no protocol-level vulnerability, no exploit of a
specific MCP server. The attack succeeds because the agent's
configuration file is writable by the user's processes and the agent
loads MCP servers from that configuration without distinguishing
between servers the user added intentionally and servers a postinstall
script added on the user's behalf. That is the structural gap
SANDWORM_MODE and Mini Shai-Hulud exploit at population scale.

## Why this attack surface exists

The economics line up almost too neatly. There are [10,000-plus public
MCP servers](https://agenstry.com/blog/mcp-discovery-fragmentation)
across fragmented registries. The cost of publishing a new npm
package is essentially zero. The cost of evaluating a new package
falls on the developer who installs it. IDEs auto-pick up MCP
configuration from well-known paths on disk. Agents trust the
configurations they're given because the spec [says no more than
that](https://agenstry.com/blog/google-mcp-origin-validation-seven-months)
about what a "trusted" server is.

[Between January and February
2026](https://www.heyuan110.com/posts/ai/2026-03-10-mcp-security-2026/),
researchers filed more than 30 CVEs targeting MCP servers, clients,
and infrastructure — including CVE-2026-26118 against Microsoft's
MCP server, CVE-2025-49596 against the MCP Inspector debugging
client, CVE-2025-54136 against Cursor, and a remote-code-execution
flaw in a package downloaded nearly half a million times. The April
15 [OX Security
advisory](https://agenstry.com/blog/mcp-spec-vs-probe-evidence)
covered the architectural STDIO-injection class. The April 22 [Google
Database Toolbox
disclosure](https://agenstry.com/blog/google-mcp-origin-validation-seven-months)
covered the DNS-rebinding class. The April 4 MCP Connector Poisoning
disclosure named the typosquat-plus-config-injection class. The May
12 Mini Shai-Hulud worm operationalized it at 160-package scale.

Two months. Three distinct attack classes. One ecosystem.

## What the defenses look like now

The agent-web supply chain attack surface has analogues at three
layers of the stack, and the defense maturity differs at each:

| Layer | Attack vector | Defense maturity today |
|---|---|---|
| `npm` / `pip` package | Typosquatting, malicious postinstall | npm's own scanning, third-party tools (Socket, Snyk), publisher verification (uneven) |
| `AGENTS.md` / `SKILL.md` | Malicious project context, instruction injection | Almost none — no signing, no schema validator at population scale |
| MCP server registration | Config-file injection, malicious endpoints | Per-IDE auth flows (uneven), no probe-driven trust signals at the registry level |

The first row is where the package ecosystem has spent the most
defensive work. The second and third are where the agent ecosystem is
still building the equivalent of npm's first-generation scanning. The
gap is structural and known. What's new is that adversaries are now
chaining attacks across the rows: a single npm typosquat produces a
package install (row 1) that injects an MCP server (row 3), with
no protocol-level vulnerability in either layer.

## What this means for registries and gateways

The Agenstry-relevant observation is the same one [we've made about
MCP server
conformance](https://agenstry.com/blog/mcp-spec-vs-probe-evidence)
and about [identity
verification](https://agenstry.com/blog/a2a-signed-cards-key-not-identity):
a self-declared claim is not evidence. An MCP server entry that says
"this server implements MCP correctly" is meaningfully different
from "this server, when probed today, responded as a valid MCP server
and was not flagged in any active malicious-package database."

For gateway operators ([Uber's
pattern](https://agenstry.com/blog/uber-1500-agents-gateway)), the
implication is that the gateway has to inspect not just the MCP
server itself, but the *publication path* of the package that
configured it. A gateway that allows arbitrary MCP servers to be
installed by user-level processes inside its trust boundary is one
postinstall script away from a SANDWORM_MODE incident. The
operational defenses (pinning install paths, requiring published
allowlists, scanning the IDE configuration for unexpected entries)
are the same defenses npm's enterprise ecosystem has been writing for
a decade. The agent-web version is roughly five years behind.

For public registries, the pattern means the next valuable signal
to publish is *provenance plus probe*: not just "this MCP server
exists," but "this server was published by this maintainer, signed
by this key, and behaved this way when probed in the last 24 hours."
Each component of that signal already exists somewhere in the
ecosystem. None of the current registries publishes all three.

## What we're watching

Three things, observable within the next two quarters:

1. **Whether `npm` itself ships an AI-coding-tool publisher
   verification flow.** A signed-maintainer requirement for packages
   under tags like `mcp`, `claude-code`, or `cursor` would close
   step 1 of the attack chain at the publication layer. npm has
   shipped similar protections for high-value namespaces in the past;
   the question is whether the AI-coding ecosystem crosses that
   threshold of attention.
2. **Whether IDEs add an explicit-confirmation step before loading a
   newly-added MCP server.** Step 4 of the attack chain
   (configuration injection) succeeds today because the IDE picks up
   new MCP entries silently. A one-time approval prompt the first
   time a server appears in the config would shift the trust model
   in a way the user could meaningfully verify.
3. **Whether a public AI-package threat intelligence feed emerges.**
   npm's ecosystem has [active monitoring
   feeds](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/)
   for malicious-package detection. The agent ecosystem is just
   starting to spin up equivalents. The first one published with
   continuous probe data against the MCP server population will set
   the template.

The headline supply chain incidents of the past two months named
TanStack, Mistral AI, and UiPath. The same attack pattern works
against any package an AI agent installs. The defenses already exist
in adjacent ecosystems; the agent-web version is the one that hasn't
shipped at scale yet. The next named incident in this class will be
the one that decides how fast that defense layer matures.

## Sources

- [TanStack and 160+ npm/PyPI Packages Compromised in Supply Chain Worm Attack](https://orca.security/resources/blog/tanstack-npm-supply-chain-worm/) — Orca Security, May 12, 2026.
- [New 'Sandworm_Mode' Supply Chain Attack Hits NPM](https://www.securityweek.com/new-sandworm_mode-supply-chain-attack-hits-npm/) — SecurityWeek, February 2026.
- [MCP Connector Poisoning: How Compromised npm Packages Hijack Your AI Agent](https://earezki.com/ai-news/2026-04-04-mcp-connector-poisoning-how-compromised-npm-packages-hijack-your-ai-agent/) — Dev|Journal, April 4, 2026.
- [MCP Security 2026: 30 CVEs in 60 Days — What Went Wrong](https://www.heyuan110.com/posts/ai/2026-03-10-mcp-security-2026/) — heyuan110.com, March 10, 2026.
- [The npm Threat Landscape: Attack Surface and Mitigations](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/) — Unit 42 (Palo Alto Networks), May 2026.
- [Microsoft MCP Server Vulnerability (CVE-2026-26118)](https://www.pointguardai.com/ai-security-incidents/microsoft-mcp-server-vulnerability-opens-door-to-ai-tool-hijacking-cve-2026-26118) — PointGuard AI, 2026.
