MCP Server Architecture and Hosting Patterns
Stateless protocol shifts and five production patterns shape how MCP servers should actually scale.

MCP server architecture comes down to three hosting choices: local process, remote service, or gateway. Pick wrong and you find out at the worst possible moment, usually when a second user shows up or a security review asks a question nobody prepped for. Anthropic put out the Model Context Protocol in November 2024 to connect large language models to outside tools and data, and it rests on three roles: a host that runs the session (Claude Desktop, an IDE, some agent orchestrator you built), a client inside that host holding one live connection to one server, and the server itself, which hands over tools, resources, and prompts. Every message rides on JSON-RPC 2.0 no matter what's carrying it underneath.
The server itself has no agency. It's plumbing the model talks through, and a lot of the confusion floating around this space comes from treating it like a decision-maker instead of what it actually is.
The governance change matters more than people gave it credit for at the time, too. Late in 2025, Anthropic handed MCP over to the Agentic AI Foundation, a Linux Foundation directed fund started jointly by Anthropic, Block, and OpenAI. Overnight, more or less, it stopped being a proprietary API and became a vendor-neutral standard. The ecosystem did what open standards do when the timing lands right: thousands of GitHub stars in a few months, then tens of millions of downloads, then hundreds of community-built servers covering databases, dev tools, chat platforms, cloud infrastructure. That kind of growth is exactly what exposes the gaps nobody had mapped yet. What follows walks through the structural patterns showing up in production MCP servers right now, and what you actually do about them.
How the MCP transport layer has evolved, and why the shift to Streamable HTTP matters for deployment
Transport sets your latency, your ability to scale out, and whether your infra team can run this thing with tools they already know. The March 2025 spec deprecated HTTP paired with Server-Sent Events, and major providers are phasing it out. If you're standing up a new server today, don't put that one on the table.
The current target is Streamable HTTP, landed with the 2025-11-25 spec. It puts the whole server behind one HTTP endpoint, so load balancers, reverse proxies, and CDN edges treat it like any other HTTP service. Nobody has to hold open a persistent WebSocket-style connection just to move protocol traffic anymore.
That transport swap turned out to be the smaller change, though. The 2026-07-28 spec made the protocol core fully stateless, and that's the one that actually reshapes how you build. Gone are the old initialize/initialized handshake and the Mcp-Session-Id header. Every request now carries its own context inline: protocol version, client info, capabilities, all packed into a _meta field on the request instead of negotiated once at session start. Google's own experience running MCP at cloud scale pushed this directly; the old stateful session model assumed persistent connections, and persistent connections don't sit well with how cloud-native systems actually scale. Simon Willison put it plainly: statelessness "greatly decreases the complexity of implementing both clients and servers." That's not a small claim to make about a protocol this widely deployed, and it's the kind of line that only lands if you've tried to debug a stuck session at 1am and lost.
Here's the part teams get wrong. A server built against the old stateful model doesn't just start working once you drop it behind a load balancer; migrating it is real engineering work, not a version bump. Session assumptions baked into the code, connection lifecycle logic buried three layers deep, all of it needs rethinking from the ground up.
The five recurring structural patterns in production MCP servers
A 2026 peer-reviewed paper (arXiv:2606.30317) looked at fifteen independently built production MCP servers and found five patterns turning up again and again. That's a little surprising, honestly, given how young this ecosystem still is.
Resource Gateway servers act as a structured window onto a data store or external API. They hand over resources, documents, records, and file blobs rather than actions you trigger. Good fit for read-heavy work: knowledge bases, file systems, CMS backends, anywhere the model mostly wants to look something up instead of change it.
Tool Orchestrator servers expose callable tools that kick off downstream actions, with the server itself handling sequencing or fan-out across backend calls instead of leaving that to the model. This is where the paper's sharpest warning lands, and it's about tool count. Accuracy drops hard once a model has to hold more than roughly ten to fifteen tools in context at once. GitHub's MCP server is the cautionary tale: it reportedly loads over forty tools into context before the model has done anything at all, quietly wrecking performance before the conversation even starts.
Stateful Session Server patterns keep state per session across turns: open file handles, computations still running, artifacts built up over a conversation. Long-running agent workflows usually need this kind of server. The catch is that stateful servers resist scaling out, and the 2026 spec's stateless core moves that burden to the application layer instead. Redis, an external store, something outside the protocol itself.
Proxy Aggregator servers act as one MCP endpoint fanning out to several upstream servers or APIs behind the scenes. The model sees only one server; the proxy routes, merges results, and isolates failures so one broken upstream doesn't take everything else down with it. Close cousin to the gateway pattern, which gets its own section below because it earns the space.
Domain-Specific Adapter servers are thin translation layers between MCP and something legacy or proprietary: an ERP system, an internal API, a specialized database nobody wants to touch. No orchestration logic gets bolted on. The whole job is faithful protocol translation, and that narrowness is often exactly why these are the right first move for a team wiring MCP onto a system nobody plans to rewrite anytime soon.
The same paper flags four anti-patterns: tool overexposure, credentials leaking through config files, missing rate limits, no versioning strategy. All four come back in the security section below, because they're structural problems baked into how a server is shaped rather than bugs you patch once and move past.
The local-process hosting pattern and where it fits in a production context
Local-process servers run as a subprocess the host application launches directly, on the same machine, usually over stdio. This is the default for developer tooling: IDE integrations, CLI agents, a Claude Desktop config sitting on somebody's laptop.
The appeal is obvious the first time you try it. Zero network latency, since host and server share a machine. No authentication surface facing the outside world, because there's no outside world here to worry about. Setup is fast, too: no deployment pipeline, no infrastructure to stand up, just a process that starts and stops with the host.
The limits show up the moment a second person needs access, and they show up fast. Scaling simply doesn't happen: one process per machine, no way to spread load across instances. The server's lifecycle is tied to the host process, so nothing survives a restart. You can't share it across multiple agents or users without redeploying per host, and stdio transport isn't reachable by a remote client at all. There's no path to it, not without changing what the thing fundamentally is.
Think of local-process as a development pattern, a single-user pattern, not a destination. Teams that prototype this way and then try lifting the same server onto a cloud VM tend to hit the mismatch fast: session assumptions break, port binding gets weird, config management stops making sense, and a redeploy quietly turns into a rebuild nobody budgeted time for.
Remote hosted servers: what changes when the server becomes a network service
Move the server onto a cloud VM, a container, a managed service, and it opens up to agents running from anywhere. That access drags new decisions along with it, whether you want them or not.
Transport-wise, Streamable HTTP is the right call for anything remote under the current spec. It works cleanly with standard reverse proxies, load balancers, and TLS termination, no extra plumbing required.
Scaling depends heavily on whether the server holds state. A stateless server, per the 2026 spec, sits behind a load balancer with no session affinity needed at all; any instance can pick up any request without knowing what came before it. A server still carrying application-layer state, open file handles, computations mid-flight, needs sticky sessions or an external store like Redis so a rerouted request doesn't lose its place. The guidance that actually holds up in practice: set a defined ceiling on concurrent connections per instance, use circuit breakers with failure thresholds measured over short windows, and watch p95 and p99 latency closely, alerting when error rates cross a threshold you've actually tested.
Authentication changes shape, too, once the server stops being a subprocess and becomes something anyone can hit. Per-user OAuth is the default starting point, but at enterprise scale it gets clunky fast: every employee authorizing every server one at a time, no central audit trail, personal and corporate credentials tangled up in the same flow. The enterprise-managed authorization extension, stabilized mid-2026, fixes this with the Identity Assertion JWT Authorization Grant, giving you centralized token issuance and an auditable trail without making every user run the OAuth dance one server at a time.
Two more things matter once a server becomes a network service. Memory ceilings, because unbounded memory growth in a long-running server is one of the more common quiet failure modes you'll run into in production. And observability: Prometheus-style metrics on latency histograms, error rates, and throughput are standard here. Skip that instrumentation and diagnosing a performance regression against your MCP server turns into guesswork fast, usually at 2am, usually with someone on Slack asking why it's slow.
The gateway pattern and how it addresses the tool-count problem at scale
The tool-count problem isn't a hypothetical cooked up for a benchmark somewhere. Every tool schema loaded into context costs tokens, and once you're running dozens of upstream servers each with their own tool set, the model's reasoning degrades before it's done any real work at all.
The gateway pattern is the answer that's emerged for this. Instead of the model connecting to many upstream MCP servers directly, everything sits behind one MCP-facing facade. Cloudflare's reference architecture is the clearest public example: a centralized portal fronts every internal MCP server, handles audit controls, and discloses tools progressively instead of dumping the whole list at once. All those upstream servers collapse down to two portal tools the model actually sees: one for searching available tool definitions, one for executing whatever it finds. The model writes small bits of code to filter and explore those definitions across every connected server, finding what it needs without loading every schema into context up front. Token costs drop because of the architecture itself, not because someone wrote a cleverer prompt.
The gateway buys more than tool management, too. Centralized authentication means one auth surface instead of a separate OAuth setup per server. Audit logging becomes unified across every tool call, which matters in regulated industries where that trail is a hard compliance requirement. Rate limiting and circuit breaking sit at the perimeter, protecting upstream servers from an agent that starts making runaway calls for reasons nobody can quite explain later.
None of it comes free, though. The gateway becomes a single point of failure by design; if it goes down, everything behind it goes down with it. That means the same reliability engineering you'd put into any production API gateway, no shortcuts just because the word "MCP" is in the name. Anthropic's own guidance points at the same idea from a different angle: running code in-context against MCP servers lets you batch and filter results structurally instead of dumping everything raw into the model's context window. The gateway pattern takes that same principle and moves it down a layer into the infrastructure where it belongs.
Security properties that differ by hosting pattern, not just by implementation
Security here doesn't map cleanly onto normal API security thinking, because the inputs aren't strings a person typed that you can validate ahead of time. They're model outputs, and you can't fully predict or audit those before they happen. A 2025 audit found a meaningful share of early MCP servers open to prompt injection attacks capable of running arbitrary commands on the host system. It's already been exploited, not just theorized in some whitepaper.
One case makes the stakes concrete. PromptArmor disclosed a vulnerability in Snowflake's Cortex Code CLI, made public in early 2026, where indirect prompt injection combined with weak command validation let AI-generated instructions slip past human-in-the-loop approval, escape the CLI's sandbox mode, and reach cached credentials. It's a clean example of how the attack surface runs through the whole tool-call chain, not just the one function you thought you'd locked down carefully.
Hosting pattern shapes how exposed you actually are, and it's worth being blunt about this. A local-process server runs with the host user's full permissions; there's no boundary at all between the server and the host's filesystem, credential store, or network. A remote containerized server can enforce memory and filesystem limits, but a container by itself isn't strong isolation if the container runtime has known holes. CVE-2024-21626, the "Leaky Vessels" runc flaw, showed a real container escape through a file descriptor leak. Anything running AI-generated code needs a hardened layer underneath the container: microVM technology, or something in the gVisor family that intercepts system calls in user space and never hands them to the host kernel directly.
The 2026 spec adds a couple of protocol-level primitives worth knowing by name. Issuer Verification, from RFC 9207, guards against authorization server mix-up attacks in setups running multiple servers. Resource Indicators, from RFC 8707, solves the confused deputy problem, where a compromised server tricks an agent into using its token somewhere it was never supposed to go.
The baseline across the security literature on agentic code execution is unforgiving but simple: any MCP server that generates and runs code needs to do it inside a strongly isolated sandbox, an ephemeral container or microVM spun up from a minimal base image, run once, output captured, then destroyed completely. Generated code should never run in a persistent environment where privileges can pile up over time without anyone noticing.
Teams that need this at real production scale, sub-second provisioning, sessions that survive across sandboxes, sign-off from a security team that actually reads the architecture doc, end up treating the sandbox layer as the central engineering problem, building it in from the start rather than stapling it onto a generic container host after the fact. Daytona builds sandbox infrastructure for exactly this: isolated runtimes that spin up in under 90 milliseconds, stateful by design so long agent workflows survive across sessions, Docker-native so it fits the tooling teams already run day to day, and compliant with SOC 2, HIPAA, and GDPR. It's the kind of foundation a team needs if it wants to ship an MCP server with real code-execution capability without quietly taking on risk nobody actually signed off on.
How to match a hosting pattern to actual production constraints
None of the patterns above wins outright, and that's the whole point of laying them out side by side instead of picking a favorite. A local-process server is exactly right for a solo developer wiring up a CLI tool on their own machine, and wrong the moment a second user needs access. A remote hosted server earns its added complexity once you actually need horizontal scale or centralized auth; bolting Streamable HTTP onto a server that still assumes stateful sessions causes more problems than it solves if nobody does the migration with care.
The gateway pattern is the right call specifically when tool count becomes the bottleneck, not before it shows up as one. Standing up a gateway to front three internal servers is over-engineering for its own sake. Standing one up to front forty is closer to a necessity. Meanwhile, the security posture that matters shifts with the hosting pattern itself, not just with how carefully any one implementation happened to get written. A local-process server inherits the host's permissions no matter how clean the code underneath looks. A remote server's exposure depends on container isolation decisions made well before the first request ever arrives.
So which constraints are you actually building against? How many users, how much state, how many upstream tools, how much scrutiny does your audit trail need to survive? Answer those in that order, honestly, and the hosting pattern mostly picks itself, though "mostly" is doing real work in that sentence. There's always some edge case that doesn't fit the framework, and you'll find it about three weeks after launch.


