Skip to main content

mcp_kit/types/
sampling.rs

1use serde::{Deserialize, Serialize};
2
3use super::content::Content;
4
5/// A message param used in sampling requests
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct MessageParam {
8    pub role: SamplingRole,
9    pub content: Content,
10}
11
12impl MessageParam {
13    /// Create a new message with the given role and content.
14    pub fn new(role: SamplingRole, content: Content) -> Self {
15        Self { role, content }
16    }
17
18    /// Create a user message with text content.
19    pub fn user_text(text: impl Into<String>) -> Self {
20        Self {
21            role: SamplingRole::User,
22            content: Content::text(text),
23        }
24    }
25
26    /// Create an assistant message with text content.
27    pub fn assistant_text(text: impl Into<String>) -> Self {
28        Self {
29            role: SamplingRole::Assistant,
30            content: Content::text(text),
31        }
32    }
33}
34
35/// Role in a sampling conversation
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
37#[serde(rename_all = "lowercase")]
38pub enum SamplingRole {
39    User,
40    Assistant,
41}
42
43/// A sampling message (alias for clarity)
44pub type SamplingMessage = MessageParam;
45
46/// Model hints for sampling requests
47#[derive(Debug, Clone, Default, Serialize, Deserialize)]
48pub struct ModelHint {
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub name: Option<String>,
51}
52
53/// Model preferences for sampling
54#[derive(Debug, Clone, Default, Serialize, Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct ModelPreferences {
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub hints: Option<Vec<ModelHint>>,
59    /// Cost priority [0.0, 1.0]
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub cost_priority: Option<f64>,
62    /// Speed priority [0.0, 1.0]
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub speed_priority: Option<f64>,
65    /// Intelligence priority [0.0, 1.0]
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub intelligence_priority: Option<f64>,
68}
69
70/// Sampling stop reason
71#[derive(Debug, Clone, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub enum StopReason {
74    EndTurn,
75    MaxTokens,
76    StopSequence,
77    #[serde(other)]
78    Other,
79}
80
81/// Request from server → client to sample from a model
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(rename_all = "camelCase")]
84pub struct CreateMessageRequest {
85    pub messages: Vec<SamplingMessage>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub model_preferences: Option<ModelPreferences>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub system_prompt: Option<String>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub include_context: Option<IncludeContext>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub temperature: Option<f64>,
94    pub max_tokens: u32,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub stop_sequences: Option<Vec<String>>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub metadata: Option<serde_json::Value>,
99}
100
101#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
102#[serde(rename_all = "camelCase")]
103pub enum IncludeContext {
104    None,
105    ThisServer,
106    AllServers,
107}
108
109/// Result of a sampling/createMessage call
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct CreateMessageResult {
113    pub role: SamplingRole,
114    pub content: Content,
115    pub model: String,
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub stop_reason: Option<StopReason>,
118}