MCP sampling, the feature that lets a server ask the client to run a language-model generation, is deprecated in the current Model Context Protocol specification, revision 2026-07-28: new implementations should not adopt it, and existing ones should migrate to calling LLM provider APIs directly (MCP Sampling).

Applies to: Model Context Protocol specification revision 2026-07-28 (the current revision) and its changelog. Last checked: October 30, 2026.

On this page

What changed in MCP sampling

The versioning page names 2026-07-28 as the current protocol version. Its changelog deprecates three features in one step, Roots, Sampling and Logging (SEP-2577), and says they “remain fully functional during the deprecation window but new implementations should not add support for them”.

The deprecated features registry lists sampling like this:

Field Registry entry for Sampling
Deprecation SEP SEP-2577
Deprecated in 2026-07-28
Migration path Integrate directly with LLM provider APIs
Earliest removal First revision released on or after 2027-07-28

The earliest removal is not a fixed removal date. The registry says it “marks when a feature becomes eligible for removal; the actual removal is a Core Maintainer decision taken during release preparation and may happen later” (Deprecated Features). The feature lifecycle policy sets a minimum deprecation window of twelve months and adds that features “may remain Deprecated, without removal, for much longer than the minimum deprecation window”.

Two related items are on the same list. The includeContext values "thisServer" and "allServers" are deprecated and “will be removed no later than the Sampling feature itself”; the registry’s migration path is to omit the field or use "none" (Deprecated Features). Roots and Logging are deprecated by the same SEP (changelog).

What SDKs have to do

The lifecycle policy puts obligations on Tier 1 SDKs once a revision that deprecates a feature is released as Current. They must mark the matching API surface deprecated in their next release, using the language’s native mechanism, and should emit a runtime warning when the deprecated feature is used (Feature Lifecycle). Removal from the specification “does not oblige an SDK to drop the feature from releases”; that follows the SDK’s own revision-support policy (same page).

What sampling does

The sampling specification describes it as a way for servers to request “completions” or “generations” from language models via clients, so that clients “maintain control over model access, selection, and permissions” and servers need no API keys of their own. Requests can contain text, image or audio content.

A request can also carry model preferences: hints with model names, and costPriority, speedPriority and intelligencePriority values from 0 to 1. The specification says “hints are advisory—clients make final model selection”. The client MUST respect maxTokens, MAY modify or ignore systemPrompt, includeContext, temperature, stopSequences and metadata, and SHOULD respect model preference hints (MCP Sampling).

How a sampling request travels in 2026-07-28

Revision 2026-07-28 replaced server-initiated requests such as sampling/createMessage with the Multi Round-Trip Requests (MRTR) pattern (changelog):

  1. The client sends tools/call, resources/read or prompts/get.
  2. The server answers with an InputRequiredResult whose inputRequests map holds a sampling/createMessage request.
  3. The client gathers the result and retries the original request with inputResponses, echoing any requestState exactly.
  4. The server completes the operation, or returns another InputRequiredResult.

The MRTR page requires a different JSON-RPC id for the retry, forbids clients from inspecting or modifying requestState, and requires servers to treat requestState as attacker-controlled input and protect its integrity (for example with HMAC or AEAD) when it affects authorization, resource access or business logic (MRTR).

This is the sampling request from the specification, delivered inside InputRequiredResult.inputRequests (MCP Sampling):

{
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "What is the capital of France?"
        }
      }
    ],
    "modelPreferences": {
      "hints": [
        {
          "name": "claude-3-sonnet"
        }
      ],
      "costPriority": 0.3,
      "intelligencePriority": 0.8,
      "speedPriority": 0.5
    },
    "temperature": 0.1,
    "systemPrompt": "You are a helpful assistant.",
    "includeContext": "thisServer",
    "maxTokens": 100
  }
}

The example still uses "includeContext": "thisServer", one of the deprecated values. In the inputRequests map, each request sits under a server-assigned key that must be unique within the request, and the client’s result comes back under the same key in inputResponses (MRTR).

Capability declaration

There is no initialize handshake in 2026-07-28; every request carries its client capabilities in _meta (changelog). A client that supports sampling must declare it on each request (MCP Sampling):

{
  "_meta": {
    "io.modelcontextprotocol/clientCapabilities": {
      "sampling": {}
    }
  }
}

Tool use during sampling needs the nested tools capability:

{
  "_meta": {
    "io.modelcontextprotocol/clientCapabilities": {
      "sampling": {
        "tools": {}
      }
    }
  }
}

Servers MUST NOT send tool-enabled sampling requests to clients that have not declared sampling.tools, and SHOULD NOT use the deprecated includeContext values unless the client declares sampling.context (MCP Sampling).

Tool loops inside sampling

A server can give the model a tools array and an optional toolChoice. The tool definitions are scoped to the sampling request and “don’t need to correspond to registered tools”. toolChoice takes {mode: "auto"} (the default), {mode: "required"} or {mode: "none"} (MCP Sampling).

The specification sets two message rules:

  • A user message that contains tool results must contain only tool results, with no text, image or audio mixed in.
  • Every assistant message with ToolUseContent blocks must be followed by a user message of ToolResultContent blocks, one per tool use with a matching toolUseId, before any other message.

It also says both parties SHOULD implement iteration limits for tool loops, and that a server may pass toolChoice: {mode: "none"} on the last iteration to force a final result (MCP Sampling).

Migrating an existing server

The documented migration path is one line: “Integrate directly with LLM provider APIs” (Deprecated Features). The sampling page’s own warning says existing implementations SHOULD migrate to that (MCP Sampling).

What the server takes over when it stops using sampling follows from what the sampling page assigns to the client today:

Handled by the client under sampling Source
Model access, so the server needs no API key MCP Sampling
Final model selection from hints and priorities MCP Sampling
Human review: “there SHOULD always be a human in the loop with the ability to deny sampling requests” MCP Sampling
User approval controls and rate limiting (security considerations 1 and 4) MCP Sampling

Remote servers also have transport and authorization choices that are separate from the model change; see MCP stdio vs Streamable HTTP and MCP OAuth authorization.