On November 10, 2026, Corelight published research titled The supply-chain risk hiding in your MCP servers after studying AI coding assistants on an administrator workstation. The investigation did not start with malware on the host; it started with a supply-chain question about where MCP server code comes from and how it updates. What Corelight describes matches what the uv toolchain documents and what independent MCP supply-chain work has warned about: uvx can rebuild a tool environment from PyPI, so transitive Python packages may change even when your MCP JSON still names the same server release. Those packages run in-process with the tokens and filesystem access you gave the MCP server—often firewall, SIEM, or cloud admin credentials on security workstations.
TL;DR
| Question | Answer |
|---|---|
| Am I affected? | Yes, if local MCP servers start via uvx, npx …@latest, or similar registry resolvers and hold privileged env vars |
| Is there a fix? | Freeze installs: hash-pinned lockfile, dedicated venv, launch the installed binary directly; upgrade mcp-remote to ≥ 0.1.16 if you use it |
| Does data leave my machine? | Not from this drift alone—risk is running unaudited code locally that can read secrets and call your networks |
| What is new on Nov 10, 2026? | Corelight measured drift on a pinned community server (19 rebuilds → 15 dependency sets, 23 of 69 packages changed over five weeks, per its write-up) |
| What should I do first? | Inventory MCP launch commands, replace @latest, and record installed package versions before the next IDE session |
What Corelight reported
Corelight states the work began during a blast-radius exercise with an AI agent on a security administrator's laptop. The agent noticed other AI assistants already running MCP servers with privileged access. Nothing was compromised, but the team asked how those servers update.
Per Corelight's November 10, 2026 publication (listed on the Corelight Bright Ideas blog), findings include:
- Launch pattern: assistants started MCP servers with
uvx, which downloads a Python distribution and runs it from a one-line MCP configuration. - Apparent pinning: configurations referenced release tags, exact PyPI versions, or Git commits, which look static to a reviewer skimming JSON.
- Transitive drift: on one community server, 19 environment rebuilds over five weeks produced 15 distinct dependency sets. 23 of 69 packages changed versions, including
cryptography, JWT libraries, and the MCP SDK, without anyone editing the MCP config. - Ignored lockfiles: the server maintainer had pinned seven direct dependencies and published a hash-locked requirements file, but
uvxdid not consume that lockfile when rebuilding tool environments. - Broader review: of 35 MCP servers Corelight examined, 23 recommended install paths that could resolve fresh dependencies from a public registry during launch or image build.
- Network footprint: servers on the lab workstation made more than 1,600 connections in a week to 11 management systems (firewall, SIEM, sensor management, and similar).
- Remediation test: after freezing five servers (hash-verified install, direct launch, startup update checks off), Corelight says 457 restarts over two weeks kept identical package lists, with faster cold starts (~2s vs 4–11s).
Corelight stresses this is not a protocol bug in MCP—it is what happens when high-privilege local servers are wired to mutable registry resolution.
Why uvx drifts even when the server pin looks fixed
The uvx alias is equivalent to uv tool run. Astral documents that uvx provisions a temporary virtual environment in the uv cache, isolated from your current project, and treats that environment as disposable—uv cache clean removes it. Tool versions can refresh when the cache is pruned, when you request @latest, or when a rebuild resolves newer transitive dependencies allowed by upstream metadata.
That matters for MCP because many configs look like declarative API wiring but are process launchers:
{
"mcpServers": {
"example": {
"command": "uvx",
"args": ["[email protected]"]
}
}
}
To uvx, the pin on [email protected] does not automatically pin every wheel that server pulls from PyPI on the next rebuild. Astral's documentation also notes that uvx is not appropriate when the tool must run from a local checkout—the documented alternative is uv run inside the project, which encodes a different trust boundary.
Independent research on the same launcher class—Poneglyph Security's uvx MCP supply-chain analysis—shows a separate failure mode: uvx resolves distribution names on PyPI, so documentation that names a package without proving registry ownership can execute whoever publishes that normalized name. Corelight's November finding is complementary: even legitimate packages can still change underneath through transitive updates.
Attack chain step by step
- Operator enables MCP in Claude Code, Cursor, Codex, or another client, pasting a README recipe that uses
uvxornpx …@latest. - Client starts the server on login or session open; the launcher creates or refreshes a tool environment and contacts PyPI, npm, or GitHub.
- Transitive packages load into the MCP server process. Corelight's point is that any of them inherit API tokens, cloud profiles, and paths declared in the MCP
envblock or the user session. - Supply-chain event—maintainer takeover, short-lived poisoned release, or dependency confusion—drops malicious code into that graph. Shai-Hulud-style worms have shown minutes-long malicious windows on registries; a server that rebuilds every few days gets more lottery tickets.
- Attacker code runs at import or startup without a visible MCP handshake failure—same class as the MCP local server compromise scenarios the specification lists (malicious startup commands, poisoned server payloads, localhost rebinding).
Parallel risk: npx and mcp-remote
Corelight notes JavaScript setups that start npx …@latest proxies face the same floating install pattern. Separately, (CVSS 9.6) affected mcp-remote versions 0.0.5 through 0.1.15, allowing command injection via a crafted OAuth callback URL; 0.1.16 fixes it per GitHub advisory GHSA-6xpm-ggf7-wc3p. Fast registry updates help patch that bug, but the same channel would spread a malicious mcp-remote release if a publisher account were abused.
How this maps to MCP security guidance
The MCP specification's local MCP server compromise section requires clients that offer one-click setup to show the exact command and treat it as dangerous code execution. It also recommends sandboxing and least-privilege launches—none of which substitutes for knowing which package versions actually ran.
That aligns with F-Secure's TA-4 entry (tool/MCP server supply-chain compromise) and with Beam's standing advice in the MCP server security review: pins on the server name are not provenance.
What this means if you run AI coding agents
Configuration checks
-
Grep your MCP configs for
"command": "uvx",npx,pipx, or bare@latest:rg -n '"command"\s*:\s*"(uvx|npx|pipx)"|@latest' ~/.config ~/.cursor -
List what actually installed after a session—Corelight hunted PyPI/GitHub/npm contacts plus endpoint package inventories. Registry DNS alone is not proof of drift; compare
pip freezeoruv pip listinside the tool environment against a saved baseline. -
Remove secrets from MCP
envunless required. Prefer short-lived, server-specific credentials over personal admin tokens. See also Cursor MCP config poisoning for why env inheritance is attack surface. -
Upgrade
mcp-remoteto ≥ 0.1.16 if present:npm ls mcp-remoteor inspect the proxy entry your client uses.
Freeze pattern (from Corelight's remediation)
- Check out a pinned commit of the MCP server source—not only a floating tag.
uv syncorpip installwith a hash-pinned lockfile into a dedicated virtual environment.- Point MCP
commandat the venv binary (for example the console script path) instead ofuvx. - Turn off implicit refresh—avoid
@lateston both Python and npm launchers. - Schedule human review when you intentionally re-lock; Corelight notes frozen servers can still lag known-good upstream versions.
For a broader MCP hardening checklist, see the MCP security practical guide.
What to log on security workstations
Corelight's investigation combined DNS/TLS visibility with endpoint package installs. If you run coding agents on SOC or firewall admin laptops, treat the following as expected-but-sensitive registry traffic—not malware by itself, but worth correlating to MCP launches:
| Host | Why it matters |
|---|---|
pypi.org / files.pythonhosted.org | uvx or pip resolving Python MCP servers |
registry.npmjs.org | npx pulling MCP proxies such as mcp-remote |
github.com / codeload.github.com | Servers installed directly from commit URLs without hash verification |
Corelight's lab narrowed four hosts via network logs, then used EDR package events to tie installs to AI assistant startups. The lesson for agent operators: when your IDE opens, check whether PyPI traffic coincides with MCP handshake in local logs—not only on CI runners.
On shared machines, snapshot uv cache tool environments after first connect. Astral documents that environments live under the uv cache and may be rebuilt transparently; comparing uv tool list or vendor-specific MCP logs week-over-week catches drift faster than re-reading unchanged JSON.
Credential scoping for high-privilege MCP
Several community servers ship README examples that export AWS_*, GITHUB_TOKEN, or vendor API keys into the MCP env block because the demo needs them. That pattern is convenient for a read-only docs server and hazardous for a registry-mutable launcher.
Minimum bar before enabling a new server:
- Dedicated service account per MCP integration, not your personal admin user.
- Read-only API roles where the tool only lists assets.
- Short TTL tokens rotated on the same schedule you re-lock dependencies.
- Separate config for production vs lab—agents love copying working JSON between repos.
If a server truly needs write access, run it on a jumphost without your everyday agent profile, not on the laptop where Claude Code also edits application source.
How Beam handles this
Beam is local-first: it heuristically scans mcp.json and skill files before you run them, flags patterns such as unpinned npx, curl-pipe shells, and risky env wiring, and can deny selected tool calls on Claude Code and Codex when workspace policy is in enforce mode. That helps you catch obviously mutable launchers early.
Beam does not:
- Resolve or pin PyPI transitive dependencies when
uvxrebuilds an environment; - Block
uv cache cleanevents or registry downloads at the network layer; - Prove a pinned version string matches installed wheel hashes.
Use Beam's scan as one line of defense alongside frozen installs and credential scoping. Docs: scan skills and MCP configs.
When investigating an incident, a running Beam collector keeps bounded, redacted hook history of what your coding assistant proposed (PreToolUse and related events)—for example file reads or shell commands the agent attempted. That can help you correlate MCP config edits with later agent actions, but it does not log PyPI resolves inside uvx or prove which wheels loaded in the MCP server process. Pair it with EDR package telemetry, not instead of it.
Related reading
- MCP server security review checklist
- MCP TypeScript SDK OAuth flaw CVE-2026-104850
- npm supply-chain worms targeting AI tooling
- strutil-core RubyGem config poisoning
- F-Secure AI Harms TA-4 MCP supply chain
- Beam: what runs on-device
For wider news context on MCP install risk, explainx.ai covers MCP and agent setup friction in related tooling stories.
Frequently asked questions
What did Corelight publish about MCP servers on November 10, 2026?
Corelight's Bright Ideas post "The supply-chain risk hiding in your MCP servers" describes a lab investigation where AI assistants on an administrator workstation launched MCP servers with uvx. Pinned releases still produced changing PyPI transitive dependencies across repeated environment rebuilds.
Is this a flaw in the Model Context Protocol?
Corelight and the MCP specification treat it as a local setup choice. The protocol does not mandate how you install server code; the risk comes from launchers that resolve public registries inside the same process that holds MCP credentials.
Does pinning the MCP server version in mcp.json stop dependency drift?
Not when you launch with uvx or similar one-step runners. Astral documents that uvx provisions a disposable tool environment from the package index; transitive packages are not locked unless you install from a hash-pinned lockfile and start the server binary directly.
Who is affected?
Developers and security admins who run Claude Code, Cursor, Codex, or other assistants with local MCP servers started via uvx, npx, or pipx, especially when those servers reach firewalls, SIEM, or cloud consoles with privileged API keys in the server environment.
How do I freeze an MCP server environment?
Pin a source commit, install dependencies from a hash-pinned lockfile into a dedicated virtual environment, launch the installed entry point directly, and disable startup refresh tags like @latest. Corelight reported five frozen servers stayed identical across hundreds of restarts in its lab.
What does Beam do about uvx-launched MCP servers?
Beam scans mcp.json for risky launch patterns and version pins before you connect, but it does not freeze PyPI dependency trees or block uvx at install time. Use beam scan --mcp plus registry pinning; Beam's checks are heuristic, not a substitute for locked environments.
Related reading: CVE-2026-125926 in AWS mcp-gateway-registry (SSRF on server registration, Nov 2026) covers server-side gateway risk complementary to local uvx drift.
Primary sources: Corelight: "The supply-chain risk hiding in your MCP servers" (Bright Ideas, Nov 10, 2026) · Astral uv tools / uvx documentation · MCP local server security best practices · GHSA-6xpm-ggf7-wc3p / CVE-2025-6514
Launcher behavior follows Astral's uv documentation and Corelight's November 10, 2026 research summary as published on corelight.com; verify freeze steps against your MCP vendor's install guide before production use.

