Fig 1. Official MCP transports as of spec 2025-11-25.
Transport
As of spec 2025-11-25, MCP officially defines two transports. The previous HTTP+SSE transport was deprecated in 2025-03-26 and fully replaced by Streamable HTTP. WebSocket transport (SEP-1288) remains a community proposal in review — not part of the official spec.
stdio
Spec 2024-11-05+
Client spawns the server as a subprocess and exchanges messages over standard streams. Ideal for local development and IDE-embedded servers. Useless across a network boundary.
Streamable HTTP
Spec 2025-03-26+
Single HTTP endpoint supporting both POST and GET. Stateless by default, with optional session tracking via Mcp-Session-Id. Servers can optionally stream responses via SSE.
HTTP + SSE
Spec 2024-11-05 only
The original remote transport. Two separate endpoints linked by a server-held socket-bound session. Breaks at multi-pod scale. Retained only for backward compatibility.
WebSocket
Not in spec yet
Proposed for full-duplex, bidirectional use cases. Actively debated in the Transport WG. Introduces session-binding complexity the community is trying to move away from.
Official community stance
The MCP Transport WG has confirmed: only two official transports — stdio for local, Streamable HTTP for remote. The next spec update focuses on making Streamable HTTP fully stateless to resolve horizontal scaling pain points.
Why the old SSE transport was deprecated
The original HTTP+SSE transport was stateful by design. It required two separate endpoints and held session state bound to a specific server instance via a live TCP socket. This made it fundamentally incompatible with multi-pod Kubernetes deployments and standard load balancers. Streamable HTTP replaces this with a single endpoint and a stateless-first model where sessions are serializable data rather than socket-bound state.
Fig 2. Scaling progression. Streamable HTTP sessions are application-layer data — portable across pods via Redis.
Scaling Patterns
Given a production MCP server, how do you scale horizontally without the gateway becoming the bottleneck?
Simplest
Single replica
One pod, one worker. Fine for low-volume workloads. No fault tolerance. A starting point, not a destination.
Historical fix
Sticky sessions
Routes requests to a fixed pod. Works for legacy SSE. Uneven load, complex rollouts, opaque failover.
Externalize state
Redis sessions
Move session data to Redis. Any pod can resolve any Mcp-Session-Id on demand. The pragmatic middle ground.
Current best
Fully stateless
No server-side session state. Any pod handles any request. Free autoscaling, zero-drop rollouts.
The emerging industry standard: prefer stateless transport, externalize genuinely shared concerns to Redis, and accept sticky sessions only when a specific feature requirement makes them unavoidable.
Access Control
Once more than one agent or team can reach your gateway, you need authentication and authorization. The 2025-03-26 spec codified OAuth 2.1 as the standard authentication framework for MCP — a significant upgrade over ad-hoc JWT approaches that dominated early deployments.
Authentication options
Spec standard
OAuth 2.1
Codified in the MCP spec since 2025-03-26. Enables universal SSO integration, delegated access, and federated identity. The recommended path for new deployments.
Still common
JSON Web Tokens
Symmetric (HS256) for internal deployments, asymmetric (RS256) for federated issuers. Simple, stateless, well-tooled. Effectively the JWT layer underneath OAuth 2.1.
Transport-layer
Mutual TLS
Certificate-based identity verified at the TLS handshake. Gold standard inside a service mesh, but it shifts identity into certificate lifecycle overhead.
Authorization models
Familiar
RBAC
Named roles group permissions. Works until tool catalogs grow — then roles proliferate or stretch.
Expressive
ABAC
Policies on request attributes. Needs a policy engine. Warranted for conditional access.
Dominant
Scope-based
Tokens carry scope strings. Simple, auditable. The interesting question is scope granularity.
Elegant, rare
Capability tokens
Unforgeable tokens grant specific capabilities. Theoretically clean, uncommon in practice.
Tool-based scoping
The scope granularity decision has significant downstream consequences for enforcement, auditability, and operational overhead. Tool-based scoping — assigning a unique, deterministic scope identifier to every individual tool — pushes authorization to the finest possible granularity.
Structural uniqueness. The scope string is a 1:1 function of the tool's identity in the source tree. Two developers cannot accidentally claim the same scope because the derivation mechanism forbids it.
Constant-time enforcement. A hash-set membership test against the token's scope claim is sufficient. No regex evaluation, rule walking, or policy execution on the hot path.
Implicit registry. The authoritative list of valid scopes is the set of registered tools. No external registry needs to be maintained in sync with the code.
Refactor safety by construction. Renaming or relocating a tool updates its scope identifier automatically. Stale strings cannot survive a refactor because there are no strings to be stale.
Hierarchical matching via naming convention. Structured identifiers admit prefix-wildcard grants, compressing broad permissions into compact claims without sacrificing fine-grained enforcement on the server side.
The scope allocation problem
Whatever granularity you choose, scope strings must come from somewhere. Manually curated scopes have well-known failure modes: collisions across teams, stale strings after refactors, inconsistent naming, and cognitive overhead on every new tool added.
Compliance-first
Centralized registry
Platform team curates a scope catalog. Pull requests for new scopes. Tight control, slow iteration.
Rising
Convention-based derivation
Scopes derived mechanically from tool identity. Uniqueness, refactor safety, zero human judgment required.
Programmable
Policy engines
Access decisions externalized to OPA or Cedar policies. Powerful but adds a dedicated policy language.
Multi-Tenancy
If your gateway serves a single team, skip this section. If multiple teams or product lines share it, three archetypal patterns — documented extensively in SaaS architecture literature — apply directly to MCP gateways.
Silo
Dedicated per tenant
Each tenant gets its own deployment. Maximum isolation, maximum operational cost. Appropriate for compliance-bound or external-customer scenarios.
Pool (recommended)
Shared + namespace
All tenants share a deployment. Isolation enforced at the application layer via identity and naming conventions. Near-zero marginal cost per tenant.
Bridge
Shared control, split data
Shared gateway with per-tenant backend workers. Flexible and nuanced. Usually emerges from silo or pool deployments that need more granularity.
For MCP gateways among internal teams, pool tenancy is the overwhelmingly common choice. Treat tenants as namespaces — logical partitions within a shared gateway — and rely on scopes to enforce isolation. The operational overhead per tenant is approximately nothing.
Reliability Patterns
Rate limiting
Three canonical algorithms dominate: token bucket (most widely deployed — tolerates bursts), leaky bucket (smooths outbound traffic to a constant rate), and sliding window (avoids boundary effects of fixed windows). All three operate at gateway granularity — per agent, per tenant, per tool, or composites. Redis is the default shared backend; in-memory counters only work for single-pod deployments.
Circuit breakers
Circuit breakers protect against repeated failures from a downstream dependency. After a threshold of consecutive errors, the breaker trips and subsequent calls fail fast without being attempted, during a cooldown period. The pattern originates in Michael Nygard's Release It! and applies naturally at per-tool granularity in MCP gateways.
Fail-open vs fail-closed
Fail-closed where the decision is about security or correctness. Fail-open where the decision is about protection or optimization. For MCP gateways: auth fails closed, rate limiting and circuit breakers fail open. The gateway should survive infrastructure outages — not amplify them.
Caching
Tool responses are often cacheable — status lookups, reference data reads, catalog queries. Caching at the gateway layer has significant latency and cost benefits, but several design questions need explicit answers up front.
Opt-in, not opt-out. Tools explicitly declare cacheability. Write operations never accidentally get cached. Safer default than blanket caching with exclusions.
Cache key design. Deterministic, includes all inputs that affect the result, excludes those that don't. Typically a hash of tool name plus sorted arguments.
TTL strategy. Short for frequently changing data, long for effectively static data. Per-tool TTLs are more accurate than a single global default.
Invalidation. The universally hardest problem in caching. TTL-based invalidation is the pragmatic baseline; event-driven invalidation requires upstream cooperation and adds system complexity.
Observability
MCP gateways benefit from the same three-pillar observability model as any service: logs, metrics, and traces.
Logging
Separate log streams by concern. A common pattern splits logs into three channels: application logs for debugging, audit logs for compliance and usage analytics, and access logs for traffic analysis. Structured JSON logging makes every stream machine-queryable by default.
Metrics
Gateway-level: requests per second, error rate, latency percentiles, active connections. Per-tool: invocation count, error rate, latency, circuit breaker state. The RED method (Rate, Errors, Duration) and USE method (Utilization, Saturation, Errors) give solid starting points for what to measure.
Distributed tracing
Agent workflows often span multiple tool calls, each of which may invoke multiple upstream APIs. OpenTelemetry has become the de facto standard for propagating trace context across the call graph. If you aren't propagating trace context today, you're flying blind during production incidents.
The Operational Stack
A production MCP gateway deployment typically combines: a container platform (Kubernetes), a load balancer with TLS termination, a shared state backend (Redis), an OAuth 2.1 identity provider, a log aggregator, a metrics backend, a tracing backend, and optionally a policy engine. None of these are MCP-specific — they are the standard cloud-native stack.
Fig 3. Production MCP gateway operational stack. Every pod is stateless. Redis holds all shared state. OAuth 2.1 authenticates every call.
Every box except Redis is stateless. Every pod is interchangeable. Tool annotations inform middleware decisions without custom logic per tool. The Tasks primitive means long-running operations can return a task ID immediately and be polled asynchronously.
Open Problems
Cross-gateway discovery
Agents today connect to a single gateway. Federated tool discovery across organizational boundaries is actively discussed but not yet standardized.
Dynamic tool loading
Adding a tool currently requires a deployment. Hot-reload mechanisms would meaningfully reduce iteration overhead for fast-moving catalogs.
Rate limit signaling
HTTP has X-RateLimit-* headers. MCP has no equivalent. Today, clients retry blindly rather than backing off intelligently based on gateway state.
Permission delegation
Many workflows involve one agent invoking another. The current model forces all access through the top-level agent's scopes — a constraint for multi-agent orchestration.
Takeaways
Transport
Streamable HTTP
The default for remote deployments. stdio for local use only.
Auth
OAuth 2.1
Spec-standard since 2025-03-26. Universal SSO integration.
Scopes
Derive, don't curate
Per-tool scoping with convention-based derivation.
Tenancy
Pool by default
Namespace-based isolation. Silo only when compliance requires it.
State
Redis for shared concerns
Rate limits, breakers, caches. Never live connections.
Observability
Three log streams
App, audit, access. RED/USE for metrics. OpenTelemetry for traces.
Closing
If there is a single takeaway from surveying the MCP deployment landscape in 2026, it is this: the protocol is stable, the operational patterns are borrowed almost entirely from general-purpose microservice practice, and the only genuinely novel decision most teams face is transport choice.
Get that right — bias toward statelessness, accept stickiness only when a specific feature requirement demands it — and the rest of the stack falls into place using patterns every backend engineer already knows.
The interesting problems have moved to the edges: federation, dynamic loading, delegation, and standardized observability. Those are the topics the next wave of MCP engineering writing will tackle. We are looking forward to reading them.
References & further reading
Official specs & foundational material
MCP Specification
spec.modelcontextprotocol.io
MCP Python SDK
github.com/modelcontextprotocol/python-sdk
MCP announcement
anthropic.com/news/model-context-protocol
Streamable HTTP transport
spec.modelcontextprotocol.io/…/transports
MCP in production — community writing
Medium — MCP tag
medium.com/tag/model-context-protocol
Medium — AI agents tag
medium.com/tag/ai-agents
Medium — LLM tag
medium.com/tag/llm
Distributed systems & scaling
Designing Data-Intensive Applications
dataintensive.net
The Twelve-Factor App
12factor.net
Release It! — Nygard
pragprog.com/…/release-it
Medium — microservices
medium.com/tag/microservices
Medium — Kubernetes
medium.com/tag/kubernetes
Authentication & authorization
OAuth 2.1
oauth.net/2.1
RS256 vs HS256
auth0.com/blog/rs256-vs-hs256
Okta — RBAC concepts
developer.okta.com/…/rbac
Open Policy Agent
openpolicyagent.org
Medium — JWT tag
medium.com/tag/jwt
Medium — OAuth tag
medium.com/tag/oauth
Multi-tenancy
Tenant isolation strategies
aws.amazon.com/…/tenant-isolation
Medium — multi-tenant arch
medium.com/tag/multi-tenant-architecture
Reliability & operations