@@ -659,6 +659,110 @@ private class CancellationTool implements McpTool {
659659}
660660```
661661
662+ ### Sampling
663+
664+ The MCP Sampling feature provides a standardized mechanism that allows servers to request LLM sampling operations from language
665+ models through connected clients. It enables servers to seamlessly integrate AI capabilities into their workflows without
666+ requiring API keys. Like other MCP features, sampling can be accessed via the MCP request features.
667+ Sampling support is optional for clients, and servers can verify its availability using the ` enabled ` method:
668+
669+ ``` java
670+ var sampling = request. features(). sampling();
671+ if (! sampling. enabled()) {
672+ }
673+ ```
674+
675+ If the client supports sampling, you can send a sampling request using the request method. A builder is provided to configure
676+ and customize the sampling request as needed:
677+
678+ ``` java
679+ McpSamplingRequest request = McpSamplingRequest . builder()
680+ .maxTokens(1 )
681+ .temperature(0.1 )
682+ .costPriority(0.1 )
683+ .speedPriority(0.1 )
684+ .hints(List . of(" hint1" ))
685+ .metadata(JsonValue . TRUE )
686+ .intelligencePriority(0.1 )
687+ .systemPrompt(" system prompt" )
688+ .timeout(Duration . ofSeconds(10 ))
689+ .stopSequences(List . of(" stop1" ))
690+ .includeContext(McpIncludeContext . NONE )
691+ .addMessage(McpSamplingMessages . textContent(" text" , McpRole . USER ))
692+ .build();
693+ ```
694+
695+ Once your request is built, send it using the sampling feature. The request method may throw an ` McpSamplingException ` if an
696+ error occurs during processing. On success, it returns an McpSamplingResponse containing the response message, the model used,
697+ and optionally a stop reason.
698+
699+ ``` java
700+ try {
701+ McpSamplingResponse response = sampling. request(req - > req. addMessage(message));
702+ } catch (McpSamplingException exception) {
703+ // Manage error
704+ }
705+ ```
706+
707+ The messages you send are prompts to the language model, and they follow the same structure as MCP prompts. You can use the
708+ ` McpSamplingMessages ` utility class to create different types of messages for the client model:
709+
710+ ``` java
711+ var text = McpSamplingMessages . textContent(" Explain Helidon MCP in one paragraph." , McpRole . USER );
712+ var image = McpSamplingMessages . imageContent(pngBytes, MediaTypes . create(" image/png" ), McpRole . USER );
713+ var audio = McpSamplingMessages . audioContent(wavBytes, MediaTypes . create(" audio/wav" ), McpRole . USER );
714+ ```
715+
716+ #### Example
717+
718+ Below is an example of a tool that uses the Sampling feature. If the connected client does not support sampling, the tool
719+ throws a ` McpToolErrorException ` .
720+
721+ ``` java
722+ import java.time.Duration ;
723+
724+ class SamplingTool implements McpTool {
725+ @Override
726+ public String name () {
727+ return " sampling-tool" ;
728+ }
729+
730+ @Override
731+ public String description () {
732+ return " Uses MCP Sampling to ask the connected client model." ;
733+ }
734+
735+ @Override
736+ public String schema () {
737+ return " " ;
738+ }
739+
740+ @Override
741+ public List<McpToolContent > process (McpRequest request ) {
742+ var sampling = request. features(). sampling();
743+
744+ if (! sampling. enabled()) {
745+ throw new McpToolErrorException (" This tool requires sampling feature" );
746+ }
747+
748+ try {
749+ McpSamplingResponse response = sampling. request(req - > req
750+ .timeout(Duration . ofSeconds(10 ))
751+ .systemPrompt(" You are a concise, helpful assistant." )
752+ .addMessage(McpSamplingMessages . textContent(" Write a 3-line summary of Helidon MCP Sampling." , McpRole . USER )));
753+
754+ McpSamplingMessage message = response. message();
755+ if (message instanceof McpSamplingTextContent text) {
756+ return List . of(McpToolContents . textContent(text. text()));
757+ }
758+ throw new McpToolErrorException (" Received non-text sampling content." );
759+ } catch (McpSamplingException e) {
760+ throw new McpToolErrorException (e. getMessage());
761+ }
762+ }
763+ }
764+ ```
765+
662766## Configuration
663767
664768MCP server configuration can be defined using Helidon configuration files. Example in YAML:
0 commit comments