MCP: A Mistake?
Earlier this week, Anthropic announced MCP, a new standard for connecting AI Agents to external data sources. The goal being to provide a way for frontier models to produce better, more reliable and accurate responses.
Understandably, this is pretty exciting. Most data sources are complex and locked in silos making them hard to access. The promise of MCP is that simply by exposing the data source as a standardized interface via an "MCP Server", we can access it from any model.
The Architecture
MCP is inspired from the Language Server Protocol, a standard for building language server extensions which standardizes how to add support for programming languages across a whole ecosystem of development tools.
┌─────────────────────────────────────┐ ┌─────────────────────────────────────────────┐
│ Application Host Process │ │ Internet │
│ │ │ │
│ ┌───────────┐ │ │ ┌────────────────┐ ┌─────────────────┐ │
│ │ Client 3 │────────▶ │ Server 3 │◀──▶│ Remote │ │
│ └───────────┘ │ │ │ External APIs │ │ Resource C │ │
│ ▲ │ │ └────────────────┘ └─────────────────┘ │
│ │ │ │ │
│ ┌────────┐ │ │ └─────────────────────────────────────────────┘
│ │ │──────────────┤ │
│ │ Host │ │ │ ┌─────────────────────────────────────────────┐
│ │ │──────┐ │ │ │ Local machine │
│ └────────┘ │ │ │ │ │
│ │ ┌────┴────┐ │ │ ┌────────────────┐ ┌─────────────────┐ │
│ │ │ Client 1│─────────▶ │ Server 1 │◀──▶│ Local │ │
│ │ └─────────┘ │ │ │ Files & Git │ │ Resource A │ │
│ │ │ │ └────────────────┘ └─────────────────┘ │
│ │ ┌─────────┐ │ │ │
│ └─▶│ Client 2│─────────▶ ┌────────────────┐ ┌─────────────────┐ │
│ └─────────┘ │ │ │ Server 2 │◀──▶│ Local │ │
│ │ │ │ Database │ │ Resource B │ │
└─────────────────────────────────────┘ │ └────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────┘
The architecture follows a client-server model with three core components: the Host, Clients, and Servers. Let's break down each of these.
Host
The host process acts as the container and coordinator for the entire system. In practice, this is an application like Cursor, Claude Desktop, or any AI-powered tool that needs to access external data.
The host is responsible for:
- Creating and managing multiple client instances
- Controlling client connection permissions and lifecycle
- Enforcing security policies and consent requirements
- Handling user authorization decisions
- Coordinating AI/LLM integration and sampling
- Managing context aggregation across clients
Think of the host as the orchestrator - it decides which servers to connect to, what permissions to grant, and how to combine information from multiple sources into a coherent context for the model.
Clients
Each client is created by the host and maintains an isolated connection to a single server. The host application creates and manages multiple clients, with each client having a dedicated relationship with a particular server.
Clients handle:
- Establishing one stateful session per server
- Protocol negotiation and capability exchange
- Routing protocol messages bidirectionally
- Managing subscriptions and notifications
- Maintaining security boundaries between servers
This isolation is intentional. By keeping each server connection separate, MCP ensures that a misbehaving or compromised server can't access data from other servers or the broader conversation context.
Servers
Servers are where the actual capabilities live. They provide specialized context and functionality through well-defined MCP primitives.
Server responsibilities include:
- Exposing resources, tools, and prompts via MCP primitives
- Operating independently with focused responsibilities
- Requesting sampling through client interfaces
- Respecting security constraints imposed by the host
- Running as local processes or remote services
The key insight here is that servers are meant to be simple and focused. A file server just handles files. A database server just handles database queries. This modularity makes servers easy to build, test, and compose.
Design Principles
MCP is built on several key design principles that inform its architecture and implementation:
Servers should be extremely easy to build
Host applications handle complex orchestration responsibilities so that servers can focus on specific, well-defined capabilities. Simple interfaces minimize implementation overhead, and clear separation enables maintainable code.
Servers should be highly composable
Each server provides focused functionality in isolation. Multiple servers can be combined seamlessly through a shared protocol that enables interoperability. This modular design supports extensibility without increasing complexity.
Servers should not be able to read the whole conversation
This is a critical security boundary. Servers receive only the contextual information they need to perform their function - nothing more. The full conversation history stays with the host, each server connection maintains isolation, and cross-server interactions are controlled exclusively by the host process.
Features can be added progressively
The core protocol provides minimal required functionality. Additional capabilities can be negotiated as needed, allowing servers and clients to evolve independently. The protocol is designed for future extensibility while maintaining backwards compatibility.
Capability Negotiation
MCP uses a capability-based negotiation system where clients and servers explicitly declare their supported features during initialization. This handshake determines which protocol features and primitives are available during a session.
Here's how it works:
- Servers declare capabilities like resource subscriptions, tool support, and prompt templates
- Clients declare capabilities like sampling support and notification handling
- Both parties must respect declared capabilities throughout the session
- Extensions can negotiate additional capabilities as the protocol evolves
Each capability unlocks specific protocol features. For example:
- Implemented server features must be advertised in the server's capabilities
- Emitting resource subscription notifications requires the server to declare subscription support
- Tool invocation requires the server to declare tool capabilities
- Sampling requires the client to declare support in its capabilities
The Problems
So far, MCP sounds great on paper. A standardized way to connect AI to data, with clean abstractions and sensible security boundaries. But as with most things in software, the devil is in the details. Let's talk about where this breaks down.
Security Feels Like an Afterthought
The initial MCP spec shipped without a defined authentication mechanism. This seems like a deliberate choice - auth is hard, and the designers wanted to keep the protocol simple. But this meant every server implementation rolled its own approach to authentication, ranging from "reasonably secure" to "basically non-existent."
There's also the issue of local code execution. MCP supports running servers over stdio, which makes local development frictionless. You don't need to spin up an HTTP server - just run a process. The downside? A lot of MCP integrations now instruct users to download and execute arbitrary code on their machines. For developers, this might be fine. For less technical users, it's a recipe for exploitation.
All Tools Are Treated Equal
Imagine you're chatting with an assistant that has access to a dozen MCP tools: reading your journal, booking flights, deleting files. Some of these actions are completely harmless. Others are expensive. A few are irreversible.
MCP has no built-in concept of risk levels. The protocol doesn't distinguish between a read operation and a destructive write. It's up to the host application to implement confirmation dialogs and safety rails - but even then, users tend to fall into patterns of auto-confirming everything when most actions are benign. One misclick later, and you've deleted something you can't get back.
Prompt Injection Gets Worse
LLMs already struggle with prompt injection - malicious input that overrides intended behavior. MCP makes this worse by giving tools a privileged position in the model's context.
Tools provided by MCP servers often get injected into the system prompt, giving them significant influence over how the assistant behaves. A malicious server could define tools that subtly manipulate the model's outputs, extract sensitive information, or hijack requests meant for other tools.
Even more concerning: MCP allows servers to dynamically redefine tool names and descriptions after the initial handshake. This opens the door to bait-and-switch attacks where a tool behaves one way during setup and differently during actual use.
And it doesn't stop at first-party servers. If your MCP server pulls data from an external source - say, a database with user-generated content - that content can itself contain injection payloads. The attack surface compounds quickly.
Context Pollution is Real
Here's a problem that doesn't get discussed enough: every tool call consumes tokens.
When an agent has access to many MCP servers, it often calls tools it doesn't actually need. Maybe the model is being thorough, or maybe it just doesn't know which tool is relevant. Either way, each unnecessary call pollutes the context window with irrelevant information.
This isn't just inefficient - it actively degrades performance. Models have finite context windows, and filling them with noise makes it harder to reason about what actually matters. Users end up paying more (tokens aren't free) for worse results. Some developers have started noticing that adding more MCP integrations makes their assistants less reliable, not more.
More Tools, Worse Performance
There's a counterintuitive reality here: LLM reliability often decreases as you add more instructional context. Users assume that connecting more data sources and tools will make their assistant smarter. In practice, it often makes things worse.
Tool use is genuinely hard for models. Even state-of-the-art systems struggle with accurate tool selection and parameter construction. Benchmarks that test real-world tool use show surprisingly low success rates. Adding more tools to the mix just compounds the difficulty.
Different models also respond differently to tool descriptions. What works well for one model might confuse another. A tool that performs great with Claude might fail with GPT-4, and vice versa. Users end up blaming the application or the MCP server when the real issue is a mismatch between tool design and model expectations.
Data Access Gets Murky
Even when everything works as intended, connecting an LLM to all your data creates new risks that traditional access control models don't account for.
An employee might have read access to public Slack channels, internal docs, and colleague calendars. That's fine - those permissions exist for a reason. But give that same employee an AI assistant with those same permissions, and suddenly they can aggregate and cross-reference information in ways that weren't anticipated. They might infer upcoming layoffs from exec calendars, identify anonymous feedback authors through writing style analysis, or piece together confidential deals from scattered breadcrumbs.
The agent has the exact same access as the user. But the ability to intelligently aggregate that access changes what's possible. Security teams will need to think carefully about what data agents can access - not just individually, but in combination.
Conclusion
MCP needed to exist. The promise of standardizing how AI connects to data is genuinely compelling, and the protocol's design principles are sound. I use MCP-connected tools daily, and when they work, they're transformative.
But "connecting AI to data" is an inherently risky proposition. MCP doesn't create these risks - it inherits them from the fundamental challenge of building reliable, secure AI systems. The protocol amplifies existing vulnerabilities and introduces some new ones along the way.
The path forward requires work on multiple fronts: the protocol itself needs to mature, host applications need to implement better safeguards, and users need to understand what they're opting into. We're still in the early days of figuring out how to do this responsibly.
For now, be thoughtful about which MCP servers you connect, understand what data you're exposing, and don't assume that more integrations means better results. Sometimes less is more.