Skip to content

Commit 88dcef6

Browse files
committed
feat(webrx): Add base URL support to WebFluxSseServerTransportProvider (modelcontextprotocol#102)
1 parent 60b3820 commit 88dcef6

1 file changed

Lines changed: 59 additions & 20 deletions

File tree

mcp-solon/mcp-solon-webrx/src/main/java/io/modelcontextprotocol/server/transport/WebRxSseServerTransportProvider.java

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* <li>Implements the {@link McpServerTransportProvider} interface that allows managing
3737
* {@link McpServerSession} instances and enabling their communication with the
3838
* {@link McpServerTransport} abstraction.</li>
39-
* <li>Uses WebFlux for non-blocking request handling and SSE support</li>
39+
* <li>Uses WebRx for non-blocking request handling and SSE support</li>
4040
* <li>Maintains client sessions for reliable message delivery</li>
4141
* <li>Supports graceful shutdown with session cleanup</li>
4242
* <li>Thread-safe message broadcasting to multiple clients</li>
@@ -80,8 +80,16 @@ public class WebRxSseServerTransportProvider implements McpServerTransportProvid
8080
*/
8181
public static final String DEFAULT_SSE_ENDPOINT = "/sse";
8282

83+
public static final String DEFAULT_BASE_URL = "";
84+
8385
private final ObjectMapper objectMapper;
8486

87+
/**
88+
* Base URL for the message endpoint. This is used to construct the full URL for
89+
* clients to send their JSON-RPC messages.
90+
*/
91+
private final String baseUrl;
92+
8593
private final String messageEndpoint;
8694

8795
private final String sseEndpoint;
@@ -99,7 +107,21 @@ public class WebRxSseServerTransportProvider implements McpServerTransportProvid
99107
private volatile boolean isClosing = false;
100108

101109
/**
102-
* Constructs a new WebFlux SSE server transport provider instance.
110+
* Constructs a new WebRx SSE server transport provider instance with the default
111+
* SSE endpoint.
112+
* @param objectMapper The ObjectMapper to use for JSON serialization/deserialization
113+
* of MCP messages. Must not be null.
114+
* @param messageEndpoint The endpoint URI where clients should send their JSON-RPC
115+
* messages. This endpoint will be communicated to clients during SSE connection
116+
* setup. Must not be null.
117+
* @throws IllegalArgumentException if either parameter is null
118+
*/
119+
public WebRxSseServerTransportProvider(ObjectMapper objectMapper, String messageEndpoint) {
120+
this(objectMapper, messageEndpoint, DEFAULT_SSE_ENDPOINT);
121+
}
122+
123+
/**
124+
* Constructs a new WebRx SSE server transport provider instance.
103125
* @param objectMapper The ObjectMapper to use for JSON serialization/deserialization
104126
* of MCP messages. Must not be null.
105127
* @param messageEndpoint The endpoint URI where clients should send their JSON-RPC
@@ -108,11 +130,27 @@ public class WebRxSseServerTransportProvider implements McpServerTransportProvid
108130
* @throws IllegalArgumentException if either parameter is null
109131
*/
110132
public WebRxSseServerTransportProvider(ObjectMapper objectMapper, String messageEndpoint, String sseEndpoint) {
133+
this(objectMapper, DEFAULT_BASE_URL, messageEndpoint, sseEndpoint);
134+
}
135+
136+
/**
137+
* Constructs a new WebRx SSE server transport provider instance.
138+
* @param objectMapper The ObjectMapper to use for JSON serialization/deserialization
139+
* of MCP messages. Must not be null.
140+
* @param baseUrl webrx message base path
141+
* @param messageEndpoint The endpoint URI where clients should send their JSON-RPC
142+
* messages. This endpoint will be communicated to clients during SSE connection
143+
* setup. Must not be null.
144+
* @throws IllegalArgumentException if either parameter is null
145+
*/
146+
public WebRxSseServerTransportProvider(ObjectMapper objectMapper, String baseUrl, String messageEndpoint, String sseEndpoint) {
111147
Assert.notNull(objectMapper, "ObjectMapper must not be null");
148+
Assert.notNull(baseUrl, "Message base path must not be null");
112149
Assert.notNull(messageEndpoint, "Message endpoint must not be null");
113150
Assert.notNull(sseEndpoint, "SSE endpoint must not be null");
114151

115152
this.objectMapper = objectMapper;
153+
this.baseUrl = baseUrl;
116154
this.messageEndpoint = messageEndpoint;
117155
this.sseEndpoint = sseEndpoint;
118156
}
@@ -138,20 +176,6 @@ public String getMessageEndpoint() {
138176
return messageEndpoint;
139177
}
140178

141-
/**
142-
* Constructs a new WebFlux SSE server transport provider instance with the default
143-
* SSE endpoint.
144-
* @param objectMapper The ObjectMapper to use for JSON serialization/deserialization
145-
* of MCP messages. Must not be null.
146-
* @param messageEndpoint The endpoint URI where clients should send their JSON-RPC
147-
* messages. This endpoint will be communicated to clients during SSE connection
148-
* setup. Must not be null.
149-
* @throws IllegalArgumentException if either parameter is null
150-
*/
151-
public WebRxSseServerTransportProvider(ObjectMapper objectMapper, String messageEndpoint) {
152-
this(objectMapper, messageEndpoint, DEFAULT_SSE_ENDPOINT);
153-
}
154-
155179
@Override
156180
public void setSessionFactory(McpServerSession.Factory sessionFactory) {
157181
this.sessionFactory = sessionFactory;
@@ -242,7 +266,7 @@ public void handleSseConnection(Context ctx) throws Throwable{
242266
logger.debug("Sending initial endpoint event to session: {}", sessionId);
243267
sink.next(new SseEvent()
244268
.name(ENDPOINT_EVENT_TYPE)
245-
.data(messageEndpoint + "?sessionId=" + sessionId));
269+
.data(this.baseUrl + messageEndpoint + "?sessionId=" + sessionId));
246270
sink.onCancel(() -> {
247271
logger.debug("Session {} cancelled", sessionId);
248272
sessions.remove(sessionId);
@@ -373,12 +397,14 @@ public static Builder builder() {
373397
* Builder for creating instances of {@link WebRxSseServerTransportProvider}.
374398
* <p>
375399
* This builder provides a fluent API for configuring and creating instances of
376-
* WebFluxSseServerTransportProvider with custom settings.
400+
* WebRxSseServerTransportProvider with custom settings.
377401
*/
378402
public static class Builder {
379403

380404
private ObjectMapper objectMapper;
381405

406+
private String baseUrl = DEFAULT_BASE_URL;
407+
382408
private String messageEndpoint;
383409

384410
private String sseEndpoint = DEFAULT_SSE_ENDPOINT;
@@ -396,6 +422,19 @@ public Builder objectMapper(ObjectMapper objectMapper) {
396422
return this;
397423
}
398424

425+
/**
426+
* Sets the project basePath as endpoint prefix where clients should send their
427+
* JSON-RPC messages
428+
* @param baseUrl the message basePath . Must not be null.
429+
* @return this builder instance
430+
* @throws IllegalArgumentException if basePath is null
431+
*/
432+
public Builder basePath(String baseUrl) {
433+
Assert.notNull(baseUrl, "basePath must not be null");
434+
this.baseUrl = baseUrl;
435+
return this;
436+
}
437+
399438
/**
400439
* Sets the endpoint URI where clients should send their JSON-RPC messages.
401440
* @param messageEndpoint The message endpoint URI. Must not be null.
@@ -423,14 +462,14 @@ public Builder sseEndpoint(String sseEndpoint) {
423462
/**
424463
* Builds a new instance of {@link WebRxSseServerTransportProvider} with the
425464
* configured settings.
426-
* @return A new WebFluxSseServerTransportProvider instance
465+
* @return A new WebRxSseServerTransportProvider instance
427466
* @throws IllegalStateException if required parameters are not set
428467
*/
429468
public WebRxSseServerTransportProvider build() {
430469
Assert.notNull(objectMapper, "ObjectMapper must be set");
431470
Assert.notNull(messageEndpoint, "Message endpoint must be set");
432471

433-
return new WebRxSseServerTransportProvider(objectMapper, messageEndpoint, sseEndpoint);
472+
return new WebRxSseServerTransportProvider(objectMapper, baseUrl, messageEndpoint, sseEndpoint);
434473
}
435474
}
436475
}

0 commit comments

Comments
 (0)