What is ModelPreferences?
ModelPreferences is a hint structure that servers attach to sampling requests (CreateMessageRequest) to express what kind of model they would like the client to use — without binding the request to a specific provider or model identifier. It sits between the server and the client's sampling layer: when a server issues a sampling/createMessage call, it passes ModelPreferences alongside the message array, and the client uses the hints to resolve a concrete model from whatever providers it has configured. This decoupling is intentional — the server describes intent, the client retains full authority over which model is actually invoked.
The API surface has two orthogonal axes. The hints[] array is an ordered list of ModelHint objects (each carrying a name substring), giving the client a preference-ordered list of model name fragments to match against. The three numeric fields — costPriority, speedPriority, and intelligencePriority — each range from 0.0 to 1.0 and allow the server to express trade-off weights when no hint matches or when the client wants to score candidates. All four fields are optional, so a server can provide only hints, only priorities, both, or neither (in which case the client applies its own defaults).
These fields do not compose into a single score by a specified formula — the MCP specification deliberately leaves the resolution algorithm to the client. Servers should therefore treat ModelPreferences as advisory rather than authoritative. The type was introduced at protocol version 2024-11-05 alongside the sampling capability and has remained stable; there are no deprecated fields or known breaking changes in later draft revisions.
When to use
Inside CreateMessageRequest to bias model selection.
When NOT to use
When you don't care — clients pick a sensible default.
Notes
hints[] is ordered, not weighted
The hints array is an explicit preference ordering, not a scored list. Clients should try the first matching hint before falling back to later entries. If you pass both hints and priority fields, well-behaved clients use the hints for name matching first and fall back to priorities only when no hint yields a usable model — but the spec does not mandate this, so do not assume it universally.
Priority fields are independent, not summed
costPriority, speedPriority, and intelligencePriority are independent signals, not components of a single objective function. A value of 1.0 on intelligencePriority does not override costPriority=0.9; the client decides how to trade them off. In practice, setting two or three fields near 1.0 simultaneously gives the client little useful signal — keep at most one or two fields high and leave the rest at 0.0 or omit them.
No validation guarantee on 0–1 range
The specification states the numeric fields should be in [0, 1], but most SDK implementations do not enforce this with a hard schema error — they may clamp, ignore, or forward the value as-is. Always clamp your own values before sending rather than relying on the transport layer to reject out-of-range inputs.
Cross-provider hint mapping is optional
The spec explicitly says clients may map hint substrings across providers (e.g., the substring 'claude' might resolve to a Claude Haiku on one client and a Claude Sonnet on another). Do not embed version strings or full model IDs in hints if you expect portability — short capability-descriptive substrings like 'sonnet', 'haiku', or 'gpt-4o' are more durable than versioned identifiers that expire.
Omitting ModelPreferences is valid and common
The modelPreferences field on CreateMessageRequest is optional. Many servers omit it entirely and rely on the client's configured default model. Over-specifying preferences — particularly hardcoding a model hint that only one client supports — reduces portability and can cause silent fallback to an unintended model on clients that cannot match the hint.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| hints | ModelHint[]? | no | Ordered list of model name hints. |
| costPriority | number? | no | 0–1, higher = prefer cheaper models. |
| speedPriority | number? | no | 0–1, higher = prefer faster models. |
| intelligencePriority | number? | no | 0–1, higher = prefer smarter models. |
Examples
Prefer a Claude Sonnet-class model
{
"hints": [{ "name": "claude-3-sonnet" }, { "name": "claude" }],
"intelligencePriority": 0.8,
"costPriority": 0.2
}
Common mistakes
❌ Treating hints as a hard requirement
✅ Hints are advisory — clients may substitute equivalent models.