Why is a server not allowed to see the full conversation history when it makes a sampling request?
Quick Answer
MCP's includeContext field on a sampling request lets a server ask for "none", "thisServer" (only context this specific server itself has contributed), or "allServers" (context from every connected server) — but the decision of how much context to actually include is made and enforced by the client, not simply handed over based on the server's request. This exists because the conversation may contain sensitive information from other servers, other tools, or the user's own messages that has nothing to do with the requesting server's task, and a server shouldn't be able to unilaterally read the entire conversation just because it wants to generate one piece of text. Limiting context by default (and requiring explicit justification/approval for broader access) reduces the blast radius if a server turns out to be compromised or poorly behaved — it can, at most, see what it's actually entitled to for the sampling task at hand.
Detailed Answer
Sampling is one of the places MCP's security model gets tested most directly. A server is asking to trigger LLM generation, and how much conversation context it gets to see for that generation is a real trust decision, not a formality.
The includeContext options
{"method": "sampling/createMessage", "params": {
"messages": [...],
"includeContext": "thisServer"
}}
| Value | Meaning |
|---|---|
"none" | The sampling request only sees the messages explicitly included in the request itself |
"thisServer" | Additionally include context this specific server has itself contributed (its own prior tool results, resources) |
"allServers" | Additionally include context from every connected server, not just this one |
Why the client enforces this, not the server
A server requesting "allServers" doesn't mean the client has to grant it. The client is the trust boundary. It decides, per its own policy and potentially with user confirmation, how much of the broader conversation a given server is actually entitled to see for a sampling call. This matters because a session might have five connected servers — a filesystem server, a banking API server, a personal notes server. It would be a serious privacy leak if any one of them could casually request "give me everything" and receive banking details or personal notes it had nothing to do with, just by asking.
The threat this defends against
Imagine a compromised or intentionally malicious third-party MCP server. If sampling requests automatically included the full conversation with no gating, that server could exfiltrate sensitive information from other servers' interactions. It would just issue a sampling request and read whatever context came back, even though its actual declared purpose has nothing to do with that other data. Scoping context by default, and treating broader access as something the client actively grants rather than something a server can simply take, is a direct mitigation for that scenario.
Practical takeaway
When designing a server that uses sampling, request the narrowest includeContext value that actually satisfies your use case. Requesting "allServers" when "thisServer" (or even "none") would do just as well is unnecessary. It's also a signal, to any host that inspects such requests, that the server may be over-reaching.