Treat MCP servers as supply chain, not plugins
Installing an MCP server feels like installing a browser extension: pick from a marketplace, click, done. That framing is wrong in a way that will eventually hurt. An MCP server is third-party code that injects prose directly into your model's context and frequently holds credentials to act on your behalf. That combination is a supply-chain trust decision — provenance, pinning, scoped authorization, continuous monitoring — not an app-store purchase.
The difference from classic dependencies is what the payload is. A malicious npm package has to smuggle in executable code. A malicious MCP server just has to write persuasive text. In a tool poisoning attack, the tool's description — which the model reads in full and the user almost never does — carries embedded instructions: exfiltrate the conversation, prefer this tool, ignore that policy. The rug pull variant is nastier: the server behaves impeccably at install and review time, then silently mutates its tool descriptions after you've extended trust. Cross-server tool shadowing goes further still, letting one malicious server hijack calls intended for a trusted server sharing the same context. These are the ecosystem's typosquatting and dependency confusion, rebuilt for a world where the attack surface is natural language.
What supply-chain discipline actually means here
Provenance first. The official MCP registry (September 2025) plus enterprise private sub-registries and allowlisting are the equivalent of a curated artifact repository — necessary because an open marketplace of thousands of community servers, growing fast, is a textbook lemon market where you cannot distinguish quality before you've already installed. Registry moderation today is a community denylist with retroactive removal; that's reactive, which is exactly why you don't outsource the decision to the marketplace.
Pinning second. Hash the tool schemas and descriptions at installation — SHA-256 — and verify on every reconnect. Description drift then becomes a detectable event demanding re-approval instead of a silent context change. This also catches the benign failure mode: tool inventory drift, where an innocent description rewrite quietly regresses your agent's behaviour with no code change on your side.
Authorization third. By default a local MCP server runs with your full user privileges and whatever tokens you hand it. Scope it like you'd scope a vendor integration: OAuth 2.1 with resource indicators and audience validation so a token minted for one server can't be replayed against another, no token passthrough, and process-level least privilege — stripped environments, sandboxed spawns — for anything you didn't build. The permissions framing of injection applies unchanged: assume the server's output is adversarial and bound what it can reach.
Monitoring last, because trust decays. Scanners like Invariant Labs' mcp-scan inspect tool descriptions for injection patterns; drift detection makes updates visible. Treat every server update as a new supply-chain event, not a patch.
The honest concession: this ceremony is disproportionate for some real cases. If you're one developer running a major vendor's official server against read-only data, hash-pinning and private registries mostly add friction. And pinning fights legitimate evolution — MCP still lacks tool-level semantic versioning (SEP-1575 is only a proposal), so today every description change looks like a potential rug pull. That's a gap in the protocol, not a reason to relax. The asymmetry stands: an over-cautious install costs minutes; an unvetted server with your credentials and your context costs an incident. Buy servers the way you buy dependencies you'll be liable for — because you will be.