getMeta() {
+ return Map.of("ui",
+ Map.of("csp",
+ Map.of("resourceDomains",
+ List.of("https://unpkg.com"))));
+ }
+ }
+
+}
diff --git a/spring-ai-modules/spring-ai-mcp/src/main/resources/application-mcp-ui.properties b/spring-ai-modules/spring-ai-mcp/src/main/resources/application-mcp-ui.properties
new file mode 100644
index 000000000000..25f4e9a45269
--- /dev/null
+++ b/spring-ai-modules/spring-ai-mcp/src/main/resources/application-mcp-ui.properties
@@ -0,0 +1,3 @@
+
+server.port=3001
+spring.ai.mcp.server.protocol=STREAMABLE
diff --git a/spring-ai-modules/spring-ai-mcp/src/main/resources/static/sport-spinner.html b/spring-ai-modules/spring-ai-mcp/src/main/resources/static/sport-spinner.html
new file mode 100644
index 000000000000..345715d29d5c
--- /dev/null
+++ b/spring-ai-modules/spring-ai-mcp/src/main/resources/static/sport-spinner.html
@@ -0,0 +1,228 @@
+
+
+
+
+ Sport Spinner
+
+
+
+
+🎡 Sport Spinner
+Spin the wheel to pick today's sport
+
+
+
+Ready to spin!
+
+
+
+
+
+
diff --git a/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolSseIntegrationTest.java b/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolSseIntegrationTest.java
index 0efbd458fea4..f4e245b575e6 100644
--- a/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolSseIntegrationTest.java
+++ b/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolSseIntegrationTest.java
@@ -14,8 +14,8 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
@@ -28,7 +28,7 @@ class ExchangeRateMcpToolSseIntegrationTest {
@Autowired
private TestMcpClientFactory testMcpClientFactory;
- @MockBean
+ @MockitoBean
private ExchangeRateService exchangeRateService;
private McpSyncClient client;
@@ -62,7 +62,7 @@ void whenMcpClientCallTool_thenTheToolReturnsMockedResponse() {
.findFirst()
.orElseThrow();
- String argumentName = exchangeRateTool.inputSchema().properties().keySet().stream()
+ String argumentName = exchangeRateTool.inputSchema().keySet().stream()
.findFirst()
.orElseThrow();
diff --git a/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolStreamableIntegrationTest.java b/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolStreamableIntegrationTest.java
index 657c17b06fe8..77058d29c978 100644
--- a/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolStreamableIntegrationTest.java
+++ b/spring-ai-modules/spring-ai-mcp/src/test/java/com/baeldung/springai/mcp/test/ExchangeRateMcpToolStreamableIntegrationTest.java
@@ -1,22 +1,22 @@
package com.baeldung.springai.mcp.test;
-import io.modelcontextprotocol.client.McpSyncClient;
-import io.modelcontextprotocol.spec.McpSchema;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+import java.util.Objects;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
-import java.util.Map;
-import java.util.Objects;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.when;
+import io.modelcontextprotocol.client.McpSyncClient;
+import io.modelcontextprotocol.spec.McpSchema;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
@@ -27,7 +27,7 @@ class ExchangeRateMcpToolStreamableIntegrationTest {
@LocalServerPort
private int port;
- @MockBean
+ @MockitoBean
private ExchangeRateService exchangeRateService;
@Autowired
@@ -64,7 +64,7 @@ void whenMcpClientCallTool_thenTheToolReturnsMockedResponse() {
.findFirst()
.orElseThrow();
- String argumentName = exchangeRateTool.inputSchema().properties().keySet().stream()
+ String argumentName = exchangeRateTool.inputSchema().keySet().stream()
.findFirst()
.orElseThrow();