Almost everything in the Model Context Protocol flows one way: the host asks, the server answers. The host lists tools, reads resources, calls a function. Sampling reverses the arrow. Here the server asks the host to run a language-model completion and hand back the result — so the server gets to think without ever holding a model, an API key, or a token budget. That inversion is useful and dangerous in equal measure, and the whole design answers the second half: how do you let a server borrow your model without letting it drive your model?

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.

Advertisement

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.

MCP sampling — server requests LLM completion via host + trust boundarylet servers ask hosts to reasonMCP serverwants completionsampling/createMessagerequestHost arbitrationuser consent + policyModel callhost executesModel preferencescost / qualityInclude contexthistory + resourcesSystem prompt hintnot requiredResponseback to serverTrust boundaryserver can't force callAuditwho asked for whatOps — cost + rate + user visibilitypreferincludehintreplygateloglogoperateoperate
MCP sampling flow — server asks, host arbitrates, model responds.

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.

Advertisement

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.

Cost attribution — the host pays for tokens the server asked for

Sampling is the one place in MCP where a remote party spends your money. Every sampled completion runs on the host’s account, against the host’s rate limits, at the host’s per-token price — and the prompt was written by software the host did not author. A server requesting a large context window and a generous token cap on every tool call can quietly multiply a session’s cost with no user-visible cause.

Which means metering cannot be a single global counter. Attribute tokens to the requesting server, keep prompt and completion counts separate, and surface the total somewhere the user actually looks. The useful controls then follow: per-server token quotas over a window, a host-applied ceiling on maxTokens, cheaper default routing for servers that did not justify an expensive model, and an alert when one connection dominates spend. Cost visibility is also the earliest signal that a server is misbehaving.

The trust problem — a server that can drive your model

Strip away the mechanics and sampling grants a third-party process two capabilities: it can put arbitrary text in front of your model, and it can read what comes back. The second is the sharper one.

The exfiltration path is direct. A server requests broad context inclusion, sends a message asking the model to restate what it has been working on, and receives the answer as an ordinary protocol response. No exploit is involved; that is the feature working as designed. The injection path runs the other way: server-supplied messages are untrusted input, and if the host folds a sampled completion back into its own conversation, text the server authored has reached the main agent loop. Treat sampling context as the sensitive grant it is: default to the narrowest scope, require opt-in for anything wider, keep server-authored text visibly fenced from user-authored text, and log every sampling call with its requester, context scope, and token cost, so ‘what did that server ask my model?’ has an answer afterwards.

When to reach for sampling

Sampling earns its complexity when the reasoning genuinely belongs to the server: a step that needs the server’s private data or domain logic, happens mid-tool-call rather than between calls, and would be worse if the host’s main loop had to do it blind. It is the wrong tool when the host could simply be handed the raw material and reason over it itself, and wrong for a server with its own business need for a model, which should carry its own key and bill. The question is not ‘can this server call a model?’ but ‘should this reasoning step happen where the user cannot watch it?’

Sampling is MCP’s inverted call: the server asks, the host runs the completion, the server gets the result — so a server can reason without ever holding a model or an API key. Every parameter it sends is a request, not an instruction: preferences are hints, and the host picks the model, may rewrite the prompt or clamp the token cap, and may refuse. That asymmetry is the safety design, and it only works if the host does its half — human review before the call and before the result goes back, depth and budget caps against unbounded recursion, per-server token metering because the host pays, and a narrow default for included context. Remember what the grant is: a third-party process that can put text in front of your model and read what comes back.