Gateway Patterns
Purpose and Scope
A gateway is any process that fronts one MCP server with many short-lived clients. In this SDK documentation, that includes a proxy, a worker pool, or another fleet entry point that needs many client instances to share the same view of a target server. The gateway page teaches the performance pattern: probe the server once, persist the resulting advertisement, and let later workers connect from that prior result without sending their own discovery traffic. This page explains that pattern as an operational design, not only as a code sample.
Sources: docs/advanced/gateway.md
Use this pattern when the expensive or high-fan-out part of your architecture is client creation rather than individual tool calls. A bootstrap client performs the first connection with version negotiation enabled, records the server advertisement, and publishes that value to the rest of the fleet. Each worker then constructs an ordinary SDK client and connects with the prior discovery value. The SDK treats that worker as connected immediately, so later calls such as tool invocation can proceed against the selected transport while the server has not received a discovery request from that worker.
Sources: docs/advanced/gateway.md
Relevant Source Files
- docs/advanced/gateway.md — The primary how-to page for gateways, prior discovery results, bootstrap probing, persistence, fan-out, authorization boundaries, listen streams, and stale-advertisement handling.
- docs/.vitepress/nav.ts — Places the Gateway page under the Advanced section of the hand-written guide sidebar, after transport, schema, and wire-schema topics.
- docs/.vitepress/llms.ts — Generates markdown renditions, an LLM index, and a full concatenated guide from the same sidebar order, so the Gateway guide is available in agent-facing docs output.
- docs/_meta/CONVENTIONS.md — Defines the guide-page voice, structure, snippet handling, recap convention, and reader-facing style used by this how-to page.
- docs/.vitepress/theme/index.ts — Wires the v2 documentation theme and top banner around the guide content.
- docs/v1/.vitepress/theme/index.ts — Shows the v1 documentation theme reusing the shared custom CSS while keeping the older site separate.
System-to-Code Mapping
The central public contract on the page is the client connection option that accepts a persisted discovery result. The gateway guide names the value as a discovery result from an earlier probe, shows it serialized as plain JSON, and demonstrates restoring it before a later connection. The page also names the result reader that exposes the recorded advertisement after a bootstrap probe. Those details map the architecture directly to SDK client behavior: one client discovers, storage preserves the advertisement, and many clients adopt it as the same server description.
Sources: docs/advanced/gateway.md
The advertisement is more than a feature flag. The documented output includes time-to-live information, cache scope, supported protocol versions, capabilities, server identity, and completion status. Treat that object as the server’s self-description for the credential that performed the probe. Because it includes capability and version information, it becomes part of the routing and compatibility decision for every worker that reuses it. That is why the guide frames the value as the whole advertisement rather than as an optimization token or connection hint.
Sources: docs/advanced/gateway.md
The Gateway page belongs late in the Advanced section because it combines several earlier concepts. The navigation places it after low-level server usage, custom methods, schema libraries, custom transports, and wire schemas, which signals that the reader should already understand client connections, transports, protocol negotiation, and raw payload boundaries. That placement matters operationally: a gateway is usually not the first MCP integration a team builds. It is the scaling shape adopted after a service has a real server endpoint and multiple clients need consistent discovery behavior.
Sources: docs/.vitepress/nav.ts
Execution Flow
Start with a bootstrap client that connects to the target MCP endpoint using automatic or pinned version negotiation. That connection sends discovery to the server and records the response. The guide’s example then serializes the recorded value, which makes the pattern independent of a particular JavaScript process. You can store the JSON string in a local process cache, a shared configuration store, or a fleet cache such as Redis. The important property is that every later worker reads the same advertisement for the same target endpoint and authorization context.
Sources: docs/advanced/gateway.md
After bootstrap, create ordinary worker clients and pass the parsed discovery result when connecting them to the same server URL. The guide states the observable result clearly: the worker is connected, tool calls work immediately, and the server has not heard from that worker yet. This is the key difference between a normal connection and a prior-backed connection. The normal path establishes the advertised server state by sending discovery; the gateway path establishes that state by adopting a persisted advertisement already obtained by the fleet.
Sources: docs/advanced/gateway.md
Fan-out follows naturally from that contract. Build each replica from the same persisted blob, connect each one with the same prior value, and let them serve application work. The documented proof uses a request-counting tool on the example server. By the time the proof runs, five clients exist: the bootstrap client, an earlier worker, and three replicas. The server has only answered the bootstrap discovery request and the proof call, demonstrating that the four prior-backed connections did not add discovery traffic.
Sources: docs/advanced/gateway.md
Authorization, Caching, and Staleness
Reuse the persisted advertisement only inside one authorization context. The guide warns that the advertisement is what the server returned to the credential that probed, so sharing it across principals can leak a capability view from one caller to another. Key the stored result on the authorization context used for discovery, not only on the URL. In a gateway, that normally means partitioning by tenant, subject, service account, token audience, or another boundary that determines what the target server is allowed to advertise.
Sources: docs/advanced/gateway.md
The advertisement is plain JSON, but it is not timeless configuration. The documented shape includes time-to-live and cache-scope fields, so a production gateway needs a refresh policy. A zero or private cache value should make you conservative, while a positive lifetime can guide how long the fleet keeps the value before probing again. Even when the guide shows process-local reuse, the operational rule is broader: expire or re-probe when your storage policy says the advertisement could be stale, and replace the blob atomically for later workers.
Sources: docs/advanced/gateway.md
Handle stale advertisements as part of the request path. A worker that adopted an old server advertisement may encounter a mismatch when a capability disappears, the server changes identity, or the protocol support window changes. The guide explicitly supports re-probing from an already connected client by sending discovery again and updating the stored result. Use that as the recovery move when a prior-backed worker sees errors that indicate the cached server description no longer matches reality. After refresh, reconnect or rebuild the affected workers from the new value.
Sources: docs/advanced/gateway.md
Listen Streams and Notification Boundaries
A prior-backed connection is enough for immediate client calls, but it does not mean every worker should maintain a long-lived notification stream. The gateway guide separates ordinary worker fan-out from opening a listen stream when a worker needs notifications. That distinction keeps gateway deployments efficient: most short-lived workers can adopt the advertisement and perform calls, while only workers that must receive server-side notifications open the additional stream. Treat listen streams as a capability you allocate deliberately, not as an automatic side effect of every prior-backed connection.
Sources: docs/advanced/gateway.md
The boundary is especially important in worker fleets. If every replica opens a stream, the server observes many long-lived consumers and may broadcast the same notification many times. If the gateway centralizes listening, it can route notifications to application workers according to its own session, tenant, or job mapping. The guide’s structure encourages that separation by teaching zero-round-trip worker connection first and listen streams as an extra step only when notifications are needed. That order helps keep discovery optimization separate from event-delivery design.
Sources: docs/advanced/gateway.md
Documentation Integration
The repository treats this gateway material as a first-class guide page. The navigation source includes it in the Advanced group, and the LLM documentation generator flattens the same sidebar into sections used for markdown renditions, an index, and a full concatenated guide. That means gateway guidance is available both in the human VitePress site and in generated agent-facing documentation. The theme files provide the shared layout and banner behavior around those pages without changing the gateway pattern itself.
Sources: docs/.vitepress/nav.ts, docs/.vitepress/llms.ts, docs/.vitepress/theme/index.ts, docs/v1/.vitepress/theme/index.ts
The docs convention file explains why the source page reads as a how-to: introduce one capability, show a concrete snippet, state the observable result, and end with a recap. For gateway deployments, that style is useful because the observable behavior is the contract you care about. The server should receive the bootstrap discovery request, later workers should connect from the persisted advertisement, and request counts should demonstrate that fan-out did not multiply discovery traffic. The page’s snippets are wired through the documentation system rather than being loose pseudocode.
Sources: docs/_meta/CONVENTIONS.md, docs/advanced/gateway.md
Compact Reference
- Primary guide route: Advanced / Gateway.
- Main pattern: probe once, persist the discovery advertisement, and connect later workers with the prior value.
- Bootstrap behavior: automatic or pinned negotiation sends discovery and records the result for later retrieval.
- Persisted value: plain JSON containing the server advertisement, including supported versions, capabilities, identity, instructions, time-to-live, cache scope, and result status.
- Fan-out behavior: many clients can adopt the same prior result for the same endpoint and authorization context without sending their own discovery requests.
- Authorization rule: never share a persisted discovery result across principals; key storage by authorization context.
- Refresh behavior: an already connected client can discover again and update the recorded result when the advertisement needs renewal.
- Notification rule: open listen streams only for workers that need server notifications.
Next Steps
Read the protocol-version guidance before using prior-backed connection in mixed-era deployments, because the gateway guide marks the prior option as a protocol-revision-specific feature. Then pair this page with the client connection guide for transport setup, the subscriptions or channel-stream guidance for notification delivery, and the sessions, state, and scaling guidance for multi-user deployment boundaries. If you maintain docs or examples, keep the gateway page in the Advanced sidebar and preserve the snippet-driven how-to shape expected by the documentation conventions.
Sources: docs/advanced/gateway.md, docs/.vitepress/nav.ts, docs/_meta/CONVENTIONS.md