In an MCP host, why is there one client per server instead of one shared client?
answer
- one connector, one blast radius
- credentials are per server, not per host
- trust is assigned to a pairing
- only the host sees across servers
- not about giving servers memory
basics
~20 sOne client per server keeps each pairing an isolated boundary with its own transport, credentials and trust decision. A crashing, slow or hostile server then degrades only its own connector, and the host stays the single place that sees across servers.
solid answer
~50 sThe one-to-one rule exists so that a server is a self-contained blast radius. Each client owns one transport — a stdio subprocess it spawned, or POSTs to one Streamable HTTP endpoint — so a hung subprocess or a 5xx endpoint fails one connector, not the whole application. Authorization is per pairing too: a remote server is its own OAuth 2.1 resource server with its own audience-bound token, and revision 2026-07-28 forbids passing that token through to anything else. Trust is per pairing: annotations and `io.modelcontextprotocol/serverInfo` from one server say nothing about another. Because only the host sits above all the clients, only the host can merge capabilities for the model, apply per-server policy, and route a chosen call back to the connector it came from. A multiplexed client would collapse all of those boundaries into one.
go deeper
Know the shape: one client per server, and the host is the only place that sees all of them. Be able to say a failing server affects its own connector rather than the whole application.
Explain the three boundaries the rule creates — transport and failure, credentials, and trust — and be ready to say that under revision 2026-07-28 it is not about session state, because sessions were removed.
Show operational judgment: how you contain a hung stdio subprocess or a failing remote endpoint, why a token minted for one server must never reach another, and how per-server policy is attached in a real host.
Own the tradeoff between many direct servers and one gateway fronting several systems: the gateway collapses the host's isolation unit to one, so it must take over the containment and authorization the topology was providing for free.
## The rule An MCP host maintains one client per server it connects to. There is no client that fans out to several servers and no path from one server to another. Everything cross-server happens in the host, above the client layer. ## Isolation of transport and failure Each client owns exactly one transport. On stdio that is a subprocess the client spawned, exchanging newline-delimited JSON-RPC on stdin and stdout. On Streamable HTTP it is a single POST-only MCP endpoint. Failure therefore has a natural containment unit: a server that hangs, floods stderr, crashes, or returns errors takes down its own connector and nothing else. The host can restart that subprocess, back off from that endpoint, or drop that server's tools out of the model's list while every other server keeps working. If one client multiplexed several servers, one badly behaved integration would sit in the critical path of all of them. ## Isolation of authorization For remote servers, authorization is defined per server. Under revision 2026-07-28 the MCP server acts as an OAuth 2.1 resource server: it publishes protected-resource metadata at `/.well-known/oauth-protected-resource` per RFC 9728, tokens are audience-bound to that server, PKCE is mandatory, and the spec prohibits token passthrough — a token minted for one server must never be forwarded to another. One client per server maps cleanly onto that: each connector holds the credential for its own server and nothing else. A shared client would be holding a bag of tokens for different audiences, which is exactly the confused-deputy shape the authorization rules are written to prevent. ## Isolation of trust Trust in MCP is per server and the host is the participant that assigns it. Tool descriptions and `ToolAnnotations` — `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint` — are hints, and clients must treat them as untrusted unless the server itself is trusted. `io.modelcontextprotocol/serverInfo` is self-reported and untrusted as well. Because a client is bound to one server, the host can attach a trust level, a policy, an approval history and a credential to that specific connector rather than to an anonymous pool of upstreams. ## What only the host can do Sitting above every client, the host is the only participant with a cross-server view. It merges the tool, resource and prompt lists that the model is shown; it decides which servers are enabled for a given task; it applies per-server policy and any user approval; and when the model chooses a call, it routes that call back to the client whose server actually offered it. Servers see none of this. A server cannot see the conversation, cannot see the user's screen, and cannot see another server. That opacity is a design feature — it is what makes it safe to enable a third-party server next to an internal one — and it depends on the host, not the client layer, being the meeting point. ## What the rule is not about A common wrong answer is "one client per server so each server can keep session state". Revision 2026-07-28 removed protocol sessions entirely: MCP is stateless, every request is self-contained and carries its own protocol version and capabilities in `params._meta`, and an open connection — including a running stdio process — is not a conversation or a session. So the one-to-one rule is about isolation and lifecycle, not about giving a server somewhere to remember things. Anything that must survive across calls has to be expressed explicitly in what a request carries. Another wrong answer is that the rule limits how the host presents servers to the model. It does not. The host may show the model a single merged list drawn from several servers; the rule constrains the wire topology beneath that, not the UI or the prompt. ## How this shows up in practice A host that wires ten servers should be able to answer, per server: which process or endpoint is it, which credential does it hold, what happens to the rest of the application when it fails, and who approved it. If those answers cannot be given per server, the boundary has been blurred — usually by a gateway that fronts several upstreams behind one MCP endpoint. That is a legitimate design, but note what it costs: to the host it is now one server, one credential and one trust decision, and the isolation moved inside the gateway, which must then enforce it.
- Doesn't the one-to-one rule exist so each server can keep session state on its connection?No — that reading is out of date. Revision 2026-07-28 removed protocol sessions and states that every request is self-contained and that an open connection, including a stdio process, is not a conversation. The one-to-one rule buys isolation of transport, credentials and trust, plus a clean lifecycle unit the host can restart or disable. It buys no memory.
- A gateway fronts six internal systems behind one MCP endpoint. What does the host lose?To the host that is one server: one client, one credential, one trust decision, and one failure unit covering all six systems. Per-system isolation has not disappeared, it has moved inside the gateway, which must now enforce authorization and containment itself. That is a fine design when the gateway is yours, and a poor one when the six systems have different trust levels.
- If the host merges tools from several servers into one list for the model, is the isolation still real?Yes, at the wire level: the merged list is a host-side presentation, and each call still goes out over the client bound to the server that offered it. What the merge does introduce is the host's responsibility to keep provenance — which server offered which entry — so the call is routed correctly and per-server policy still applies.
saying these in an interview costs you the question
- Saying one client can multiplex several servers for efficiency
- Claiming the rule exists so servers can keep session state
- Reusing one server's token when calling another server
- Assuming a trusted server's annotations vouch for other servers
- Thinking the rule forbids the host from merging tool lists