";
+
+ if (toolContext != null && toolContext.getContext().containsKey("exchange")) {
+
+ // Spring AI MCP Auto-configuration injects the McpSyncServerExchange into the ToolContext under the key "exchange"
+ McpSyncServerExchange exchange = (McpSyncServerExchange) toolContext.getContext().get("exchange");
+ if (exchange.getClientCapabilities().sampling() != null) {
+ var messageRequestBuilder = McpSchema.CreateMessageRequest.builder()
+ .systemPrompt("You are a poet!")
+ .messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
+ new McpSchema.TextContent(
+ "Please write a poem about thius weather forecast (temperature is in Celsious). Use markdown format :\n "
+ + ModelOptionsUtils.toJsonStringPrettyPrinter(weatherResponse)))));
+
+ var opeAiLlmMessageRequest = messageRequestBuilder
+ .modelPreferences(ModelPreferences.builder().addHint("openai").build())
+ .build();
+ CreateMessageResult openAiLlmResponse = exchange.createMessage(opeAiLlmMessageRequest);
+
+ openAiWeatherPoem = ((McpSchema.TextContent) openAiLlmResponse.content()).text();
+
+ var anthropicLlmMessageRequest = messageRequestBuilder
+ .modelPreferences(ModelPreferences.builder().addHint("anthropic").build())
+ .build();
+ CreateMessageResult anthropicAiLlmResponse = exchange.createMessage(anthropicLlmMessageRequest);
+
+ anthropicWeatherPoem = ((McpSchema.TextContent) anthropicAiLlmResponse.content()).text();
+
+ }
+ }
+
+ String responseWithPoems = "OpenAI poem about the weather: " + openAiWeatherPoem + "\n\n" +
+ "Anthropic poem about the weather: " + anthropicWeatherPoem + "\n"
+ + ModelOptionsUtils.toJsonStringPrettyPrinter(weatherResponse);
+
+ logger.info(anthropicWeatherPoem, responseWithPoems);
+
+ return responseWithPoems;
+
+ }
+
+}
\ No newline at end of file
diff --git a/model-context-protocol/sampling/mcp-weather-webmvc-server/src/main/resources/application.properties b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/main/resources/application.properties
new file mode 100644
index 0000000..cc33bc0
--- /dev/null
+++ b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/main/resources/application.properties
@@ -0,0 +1,13 @@
+# spring.main.web-application-type=none
+
+# NOTE: You must disable the banner and the console logging
+# to allow the STDIO transport to work !!!
+spring.main.banner-mode=off
+# logging.pattern.console=
+
+# spring.ai.mcp.server.stdio=false
+
+spring.ai.mcp.server.name=mcp-sampling-server
+spring.ai.mcp.server.version=0.0.1
+
+logging.file.name=./model-context-protocol/sampling/mcp-weather-webmvc-server/target/mcp-sampling-server.log
diff --git a/model-context-protocol/book-library/manual-servlet-server/src/test/java/org/springframework/ai/mcp/sample/servlet/client/HttpClientSse.java b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientSse.java
similarity index 91%
rename from model-context-protocol/book-library/manual-servlet-server/src/test/java/org/springframework/ai/mcp/sample/servlet/client/HttpClientSse.java
rename to model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientSse.java
index 44e841d..3846cc5 100644
--- a/model-context-protocol/book-library/manual-servlet-server/src/test/java/org/springframework/ai/mcp/sample/servlet/client/HttpClientSse.java
+++ b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientSse.java
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.ai.mcp.sample.servlet.client;
+package org.springframework.ai.mcp.sample.client;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
+
/**
* @author Christian Tzolov
*/
-public class HttpClientSse {
+public class ClientSse {
public static void main(String[] args) {
var transport = new HttpClientSseClientTransport("http://localhost:8080");
-
new SampleClient(transport).run();
}
diff --git a/model-context-protocol/book-library/starter-webflux-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java
similarity index 69%
rename from model-context-protocol/book-library/starter-webflux-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java
rename to model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java
index caacea6..325448e 100644
--- a/model-context-protocol/book-library/starter-webflux-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java
+++ b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/ClientStdio.java
@@ -15,11 +15,14 @@
*/
package org.springframework.ai.mcp.sample.client;
+import java.io.File;
+
import io.modelcontextprotocol.client.transport.ServerParameters;
import io.modelcontextprotocol.client.transport.StdioClientTransport;
/**
- * With stdio transport, the MCP server is automatically started by the client. But you
+ * With stdio transport, the MCP server is automatically started by the client.
+ * But you
* have to build the server jar first:
*
*
@@ -30,13 +33,17 @@ public class ClientStdio {
public static void main(String[] args) {
+ System.out.println(new File(".").getAbsolutePath());
+
var stdioParams = ServerParameters.builder("java")
- .args("-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none",
- "-Dlogging.pattern.console=", "-jar",
- "model-context-protocol/mcp-webflux-server-starter/target/mcp-webflux-server-starter-0.0.1-SNAPSHOT.jar")
- .build();
+ .args("-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none",
+ "-Dlogging.pattern.console=", "-jar",
+ "model-context-protocol/sampling/mcp-weather-webmvc-server/target/mcp-sampling-weather-server-0.0.1-SNAPSHOT.jar")
+ .build();
- new SampleClient(new StdioClientTransport(stdioParams)).run();
+ var transport = new StdioClientTransport(stdioParams);
+
+ new SampleClient(transport).run();
}
}
diff --git a/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/SampleClient.java b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/SampleClient.java
new file mode 100644
index 0000000..c8fbfe0
--- /dev/null
+++ b/model-context-protocol/sampling/mcp-weather-webmvc-server/src/test/java/org/springframework/ai/mcp/sample/client/SampleClient.java
@@ -0,0 +1,69 @@
+/*
+* Copyright 2024 - 2024 the original author or authors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* https://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.springframework.ai.mcp.sample.client;
+
+import java.util.Map;
+
+import io.modelcontextprotocol.client.McpClient;
+import io.modelcontextprotocol.spec.McpClientTransport;
+import io.modelcontextprotocol.spec.McpSchema;
+import io.modelcontextprotocol.spec.McpSchema.CallToolRequest;
+import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
+import io.modelcontextprotocol.spec.McpSchema.CreateMessageResult;
+import io.modelcontextprotocol.spec.McpSchema.ListToolsResult;
+
+import org.springframework.ai.chat.model.ToolContext;
+
+/**
+ * @author Christian Tzolov
+ */
+
+public class SampleClient {
+
+ private final McpClientTransport transport;
+
+ public SampleClient(McpClientTransport transport) {
+ this.transport = transport;
+ }
+
+ public void run() {
+
+ var client = McpClient.sync(this.transport)
+ .sampling(request -> {
+ System.out.println("Received a new message: " + request);
+ return CreateMessageResult.builder()
+ .content(new McpSchema.TextContent("Bla bla bla"))
+ .build();
+ })
+ .build();
+
+ client.initialize();
+
+ client.ping();
+
+ // List and demonstrate tools
+ ListToolsResult toolsList = client.listTools();
+ System.out.println("Available Tools = " + toolsList);
+
+ CallToolResult weatherForcastResult = client.callTool(new CallToolRequest("getTemperature",
+ Map.of("latitude", "47.6062", "longitude", "-122.3321", "toolContext", new ToolContext(Map.of()))));
+ System.out.println("Weather Forcast: " + weatherForcastResult);
+
+ client.closeGracefully();
+
+ }
+
+}
diff --git a/model-context-protocol/sqlite/chatbot/pom.xml b/model-context-protocol/sqlite/chatbot/pom.xml
index b0eb32f..f6ce845 100644
--- a/model-context-protocol/sqlite/chatbot/pom.xml
+++ b/model-context-protocol/sqlite/chatbot/pom.xml
@@ -22,7 +22,7 @@
org.springframework.ai
spring-ai-bom
- 1.0.0-M5
+ 1.0.0-SNAPSHOT
pom
import
@@ -37,13 +37,12 @@
org.springframework.ai
- spring-ai-openai-spring-boot-starter
+ spring-ai-starter-model-openai
- org.springframework.experimental
- spring-ai-mcp
- 0.6.0
+ org.springframework.ai
+ spring-ai-starter-mcp-client