Sampling
specification/2025-11-25/client/sampling
History
specification/2025-11-25/client/sampling New page · 631 lines, new page
# Sampling ## User Interaction Model ## Tools in Sampling ## Capabilities ## Protocol Messages ### Creating Messages ### Sampling with Tools ### Multi-turn Tool Loop ## Message Content Constraints ### Tool Result Messages ### Tool Use and Result Balance ## Cross-API Compatibility ### Message Roles ### Tool Choice Modes ### Parallel Tool Use ## Message Flow ## Data Types ### Messages #### Text Content #### Image Content #### Audio Content ### Model Preferences #### Capability Priorities #### Model Hints ## Error Handling ## Security Considerations
A whole new page. There's nothing to diff it against, so here is what it says.
# Sampling
<div id="enable-section-numbers" />
The Model Context Protocol (MCP) provides a standardized way for servers to request LLM
sampling ("completions" or "generations") from language models via clients. This flow
allows clients to maintain control over model access, selection, and permissions while
enabling servers to leverage AI capabilities—with no server API keys necessary.
Servers can request text, audio, or image-based interactions and optionally include
context from MCP servers in their prompts.
## User Interaction Model
Sampling in MCP allows servers to implement agentic behaviors, by enabling LLM calls to
occur *nested* inside other MCP server features.
Implementations are free to expose sampling through any interface pattern that suits
their needs—the protocol itself does not mandate any specific user interaction
model.
<Warning>
For trust & safety and security, there **SHOULD** always
be a human in the loop with the ability to deny sampling requests.
Applications **SHOULD**:
* Provide UI that makes it easy and intuitive to review sampling requests
* Allow users to view and edit prompts before sending
* Present generated responses for review before delivery
</Warning>
## Tools in Sampling
Servers can request that the client's LLM use tools during sampling by providing a `tools` array and optional `toolChoice` configuration in their sampling requests. This enables servers to implement agentic behaviors where the LLM can call tools, receive results, and continue the conversation - all within a single sampling request flow.
Clients **MUST** declare support for tool use via the `sampling.tools` capability to receive tool-enabled sampling requests. Servers **MUST NOT** send tool-enabled sampling requests to Clients that have not declared support for tool use via the `sampling.tools` capability.
## Capabilities
Clients that support sampling **MUST** declare the `sampling` capability during
[initialization](/specification/2025-11-25/basic/lifecycle#initialization):
**Basic sampling:**
```json theme={null}
{
"capabilities": {
"sampling": {}
}
}
```
**With tool use support:**
```json theme={null}
{
"capabilities": {
"sampling": {
"tools": {}
}
}
}
```
**With context inclusion support (soft-deprecated):**
```json theme={null}
{
"capabilities": {
"sampling": {
"context": {}
}
}
}
```
<Note>
The `includeContext` parameter values `"thisServer"` and `"allServers"` are
soft-deprecated. Servers **SHOULD** avoid using these values (e.g. can just
omit `includeContext` since it defaults to `"none"`), and **SHOULD NOT** use
them unless the client declares `sampling.context` capability. These values
may be removed in future spec releases.
</Note>
## Protocol Messages
### Creating Messages
To request a language model generation, servers send a `sampling/createMessage` request:
**Request:**
```json theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"method": "sampling/createMessage",
"params": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "What is the capital of France?"
}
}
],
"modelPreferences": {
"hints": [
{
"name": "claude-3-sonnet"
}
],
"intelligencePriority": 0.8,
"speedPriority": 0.5
},
"systemPrompt": "You are a helpful assistant.",
"maxTokens": 100
}
}
```
**Response:**
```json theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"role": "assistant",
"content": {
"type": "text",
"text": "The capital of France is Paris."
},
"model": "claude-3-sonnet-20240307",
"stopReason": "endTurn"
}
}
```
### Sampling with Tools
The following diagram illustrates the complete flow of sampling with tools, including the multi-turn tool loop:
```mermaid theme={null}
sequenceDiagram
participant Server
participant Client
participant User
participant LLM
Note over Server,Client: Initial request with tools
Server->>Client: sampling/createMessage<br/>(messages + tools)
Note over Client,User: Human-in-the-loop review
Client->>User: Present request for approval
User-->>Client: Approve/modify
Client->>LLM: Forward request with tools
LLM-->>Client: Response with tool_use<br/>(stopReason: "toolUse")
Client->>User: Present tool calls for review
User-->>Client: Approve tool calls
Client-->>Server: Return tool_use response
Note over Server: Execute tool(s)
Server->>Server: Run get_weather("Paris")<br/>Run get_weather("London")
Note over Server,Client: Continue with tool results
Server->>Client: sampling/createMessage<br/>(history + tool_results + tools)
Client->>User: Present continuation
User-->>Client: Approve
Client->>LLM: Forward with tool results
LLM-->>Client: Final text response<br/>(stopReason: "endTurn")
Client->>User: Present response
User-->>Client: Approve
Client-->>Server: Return final response
Note over Server: Server processes result<br/>(may continue conversation...)
```
To request LLM generation with tool use capabilities, servers include `tools` and optionally `toolChoice` in the request:
**Request (Server -> Client):**
```json theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"method": "sampling/createMessage",
"params": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "What's the weather like in Paris and London?"
}
}
],
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name"
}
},
"required": ["city"]
}
}
],
"toolChoice": {
"mode": "auto"
},
"maxTokens": 1000
}
}
```
**Response (Client -> Server):**
```json theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "call_abc123",
"name": "get_weather",
"input": {
"city": "Paris"
}
},
{
"type": "tool_use",
"id": "call_def456",
"name": "get_weather",
"input": {
"city": "London"
}
}
],
"model": "claude-3-sonnet-20240307",
"stopReason": "toolUse"
}
}
```
### Multi-turn Tool Loop
After receiving tool use requests from the LLM, the server typically:
1. Executes the requested tool uses.
2. Sends a new sampling request with the tool results appended
3. Receives the LLM's response (which might contain new tool uses)
4. Repeats as many times as needed (server might cap the maximum number of iterations, and e.g. pass `toolChoice: {mode: "none"}` on the last iteration to force a final result)
**Follow-up request (Server -> Client) with tool results:**
```json theme={null}
{
"jsonrpc": "2.0",
"id": 2,
"method": "sampling/createMessage",
"params": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "What's the weather like in Paris and London?"
}
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "call_abc123",
"name": "get_weather",
"input": { "city": "Paris" }
},
{
"type": "tool_use",
"id": "call_def456",
"name": "get_weather",
"input": { "city": "London" }
}
]
Cut at 300 lines.