What is CreateMessageRequest?
CreateMessageRequest is the wire type a server emits when it invokes the sampling/createMessage method — it is the server's way of asking the connected MCP client to run an LLM completion on its behalf. Rather than bundling its own model credentials, the server delegates inference entirely to the client, which retains full control over which model is actually used, how requests are rate-limited, and whether a human-in-the-loop approval step is required before the completion proceeds. The request carries a required messages array of SamplingMessage objects (each a role/content pair), a required maxTokens cap, and an optional modelPreferences object that lets the server express priorities — cost, speed, or intelligence — along with concrete model hints such as preferred provider or model family. The client treats hints as advisory: it may honour them, downgrade to a cheaper model, or ignore them entirely. Optional fields like systemPrompt, temperature, stopSequences, and includeContext (controlling whether conversation history from this server or all connected servers is injected) give servers fine-grained influence without forcing them to own model-selection logic. Because human approval is a first-class concern in sampling, clients should surface the pending request to the user before forwarding it to the underlying LLM. This design keeps sensitive prompt content visible to the operator and prevents servers from using the client as a silent inference proxy. The includeContext field in particular deserves scrutiny: "allServers" broadens the context injection surface considerably and should be treated as a trust-escalation signal worth confirming with the user.
When to use
When the server needs analysis, summarisation, or reasoning from the LLM.
When NOT to use
When deterministic logic suffices — don't pay model costs for nothing.
Notes
maxTokens is a hard server-side cap
The maxTokens field is required and represents the server's upper bound on output tokens — it is not a suggestion. Clients should pass it directly to the underlying model API and must not silently increase it. Exceeding the cap without the server's knowledge can produce responses the server's downstream logic is not prepared to parse or truncate.
modelPreferences hints are advisory only
Model hints inside modelPreferences (such as a preferred provider name or model family string) give the client guidance but no binding authority. A client backed by a single provider will simply use the closest available model. Servers must not assume a specific model was used; if the actual model matters for reasoning about the response, the server should inspect the model field in the CreateMessageResult that the client returns.
includeContext expands the trust surface
Setting includeContext to "allServers" instructs the client to inject conversation history from every connected server, not just the one making the request. This is a significant context-leakage vector in multi-server setups: one server can indirectly read artefacts produced by another. Production clients should log or surface this field value during the human approval step so operators can assess the blast radius before confirming.
Human approval is required, not optional
The MCP specification treats client-side human approval as a mandatory gate for sampling requests, not a recommended best practice. Clients that auto-approve every CreateMessageRequest silently violate the spec's trust model and can expose users to prompt-injection attacks where a malicious tool response crafts a sampling request designed to exfiltrate data. Approval UX should show the full messages array and any systemPrompt before proceeding.
stopSequences interact with maxTokens unexpectedly
When both stopSequences and maxTokens are present, generation halts at whichever limit is hit first. Servers that rely on a stop sequence to delimit structured output (e.g., JSON fences) should set a generous maxTokens so the stop sequence is actually reached rather than the token cap. If the result's stopReason is "maxTokens" instead of "stopSequence", the structured payload is likely truncated and should be treated as malformed.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| method | 'sampling/createMessage' | yes | Method identifier. |
| params.messages | SamplingMessage[] | yes | Conversation history to complete. |
| params.modelPreferences | ModelPreferences? | no | Hints, costPriority, speedPriority, intelligencePriority. |
| params.systemPrompt | string? | no | System prompt for the completion. |
| params.includeContext | 'none' | 'thisServer' | 'allServers'? | no | Whether to include MCP context. |
| params.maxTokens | number | yes | Maximum tokens in response. |
| params.temperature | number? | no | Sampling temperature. |
| params.stopSequences | string[]? | no | Sequences that halt generation. |
Examples
Asking the client to summarise
{
"method": "sampling/createMessage",
"params": {
"messages": [{ "role": "user", "content": { "type": "text", "text": "Summarise..." } }],
"maxTokens": 200,
"modelPreferences": { "intelligencePriority": 0.8 }
}
}
Common mistakes
❌ Skipping maxTokens
✅ maxTokens is required — clients enforce it to bound cost.