turbomcp_client/client/operations/
sampling.rs

1//! Sampling operations for MCP client
2//!
3//! This module provides sampling capability management for LLM operations.
4//! Sampling allows the MCP server to request the client to perform LLM
5//! inference when the server needs language model capabilities.
6//!
7//! The client's role in sampling is to:
8//! 1. Register handlers for sampling/createMessage requests
9//! 2. Advertise sampling capabilities during initialization
10//! 3. Process server-initiated sampling requests (handled in core message routing)
11
12use crate::sampling::SamplingHandler;
13use std::sync::Arc;
14use turbomcp_protocol::types::SamplingCapabilities;
15
16impl<T: turbomcp_transport::Transport + 'static> super::super::core::Client<T> {
17    /// Set the sampling handler for processing server-initiated sampling requests
18    ///
19    /// Registers a handler that can process LLM sampling requests from the server.
20    /// When a handler is set, the client will advertise sampling capabilities
21    /// during initialization, allowing the server to request LLM operations.
22    ///
23    /// # Arguments
24    ///
25    /// * `handler` - The handler implementation for sampling requests
26    ///
27    /// # Examples
28    ///
29    /// ```rust,no_run
30    /// use turbomcp_client::{Client, sampling::SamplingHandler};
31    /// use turbomcp_transport::stdio::StdioTransport;
32    /// use turbomcp_protocol::types::{CreateMessageRequest, CreateMessageResult};
33    /// use async_trait::async_trait;
34    /// use std::sync::Arc;
35    ///
36    /// #[derive(Debug)]
37    /// struct ExampleHandler;
38    ///
39    /// #[async_trait]
40    /// impl SamplingHandler for ExampleHandler {
41    ///     async fn handle_create_message(
42    ///         &self,
43    ///         _request_id: String,
44    ///         _request: CreateMessageRequest,
45    ///     ) -> Result<CreateMessageResult, Box<dyn std::error::Error + Send + Sync>> {
46    ///         // Handle sampling request (use request_id for tracking/correlation)
47    ///         todo!("Implement sampling logic")
48    ///     }
49    /// }
50    ///
51    /// let mut client = Client::new(StdioTransport::new());
52    /// client.set_sampling_handler(Arc::new(ExampleHandler));
53    /// ```
54    pub fn set_sampling_handler(&self, handler: Arc<dyn SamplingHandler>) {
55        *self
56            .inner
57            .sampling_handler
58            .lock()
59            .expect("sampling_handler mutex poisoned") = Some(handler);
60    }
61
62    /// Check if sampling is enabled
63    ///
64    /// Returns true if a sampling handler has been configured and sampling
65    /// capabilities are enabled.
66    #[must_use]
67    pub fn has_sampling_handler(&self) -> bool {
68        self.inner
69            .sampling_handler
70            .lock()
71            .expect("sampling_handler mutex poisoned")
72            .is_some()
73    }
74
75    /// Remove the sampling handler
76    ///
77    /// Disables sampling capabilities and removes the handler. The client
78    /// will no longer advertise sampling support to servers.
79    pub fn remove_sampling_handler(&self) {
80        *self
81            .inner
82            .sampling_handler
83            .lock()
84            .expect("sampling_handler mutex poisoned") = None;
85    }
86
87    /// Get sampling capabilities for initialization
88    ///
89    /// Returns the sampling capabilities to be sent during client initialization
90    /// if sampling is enabled.
91    pub(crate) fn get_sampling_capabilities(&self) -> Option<SamplingCapabilities> {
92        if self
93            .inner
94            .sampling_handler
95            .lock()
96            .expect("sampling_handler mutex poisoned")
97            .is_some()
98        {
99            Some(SamplingCapabilities)
100        } else {
101            None
102        }
103    }
104}