The inverted call — server asks, host arbitrates, model answers
The normal MCP shape matches every RPC system you have used: the client asks, the server answers. Sampling flips the direction on a single method. The server issues sampling/createMessage to the client, carrying messages it would like completed. The host receives that request, decides whether to honour it, picks a model, runs the completion with its own credentials, and returns the generated message.
Three parties matter. The server wants reasoning. The host owns the model, the money, and the user’s trust. The client is the host’s per-server connection that carries the message. Sampling is a client-side capability, declared during the initialize handshake, so a server that needs it must first check whether the connection offers it at all.
One boundary before we go on, because MCP has two inversions and they get mixed up: sampling asks the model, elicitation asks the person.
Why it exists — agency without an API key
Consider a server that indexes a document store. Without sampling it can only return raw chunks; summarising and ranking happen back in the host’s main loop, so the server’s domain knowledge about which chunks matter never gets applied. With sampling, the server can ask for a completion mid-tool-call, fold the answer into its own logic, and return a far better result.
The alternative is for the server to ship its own model access — bundle an SDK, demand an API key, bill someone separately. That is a miserable deal for everyone. The user manages two model relationships. The operator hands a third-party binary a live credential. The server author owns a rate-limit and pricing problem nobody wanted. Sampling collapses all of it: one model relationship, held by the host, lent out under supervision. A server becomes agentic while staying a plain, credential-free process.
The request shape — messages, system prompt, context, token cap
A sampling request stays deliberately close to a bare completion call, because the host must translate it to whatever provider it uses. The core is messages: an ordered conversation of user and assistant turns with text or image content. Alongside it the server may supply a systemPrompt describing the job, and maxTokens as an upper bound on the response.
The interesting field is includeContext, which asks the host to attach context the server itself cannot see — nothing, the context belonging to the requesting server, or context spanning all connected servers. Note the asymmetry: the server is asking that material it has no access to be injected into a prompt whose output it will receive. Every one of these fields is a request, not a guarantee, and a server written as though they were guarantees will break the first time a host tightens its policy.
Model preferences are hints, not demands
Servers often do have an opinion about the model. A quick classification step wants something cheap and fast; a careful synthesis wants something strong. MCP lets the server express that through a modelPreferences block carrying two kinds of signal.
The first is hints — loose, substring-style name suggestions, a family or tier the server would prefer. These are explicitly advisory: a host running a different provider is expected to map them onto its own catalogue rather than fail. The second is a set of normalised priorities weighing cost, speed, and intelligence against one another. Priorities travel better than names, because they describe the shape of the trade-off rather than a product that may not exist on the other end of the connection.
The diagram below shows the whole loop in one frame.
Host arbitration — select, modify, or refuse
Arbitration is the load-bearing word. When a sampling request arrives the host is not a proxy; it is a gatekeeper with three legitimate answers. It may select a model, consulting the preferences and then applying its own routing, availability, and contract constraints. It may modify the request: swap in its own system prompt, clamp maxTokens to a policy ceiling, narrow the requested context, adjust sampling parameters. And it may refuse, returning an error rather than a completion.
The response reports which model actually ran and why generation stopped — the honest admission at the heart of the design, since if preferences were binding there would be nothing to report. Servers should read it, and should be written so a smaller model than they asked for degrades output quality rather than breaking parsing. A server whose only path through a feature runs via sampling should offer a reduced mode or say plainly that the capability is required.
The human in the loop, on both sides of the call
The expectation baked into sampling is that a human sees it — not as a vague principle but as two checkpoints. Before the call, the user should see what the server is asking the model to do and be able to approve, edit, or deny it. After the call, the user should see what the model produced and be able to approve, edit, or withhold it before it goes back to the server.
The second checkpoint is the one implementers skip and the more important of the two. Pre-call review protects your token budget; post-call review is the only thing standing between a server and whatever your model just wrote using your context. Hosts soften the friction with scoped policy — auto-approve short completions, prompt for anything larger or broader — but the policy is the host’s to write and the user’s to change. Adoption has lagged precisely because this consent surface is real work, so servers must handle its absence.
Recursion — a completion that triggers more work
Here is the failure mode that makes sampling different from every other MCP method. The host calls a tool. The server, mid-execution, requests a completion. The host runs it and returns generated text. The server acts on that text — and if it suggests further work, the server may call another tool or request another completion, or the host’s agent loop may take the tool result and produce another turn. The cycle extends with no human issuing a new instruction.
Nothing in the protocol stops this, because the protocol does not know it is happening; each individual message is well-formed. The controls live in the host, and they are unglamorous: a maximum sampling depth per originating user action, a turn-wide token budget that sampling draws down rather than sits outside, a wall-clock timeout, and a loop detector for a server that keeps re-requesting near-identical completions. An unbounded sampling chain is an availability and billing incident waiting for a trigger.