1+ /*
2+ * Copyright 2024-2024 the original author or authors.
3+ */
4+
5+ package io .modelcontextprotocol .server .transport ;
6+
7+ import java .util .Map ;
8+ import java .util .List ;
9+
10+ import com .fasterxml .jackson .databind .ObjectMapper ;
11+ import io .modelcontextprotocol .client .McpClient ;
12+ import io .modelcontextprotocol .client .transport .WebClientStreamableHttpTransport ;
13+ import io .modelcontextprotocol .server .McpServer ;
14+ import io .modelcontextprotocol .server .McpServerFeatures ;
15+ import io .modelcontextprotocol .spec .McpSchema ;
16+ import io .modelcontextprotocol .spec .McpSchema .CallToolResult ;
17+ import io .modelcontextprotocol .spec .McpSchema .InitializeResult ;
18+ import org .apache .catalina .LifecycleException ;
19+ import org .apache .catalina .LifecycleState ;
20+ import org .apache .catalina .startup .Tomcat ;
21+ import org .junit .jupiter .api .AfterEach ;
22+ import org .junit .jupiter .api .BeforeEach ;
23+ import org .junit .jupiter .api .Test ;
24+ import org .springframework .web .reactive .function .client .WebClient ;
25+
26+ import static org .assertj .core .api .Assertions .assertThat ;
27+
28+ /**
29+ * Integration tests for {@link StreamableHttpServerTransportProvider} with
30+ * {@link WebClientStreamableHttpTransport}.
31+ */
32+ class StreamableHttpServerTransportProviderIntegrationTests {
33+
34+ private static final int PORT = TomcatTestUtil .findAvailablePort ();
35+
36+ private static final String ENDPOINT = "/mcp" ;
37+
38+ private StreamableHttpServerTransportProvider serverTransportProvider ;
39+
40+ private McpClient .SyncSpec clientBuilder ;
41+
42+ private Tomcat tomcat ;
43+
44+ @ BeforeEach
45+ void setUp () {
46+ serverTransportProvider = new StreamableHttpServerTransportProvider (new ObjectMapper (), ENDPOINT , null );
47+
48+ tomcat = TomcatTestUtil .createTomcatServer ("" , PORT , serverTransportProvider );
49+ try {
50+ tomcat .start ();
51+ assertThat (tomcat .getServer ().getState ()).isEqualTo (LifecycleState .STARTED );
52+ }
53+ catch (Exception e ) {
54+ throw new RuntimeException ("Failed to start Tomcat" , e );
55+ }
56+
57+ WebClientStreamableHttpTransport clientTransport = WebClientStreamableHttpTransport
58+ .builder (WebClient .builder ().baseUrl ("http://localhost:" + PORT ))
59+ .endpoint (ENDPOINT )
60+ .objectMapper (new ObjectMapper ())
61+ .build ();
62+
63+ clientBuilder = McpClient .sync (clientTransport )
64+ .clientInfo (new McpSchema .Implementation ("Test Client" , "1.0.0" ));
65+ }
66+
67+ @ AfterEach
68+ void tearDown () {
69+ if (serverTransportProvider != null ) {
70+ serverTransportProvider .closeGracefully ().block ();
71+ }
72+ if (tomcat != null ) {
73+ try {
74+ tomcat .stop ();
75+ tomcat .destroy ();
76+ }
77+ catch (LifecycleException e ) {
78+ throw new RuntimeException ("Failed to stop Tomcat" , e );
79+ }
80+ }
81+ }
82+
83+ @ Test
84+ void shouldInitializeSuccessfully () {
85+ var mcpServer = McpServer .sync (serverTransportProvider ).serverInfo ("Test Server" , "1.0.0" ).build ();
86+
87+ try (var mcpClient = clientBuilder .build ()) {
88+ InitializeResult result = mcpClient .initialize ();
89+ assertThat (result ).isNotNull ();
90+ assertThat (result .serverInfo ().name ()).isEqualTo ("Test Server" );
91+ }
92+
93+ mcpServer .close ();
94+ }
95+
96+ @ Test
97+ void shouldCallToolSuccessfully () {
98+ String emptyJsonSchema = """
99+ {
100+ "$schema": "http://json-schema.org/draft-07/schema#",
101+ "type": "object",
102+ "properties": {}
103+ }
104+ """ ;
105+
106+ var callResponse = new CallToolResult (List .of (new McpSchema .TextContent ("Tool executed successfully" )), null );
107+ McpServerFeatures .SyncToolSpecification tool = new McpServerFeatures .SyncToolSpecification (
108+ new McpSchema .Tool ("test-tool" , "Test tool description" , emptyJsonSchema ),
109+ (exchange , request ) -> callResponse );
110+
111+ var mcpServer = McpServer .sync (serverTransportProvider ).serverInfo ("Test Server" , "1.0.0" ).tools (tool ).build ();
112+
113+ try (var mcpClient = clientBuilder .build ()) {
114+ mcpClient .initialize ();
115+
116+ CallToolResult response = mcpClient .callTool (new McpSchema .CallToolRequest ("test-tool" , Map .of ()));
117+
118+ assertThat (response ).isNotNull ();
119+ assertThat (response ).isEqualTo (callResponse );
120+ }
121+
122+ mcpServer .close ();
123+ }
124+
125+ }
0 commit comments