SecurityMCPSupply ChainIncident Analysis

The Nx Console MCP Attack: How One VS Code Extension Stole GitHub's Tokens — and What It Means for Every Agent User

On 2026-05-18 a poisoned build of Nx Console disguised a credential stealer as a routine MCP setup task — siphoning GitHub tokens, AWS keys, Vault secrets, SSH keys, and Claude Code config from every developer who installed it. Two days later, the same tokens let attackers walk into GitHub's internal repos. Here is exactly what happened, why MCP-shaped attacks are now the standard playbook, and the concrete defenses every Claude Code / Cursor / Cline user should apply today.

Published 2026-05-28

TL;DR

What happened, in plain English

On 2026-05-18, the VS Code Marketplace started serving a new build of Nx Console — the official extension for the popular Nx monorepo tooling. The publisher account looked legitimate; the version number (18.95.0) followed normal cadence; the extension worked as expected for almost every user.

It also, silently, ran a single shell command on startup. The command fetched a payload from a planted commit on the *real* nrwl/nx repository — meaning even careful developers who checked the URL saw the official org name and waved it through. The payload was a credential stealer.

The threat group TeamPCP later claimed full responsibility. They had already hit axios, the TanStack ecosystem, SAP-CAP packages, and AntV in the weeks before; Nx Console was the highest-leverage target yet because VS Code extensions auto-update.

Why the disguise was 'MCP setup'

This is the part every agent user should internalize. The malicious command was logged and described to the user as a *routine MCP server registration step* — exactly the kind of one-liner you'd run after installing a real MCP integration. In 2026, MCP setup commands are everywhere:

claude mcp add my-server -- npx -y some-package
npx -y @some-org/mcp-installer
curl -sSL https://example.dev/install.sh | bash

Developers have been trained to copy-paste these commands without reading them. The attackers knew this. They picked a string that looked like a Claude/Cursor/Cline install snippet because MCP install snippets are now the most-pasted shell commands in developer tooling, and they get the least scrutiny.

What the stealer actually took

The payload ran in the background and harvested anything that smelled like a credential. The published target list is unusually broad — this was not a focused operation, it was a *vacuum*:

SourceWhat it gives the attacker
~/.gitconfig + GitHub PATsPush to any repo the user can push to. Read every private repo they can read.
.npmrcPublish to npm as the victim. This is how worms self-propagate.
AWS IMDS + env varsTake over the cloud account, spin up resources, exfil S3.
HashiCorp Vault tokensRead every secret the victim's role can read.
Kubernetes service account tokensPivot into production clusters.
1Password CLI sessionsPull personal credentials, banking, recovery codes.
SSH private keysLog in to every server the victim can SSH to.
Claude Code config (~/.claude/)OAuth tokens for Anthropic, MCP server credentials, and any API keys you pasted into MCP env vars.

That last row is the new one. Every previous credential-stealer of this scale already grabbed GitHub and AWS. Anthropic's Claude Code config directory is now on the standard target list — and the same is true for ~/.cursor/, ~/.codeium/windsurf/, and ~/.continue/.

Three exfil channels, not one

Blocking one path was not enough. The stealer pushed the harvested credentials out via:

  1. Encrypted HTTPS to a TeamPCP-controlled server. The 'obvious' channel — the one your endpoint firewall might catch.
  2. The GitHub API, using the *victim's own freshly-stolen token*. This blends into the noise of legitimate developer activity on GitHub. Almost impossible to spot without behavioral analytics.
  3. DNS tunneling, as a backup for hosts where outbound HTTPS was blocked but DNS was wide open (i.e., most corporate networks).

If you only audit HTTPS egress, you missed two of three. This is the same multi-channel pattern as the Mini Shai-Hulud worm that hit TanStack (2026-05-12) and AntV (2026-05-19, 300+ packages in 22 minutes). It is the new normal.

The blast radius: how GitHub itself got breached

On 2026-05-20, GitHub publicly disclosed that the Nx Console extension was installed on at least one of its employees' laptops. The stolen tokens belonged to that employee. With them, the attackers reached *roughly 3,800 internal GitHub repositories* — a number GitHub described as 'directionally consistent' with TeamPCP's claims.

Downstream effects rippled to OpenAI, Mistral AI, Grafana, and a long tail of customers whose private dependencies happened to live in those compromised repos. One VS Code extension. One employee. ~3,800 repos. Multiple unrelated companies. That is the modern MCP-era supply chain attack.

And just today (2026-05-28): AI-generated stealers join the party

On the morning of 2026-05-28 — the day this article is published — an npm package called mouse5212-super-formatter was caught silently stealing files from any developer who installed it. The malware was generated by an LLM by an inexperienced operator who left their own GitHub PAT inside the payload. Their op got burned within hours, but the lesson stands: the barrier to writing this class of attack is now near-zero.

Combine 'AI-generated stealers, hourly publishing' with 'MCP install commands are the most-pasted snippets', and you have a structural problem. Defense is no longer a one-time hygiene effort — it has to be a habit.

Defense: what every Claude Code / Cursor / MCP user should do today

Sorted from most to least impact. Pick the top three and you cover the realistic attack surface.

1. Audit your MCP server list and pin versions

2. Scope tokens. Make them short-lived. Never paste secrets into MCP env vars.

3. Vet sources every time. The 'official-looking' commit is the attack.

4. Use a secrets-aware shell history and egress monitoring

5. Treat Claude Code config as a secret

6. Watch the post-install logs

TeamPCP's command was *visible* in the VS Code extension install output. Nobody read it. Habituate yourself to scan the post-install of any new MCP server or extension for unusual curl, wget, bash -c, eval, or node -e calls — and to immediately uninstall if you see one that wasn't explicitly documented in the README.

What FreeMCPLab does to reduce this risk

None of that protects you from a publisher who gets compromised the day *after* we list them. The defenses above are still on you. We can narrow the field; we can't audit every commit.

Bottom line

The Nx Console incident is not a one-off, it's the template. The MCP install command has become the new postinstall script — the most-trusted, least-scrutinized place to hide a credential stealer. Three changes — pin versions, scope tokens, vet sources — cut the realistic risk by an order of magnitude. Do them today. Rotate anything you can't account for.

FAQ

Was I affected if I installed Nx Console between May 18 and May 20?
Assume yes if you ran VS Code at any point in that window. Check VS Code's extension log for an Nx Console update to v18.95.0. If you find it, rotate every credential listed in the 'What the stealer took' section above — GitHub PATs, AWS keys, Vault tokens, SSH keys, and your ~/.claude/ OAuth tokens. The patched build is v18.95.1 and later.
Are official MCP servers (Stripe, GitHub, Sentry, etc.) safer than community ones?
Marginally. They have larger security teams, signed releases, and reputational incentives. But the Nx Console attack proves that 'official publisher' is not enough — an attacker who compromises an employee account at the publisher gets the same trust you give to the publisher. Pin versions and scope tokens regardless.
Does Claude Code's sandboxing protect me?
Claude Code runs commands on your behalf in your shell. It does *not* sandbox the MCP server processes themselves — they have the same filesystem and network access your user has. A malicious MCP server can read any file you can read, and call any network endpoint your network allows. Permissions modes (--permission-mode acceptEdits etc.) limit what Claude approves automatically; they don't limit what the MCP server's process can do once it's running.
What's the single highest-leverage thing I can do in the next 10 minutes?
Open your Claude Desktop / Cursor / Cline config and replace every npx -y package-name with npx -y package-name@<latest-known-good-version>. This kills the auto-update attack vector across your whole MCP fleet in one edit.
Should I stop using MCP servers entirely?
No. The benefit-vs-risk calculation hasn't changed much — MCPs make agents dramatically more useful, and most servers are run by people doing real work. What's changed is that the *defaults* are now wrong. Treat every mcp add like sudo and you're back to a reasonable risk posture.
Where can I get notified about future MCP supply-chain incidents?
Follow the maintainers of modelcontextprotocol/servers on GitHub, subscribe to the OWASP MCP Top 10 mailing list, and watch the security advisory feeds for npm and the VS Code Marketplace. We'll also publish incident analyses here at /posts/ whenever a credible MCP-shaped attack lands.