feat(mcp): customize transport endpoints and improve URI handling (#69)

- Add support for customizable SSE endpoints in HttpClientSseClientTransport
- Replace pathInfo with requestURI in HttpServletSseServerTransportProvider for more reliable endpoint matching
- Implement builder pattern to support the customization options

Related to #40

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
or-givati 2025-03-24 14:41:07 +02:00 • committed by Christian Tzolov
commit 2934635d99
3 changed files with 189 additions and 13 deletions

View file

@ -4,7 +4,6 @@
package io.modelcontextprotocol.server;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.transport.HttpServletSseServerTransportProvider;
import io.modelcontextprotocol.spec.McpServerTransportProvider;
import org.junit.jupiter.api.Timeout;
@ -19,7 +18,7 @@ class ServletSseMcpAsyncServerTests extends AbstractMcpAsyncServerTests {
@Override
protected McpServerTransportProvider createMcpTransportProvider() {
return new HttpServletSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
return HttpServletSseServerTransportProvider.builder().messageEndpoint("/mcp/message").build();
}
}

View file

@ -4,7 +4,6 @@
package io.modelcontextprotocol.server;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.transport.HttpServletSseServerTransportProvider;
import io.modelcontextprotocol.spec.McpServerTransportProvider;
import org.junit.jupiter.api.Timeout;
@ -19,7 +18,7 @@ class ServletSseMcpSyncServerTests extends AbstractMcpSyncServerTests {
@Override
protected McpServerTransportProvider createMcpTransportProvider() {
return new HttpServletSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
return HttpServletSseServerTransportProvider.builder().messageEndpoint("/mcp/message").build();
}
}

View file

@ -47,7 +47,9 @@ public class HttpServletSseServerTransportProviderIntegrationTests {
private static final int PORT = 8185;
private static final String MESSAGE_ENDPOINT = "/mcp/message";
private static final String CUSTOM_SSE_ENDPOINT = "/somePath/sse";
private static final String CUSTOM_MESSAGE_ENDPOINT = "/otherPath/mcp/message";
private HttpServletSseServerTransportProvider mcpServerTransportProvider;
@ -66,7 +68,11 @@ public class HttpServletSseServerTransportProviderIntegrationTests {
Context context = tomcat.addContext("", baseDir);
// Create and configure the transport provider
mcpServerTransportProvider = new HttpServletSseServerTransportProvider(new ObjectMapper(), MESSAGE_ENDPOINT);
mcpServerTransportProvider = HttpServletSseServerTransportProvider.builder()
.objectMapper(new ObjectMapper())
.messageEndpoint(CUSTOM_MESSAGE_ENDPOINT)
.sseEndpoint(CUSTOM_SSE_ENDPOINT)
.build();
// Add transport servlet to Tomcat
org.apache.catalina.Wrapper wrapper = context.createWrapper();
@ -87,7 +93,9 @@ public class HttpServletSseServerTransportProviderIntegrationTests {
throw new RuntimeException("Failed to start Tomcat", e);
}
this.clientBuilder = McpClient.sync(new HttpClientSseClientTransport("http://localhost:" + PORT));
this.clientBuilder = McpClient.sync(HttpClientSseClientTransport.builder("http://localhost:" + PORT)
.sseEndpoint(CUSTOM_SSE_ENDPOINT)
.build());
}
@AfterEach