Est.
MCP SecurityLong read

Economy of Mechanism in MCP Server Design

Keeping MCP servers simple cuts through security flaws that complexity hides.

Staff Writer · · 12 min read
Cover illustration for “Economy of Mechanism in MCP Server Design”
MCP Security · August 26, 2026 · 12 min read · 2,727 words

Economy of mechanism is a fifty-year-old security principle, and it says something almost embarrassingly simple: the smaller a system is, the fewer places it has to break. Saltzer and Schroeder wrote it into their 1975 paper, "The Protection of Information in Computer Systems," with a line that still holds up: "Keep the design as simple and small as possible." I've been staring at that paper on and off for years, long before MCP existed, and it's still the sharpest lens I've got for looking at what's happening with these servers right now. Every extra tool, every unscoped permission, every capability a server exposes "just in case" is a door nobody with a governance hat on ever actually signed off on.

Saltzer and Schroeder were writing about mainframes and access control lists. A world that looks almost quaint now, decades before anyone dreamed up an AI agent. But they zeroed in on protection mechanisms specifically, because normal use never tests the door that shouldn't be there. A system can run for years, pass every audit, satisfy every user, while a flaw sits quietly in a corner waiting for someone to go looking for it on purpose. Complexity hides bugs. Not the loud kind. The kind nobody finds until an attacker does.

That paper laid out eight principles total: economy of mechanism alongside fail-safe defaults, complete mediation, least privilege, and a handful of others. None of them work alone, which is easy to forget when you're only reading about one. A smaller design makes every other principle cheaper to enforce. Least privilege is trivial to check when there are ten tools, and close to impossible when there are ninety. I've read retrospectives on SolarWinds and on Log4j that both land on the same missing principles, economy of mechanism among them. Fifty years later, the same framework still diagnoses the failure. That's the gap I want to sit inside for a while: how old the idea is, and how well it still explains what's going wrong with MCP servers today.

Venn diagram: MCP Server Design: Security vs. Complexity. Compares Economy of Mechanism and MCP Over-Exposure; overlap: Shared Risk.

What MCP is and what it means for the attack surface that governs it

Anthropic put the Model Context Protocol out as open source in November 2024. By February 2025, over 1,000 servers existed. By autumn, the count passed 5,500. None of that growth waited for a governance framework to catch up, and by April 2026, MCP SDKs were logging 97 million monthly downloads, with more than 10,000 published servers live and native support sitting inside Claude, ChatGPT, Gemini, and Microsoft Copilot.

The architecture underneath all that growth is fairly plain, honestly. An MCP host (an AI application) connects to one or more MCP servers, each through its own dedicated client. Servers expose tools, resources, and prompts, and the exchange rides on JSON-RPC 2.0. MCP exists to kill the N×M integration problem: connecting N tools to M model front-ends without hand-building a bridge for every pair. That's why the ecosystem took off the way it did. It's also why every new server is a new opening.

Here's the structural fact that matters most, and it's easy to skate past. When an agent connects to a server, it gets that server's entire tool catalog, full stop. Whatever the server decides to expose is the whole boundary between the agent and everything sitting behind it. There's no partial handshake, no soft introduction where the agent gets a taste first before committing. So deciding what to expose, and what to leave out, is a security decision made at design time, whether or not the person building the server ever thinks of it that way.

How over-exposure happens by default: the kitchen-sink server and the god-tool

Table: MCP Anti-Patterns vs. Economy of Mechanism. Compares What it looks like, Surface area, Primary failure, Token cost, and 1 more by Kitchen-Sink Server and God-Tool.

Two anti-patterns show up over and over in production MCP servers, and they look like opposites at first. They're not. Both trace back to the same root failure: nobody sat down and deliberately designed the surface area, so the surface area designed itself.

The first is what I'd call the kitchen-sink server: the one that dumps 80 or more tools during the initial tools/list handshake, regardless of what the agent's actually trying to do or what the user's even allowed to touch. A few things happen when this occurs, and none of them are hypothetical. Handshake bloat comes first, flooding the agent's context before it's done anything useful. Selection entropy follows right behind: the needle-in-a-haystack problem, where tool-selection accuracy drops the moment a model has to pick from a huge, undifferentiated list. Underneath both sits the security boundary violation, where sessions that had no business knowing an administrative tool even exists now know it exists, because it showed up in the list handed to everyone.

David Soria Parra, one of MCP's co-creators, said it plainly at AI Engineer World's Fair 2025: wrapping an existing REST API one-to-one as a set of MCP tools "is a bit cringe, it just results in horrible things." He compared it to the old distributed-monolith disaster, just rebuilt with a new protocol stapled on top. And here's the part that catches people off guard: this happens even when no human is designing the server. I've talked to a few people building MCP servers with agentic coding tools, and more than one has noticed the AI itself tends to overreach, trying to make the server "too smart," stuffing analytical logic into places that have no business holding it. That instinct runs directly against economy of mechanism. It's a little unsettling how naturally it shows up, actually, like the model wants to be helpful in exactly the wrong direction.

The second anti-pattern is the god-tool. Picture one mega-tool, something like run_command(action, params), where action can be one of fifteen different string values, and the tool does something completely different depending on which one gets picked. The schema technically allows every combination of parameters, but most combinations are invalid for any given action, and the model has no way to resolve that ambiguity just by reading the schema. So it picks the wrong action. Or the parameters fail validation somewhere deep inside the handler. Or the model just refuses to call the tool at all because it can't figure out what's safe.

One tool with fifteen internal branches is structurally identical to fifteen separate tools with no boundaries between them. Same attack surface, just hidden behind a single name, which somehow makes it feel smaller. The hiding is the only thing that changed.

The token cost that makes complexity immediately measurable

Diagram: Context Window Consumed Before Any Reasoning Begins. Visualizes: Visualize how a 200,000-token context window gets eaten by tool-definition overhead before an agent does any real work.

Complexity in MCP shows up as a bill, and the bill is easy to run up without noticing. A 93-tool GitHub MCP server costs 55,000 tokens in tool definitions alone, before the agent's done a single thing. Connect three services, say GitHub, Slack, and Sentry, and you've burned 143,000 tokens out of a 200,000-token context window. That's 72% of the whole window gone before any actual reasoning starts.

Run that at scale, 1,000 requests a day, and schema overhead alone costs $170 a day. Something like $5,100 a month, before the model reasons about anything real. MuleSoft's enterprise analysis from June 2026 found that a single SaaS MCP server with 30 or more tools can add 150,000 to 300,000 definition tokens to every call, whether the agent touches any of those tools or not. Multiply that across the dozens of MCP servers a real enterprise runs at once, and the overhead compounds faster than most teams budget for.

This isn't some future problem waiting in the wings, either. As of October 2025, Cursor and Claude Code were already exposing 18 and 15 tools respectively to their coding agents, with tool definitions eating 5 to 7% of the context window before the user typed a single prompt. That's the small-scale preview of what enterprise deployments are running into right now, just at much larger scale.

Token cost matters here for a reason that goes past the invoice, though. What consumes context is what the agent can see and act on; those are the same problem wearing different clothes. Stanford researchers documented what they called the "lost in the middle" effect, where model performance drops by more than 20% when relevant information sits in the middle of a long context instead of at the beginning or end. A bloated tool list costs money, sure, but it also buries the one tool the agent actually needed under seventy it didn't need at all. Separate benchmark data puts a number on where this breaks: accuracy sits around 91% at 10 tools for Haiku-class models, then drops to 87% at 15. The usable boundary looks like somewhere around 10 to 15 tools per context, no matter how tempting it is to bolt on one more.

What the real security exposure looks like when MCP servers go ungoverned

A July 2025 internet-wide scan turned up 1,862 MCP servers sitting exposed on the open internet, answering unauthenticated tool-listing requests like nothing was wrong. The MCP authorization spec does define OAuth 2.1, worth saying clearly, but it marks it optional. And optional security tends to mean absent security once a deadline shows up and somebody has to ship.

By April 2026, the number of exposed servers had grown substantially, with attackers actively going after cloud-specific MCP implementations. The threat profile broadened well beyond initial data-exposure concerns, and that shift happened faster than most of the write-ups I've read gave it credit for. As of May 2026, there are at least 7 confirmed high- or critical-severity CVEs spread across major MCP-integrated platforms, including MCP Inspector, LiteLLM, Cursor IDE, LibreChat, and Windsurf.

Then there's tool poisoning, maybe the cleanest illustration of the whole problem I've come across. Demonstrated attacks have shown that a single poisoned tool description can exfiltrate private repository contents with zero user interaction required. Testing against real-world MCP servers has recorded significant attack success rates. The broader security community has catalogued tool poisoning alongside related attacks like rug pulls and tool shadowing, all three targeting the same thing: the capability supply chain agents depend on just to function.

The structural cause running underneath all of it: MCP clients inherit trust from whatever server they connect to, with no ongoing check on whether that trust is still earned later. Every tool a server exposes is a trust extension the client makes automatically, no questions asked, no second look. This is Saltzer and Schroeder's warning playing out exactly as written on the page. These vulnerabilities existed and went unnoticed precisely because normal use never exercises the improper path; only an attacker goes looking for it on purpose. A 2025 academic survey summed up where the field actually stands, and I think it's honest to a fault: MCP security research "remains at the level of guiding technical approaches." The governance layer is still being poured while the building keeps going up around it.

What economy of mechanism looks like as a concrete design practice for MCP servers

MCP's own best-practices documentation says it plainly: "Each MCP server should have one clear, well-defined purpose." That's a security boundary, stated as a design rule, and it deserves to be read that literally, not as a nice-to-have.

Start with scoping tools to what the user's actually trying to do, not to everything the underlying system happens to support. One tool per intent, the smallest schema that captures that intent without ambiguity left over. Itential's production guidance from May 2026 makes the point directly: the teams that succeed with MCP "design curated, intention-level capabilities," setting that discipline against the pull toward posting the largest tool count on a slide. Their framework leans on outcome-first tool design, aggressive curation of surface area, and context resources with real boundaries around them. A decent rule of thumb: if a tool only works correctly when the model understands the server's internal logic, that tool's too big, and it needs to be split.

Authentication boundaries matter just as much as tool boundaries, maybe more. Mixing domains on one server means a session authenticated for Slack, say, can also see tools meant for GitHub sitting right next to it. That's the kitchen-sink server's flaw, stated precisely rather than vaguely. Separate servers for separate domains make role-based access control something you can actually enforce by construction, instead of something you're hoping a policy document catches after the fact.

Shared state deserves its own scrutiny, too. When tool invocations share state, one tool's side effect becomes another tool's unexpected input, which is exactly the failure mode Saltzer and Schroeder's "least common mechanism" principle was written to head off. Stateless, or close enough to it, tool handlers keep the blast radius small. A compromised call can't leak into the next one down the line.

Dynamic toolsets and lazy loading turn this into infrastructure you can actually point to. Speakeasy's benchmarks from November 2025 found up to 160x token reduction against static toolsets: a 96% average drop in input tokens, 90% overall token reduction, all while task success rates held steady. The mechanism's simple enough. A describe_tools function lets the model pull schemas only for the tools it plans to use, instead of loading every schema at connection time whether it needs them or not. Since schemas are the biggest token cost in the whole exchange, pulling them on demand instead of pushing them up front changes the math completely.

There's a security payoff tucked inside that efficiency gain, too, and it's easy to miss if you're only counting tokens. A tool that isn't visible in a given session can't be probed, poisoned, or shadow-attacked in that session, because it isn't there to attack. Dynamic exposure saves money and scopes the attack surface down to whatever the session actually needs, nothing past that. The MCP+ post-processing wrapper takes the same logic and applies it on the output side, intercepting tool results and returning only the relevant data, with claimed inference cost reductions up to 75%. Same principle, running on the way out instead of the way in.

The target worth building toward: granular primitives for data access, paired with a discovery layer controlling which primitives are visible at any given moment. The model keeps full composability, context stays lean, and the attack surface only ever matches what the session was actually built to do.

Why small-by-construction requires a governance layer to hold at scale

A well-designed MCP server is economy of mechanism at the component level, and that's genuinely worth something. But most enterprises aren't running one server. They're running dozens, sometimes hundreds, and the real attack surface is the sum of all of them together, not any single one taken in isolation.

Every server that gets added without a registry entry becomes an identity the organization can't account for. An identity nobody's tracking is exactly the one that ends up exploited, because nobody's watching closely enough to notice when it starts behaving strangely at 2am on a Saturday.

Dynamic toolsets and session-scoped exposure sound great on paper, but they need something upstream deciding what a given session is even authorized to see in the first place. That's role-based access control for agents, and it has to be a deliberate call somebody made, not a default nobody thought about until it mattered. Visibility only helps if it's live, too. An audit log read after a tool-poisoning incident already happened is a postmortem: useful for the next fix, and no use at all for the one that already went wrong.

A gateway that enforces scope at the protocol level, instead of counting on every individual server's implementation discipline to hold on its own, is what lets "small by construction" survive contact with an ecosystem still growing by the thousands every few months. I'd point to MCP Manager here, built on Usercentrics' data governance foundation, because it's aimed at exactly this layer: the registry, the access controls, the real-time observability that turns a pile of individually well-designed servers into one coherent security posture across the whole organization.

The organizations treating AI governance as a real edge before an incident forces their hand are the ones building this layer early rather than late. Fast adoption and safe adoption meet at the same place: a gateway that shows the right tool to the right session at the right time, and nothing else. Most of the friction people blame on security traces back, if you look closely enough, to the absence of the gateway that should've been sitting there from day one.

Filed underMCP Security

More in MCP Security