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 pub fn has_sampling_handler(&self) -> bool {
67 self.inner
68 .sampling_handler
69 .lock()
70 .expect("sampling_handler mutex poisoned")
71 .is_some()
72 }
73
74 /// Remove the sampling handler
75 ///
76 /// Disables sampling capabilities and removes the handler. The client
77 /// will no longer advertise sampling support to servers.
78 pub fn remove_sampling_handler(&self) {
79 *self
80 .inner
81 .sampling_handler
82 .lock()
83 .expect("sampling_handler mutex poisoned") = None;
84 }
85
86 /// Get sampling capabilities for initialization
87 ///
88 /// Returns the sampling capabilities to be sent during client initialization
89 /// if sampling is enabled.
90 pub(crate) fn get_sampling_capabilities(&self) -> Option<SamplingCapabilities> {
91 if self
92 .inner
93 .sampling_handler
94 .lock()
95 .expect("sampling_handler mutex poisoned")
96 .is_some()
97 {
98 Some(SamplingCapabilities)
99 } else {
100 None
101 }
102 }
103}