The MCP Control Plane: Gateway, Registry & OAuth 2.1
Chapter 8 established the Model Context Protocol as the contract between an agent and its tools, and the M×N problem it dissolves. But a single host wired directly to a dozen MCP servers is itself the failure mode: credentials scattered across config files, no central place to authorize or audit a tool call, no rate limit, no curation, and tool names colliding the moment two servers both expose search. The fix is the same one every mature integration layer reaches — a control plane. It has three parts: a gateway on the data path, a registry for discovery and curation, and an authorization model that decides trust. This chapter builds all three, and is honest about where the standards are real and where they are still aspirational.
22.1 Why MCP needs a control plane
Direct client-to-server wiring breaks along predictable seams as server count grows. There is no single enforcement point, so authorization and audit must be re-implemented per host. Secrets for every upstream are mounted into the agent's process — exactly the blast radius Chapter 9 told you to avoid. Tool namespaces collide. Nothing rate-limits a runaway loop hammering a server. And nobody is vetting which servers an agent is even allowed to reach. Each of these is a platform concern, not a per-agent one, which is the definition of something that belongs in a shared layer.
stdio server — which the gateway must normalize behind one policy.22.2 The MCP gateway
An MCP gateway sits between hosts and servers and presents many servers as one virtual endpoint. Concretely it does seven jobs. It aggregates and routes — one connection for the client, fan-out to many servers behind it. It namespaces and de-duplicates tools so colliding names (search, read) become addressable and the model isn't handed two tools it can't tell apart. It performs authentication and token brokering — validating the caller, then attaching the correct upstream credential (see §21.4). It applies rate limits and quotas per tenant, per agent, per tool. It enforces guardrails as a policy point: tool allow-listing, JSON-Schema validation of arguments, and egress filtering of secrets or PII in tool results (Ch. 16). It emits observability — an OpenTelemetry span per tool call, the audit record Chapter 17 demands. And it provides resilience — timeouts, retries, and caching in front of flaky servers (Ch. 21).
Architecturally the gateway is a proxy data plane, so the natural implementations are proxy-shaped: an Envoy- or Rust-based agent proxy (for example agentgateway, or MCP support emerging in Kong, APISIX, and Solo's mesh), or purpose-built gateways such as Docker's MCP Gateway and IBM's open-source ContextForge. Whichever you pick, the role is fixed.
Every tool invocation should pass through one place that can answer "who is calling, are they allowed, with what budget, and is the result safe to return?" — and produce an audit record. Scatter that logic into hosts and you lose the single source of truth that authorization, rate limiting, and compliance all depend on.
22.3 The MCP registry
A gateway routes to servers; something must decide which servers exist and are trusted. That is the registry. The official MCP Registry publishes a catalog of servers with structured server.json metadata, hierarchical namespacing (e.g. io.github.…), version information, and a programmatic discovery API. In production you rarely point agents at the open catalog directly. You run a private or internal registry that mirrors and curates a vetted subset, pins exact versions, and attaches policy — which tenants may use a server, what scopes it needs, whether its results require extra filtering. Subregistries can federate from the public one while keeping the enterprise list authoritative.
An MCP server is executable supply chain: it runs with whatever credentials you give it and can exfiltrate everything it touches. Auto-discovering and connecting to arbitrary servers turns the registry into an attack vector. Curate, pin a version, and prefer signed/attested entries; treat adding a server like adding a dependency to production, because it is one.
22.4 MCP security: OAuth 2.1, available and not
The MCP authorization specification models an MCP server as an OAuth resource server: clients present an access token, and the server validates it. The June 2025 revision made a crucial correction — it separated the authorization server from the resource server, so an MCP server delegates identity to an external IdP (Auth0, Entra, Keycloak, your own) rather than minting tokens itself. The building blocks are existing, boring, well-understood OAuth standards.
| Standard | What it provides | Why MCP needs it |
|---|---|---|
| OAuth 2.1 | Consolidated OAuth with PKCE mandatory; implicit & password grants removed | A safe baseline flow for confidential and public clients |
| Protected Resource Metadata RFC 9728 | The server advertises which authorization server(s) issue its tokens | Lets a client discover where to authenticate, with no manual config |
| AS Metadata RFC 8414 | The authorization server publishes its endpoints and capabilities | Completes automated discovery of the auth flow |
| Resource Indicators RFC 8707 | Client requests a token bound to a specific resource (this server) | Stops a token for one server being replayed at another — the core defense |
| Dynamic Client Registration RFC 7591 | Clients register with the AS programmatically | Onboarding without hand-configuring every client/server pair |
That is the specification. Reality is uneven, and a platform has to handle the whole distribution, not the happy path. OAuth is defined for the HTTP transport; a local stdio server has no standard auth at all and relies on process and environment trust. A large tail of community servers ship with a static API key or bearer token, or predate the auth spec entirely. Only a subset of remote servers are fully 2.1-compliant with metadata discovery and resource indicators.
| Server reality | Auth available | How the gateway handles it |
|---|---|---|
| Compliant remote | OAuth 2.1 + 9728/8707 | Validate token, request resource-bound token via on-behalf-of exchange |
| Token-only remote | static API key / bearer | Hold the key in a vault; inject per-request; agent never sees it |
| Pre-spec remote | ad-hoc / none over HTTP | Front with the gateway's own authz; wrap or quarantine |
| Local stdio | none (process trust) | Confine to a sandbox; scope the launching environment tightly (Ch. 9) |
The gateway is what makes this tractable: it validates the inbound token, performs an on-behalf-of token exchange (RFC 8693, Ch. 15) to obtain a downstream token scoped to exactly the server being called, and injects static upstream credentials from a vault so they never enter the agent's context. It is, in effect, the adapter that gives a heterogeneous server population one coherent identity story.
The specification says a server must not accept a token that was not issued for it, and a client must not forward a token issued for one audience to a different server. Passing a user's token straight through to an upstream lets a malicious or compromised server replay it elsewhere with the user's authority — the confused-deputy attack of Chapter 15, in MCP clothing. Bind every token to its resource (RFC 8707) and exchange, never forward.