1313import java .util .concurrent .CountDownLatch ;
1414import java .util .concurrent .TimeUnit ;
1515import java .util .concurrent .atomic .AtomicReference ;
16+ import java .util .function .Consumer ;
1617import java .util .function .Function ;
1718
1819import com .fasterxml .jackson .core .type .TypeReference ;
@@ -103,7 +104,10 @@ public class HttpClientSseClientTransport implements McpClientTransport {
103104 /**
104105 * Creates a new transport instance with default HTTP client and object mapper.
105106 * @param baseUri the base URI of the MCP server
107+ * @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead. This
108+ * constructor will be removed in future versions.
106109 */
110+ @ Deprecated (forRemoval = true )
107111 public HttpClientSseClientTransport (String baseUri ) {
108112 this (HttpClient .newBuilder (), baseUri , new ObjectMapper ());
109113 }
@@ -114,7 +118,10 @@ public HttpClientSseClientTransport(String baseUri) {
114118 * @param baseUri the base URI of the MCP server
115119 * @param objectMapper the object mapper for JSON serialization/deserialization
116120 * @throws IllegalArgumentException if objectMapper or clientBuilder is null
121+ * @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead. This
122+ * constructor will be removed in future versions.
117123 */
124+ @ Deprecated (forRemoval = true )
118125 public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , String baseUri , ObjectMapper objectMapper ) {
119126 this (clientBuilder , baseUri , DEFAULT_SSE_ENDPOINT , objectMapper );
120127 }
@@ -126,7 +133,10 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, String bas
126133 * @param sseEndpoint the SSE endpoint path
127134 * @param objectMapper the object mapper for JSON serialization/deserialization
128135 * @throws IllegalArgumentException if objectMapper or clientBuilder is null
136+ * @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead. This
137+ * constructor will be removed in future versions.
129138 */
139+ @ Deprecated (forRemoval = true )
130140 public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , String baseUri , String sseEndpoint ,
131141 ObjectMapper objectMapper ) {
132142 this (clientBuilder , HttpRequest .newBuilder (), baseUri , sseEndpoint , objectMapper );
@@ -141,18 +151,37 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, String bas
141151 * @param sseEndpoint the SSE endpoint path
142152 * @param objectMapper the object mapper for JSON serialization/deserialization
143153 * @throws IllegalArgumentException if objectMapper, clientBuilder, or headers is null
154+ * @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead. This
155+ * constructor will be removed in future versions.
144156 */
157+ @ Deprecated (forRemoval = true )
145158 public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , HttpRequest .Builder requestBuilder ,
146159 String baseUri , String sseEndpoint , ObjectMapper objectMapper ) {
160+ this (clientBuilder .connectTimeout (Duration .ofSeconds (10 )).build (), requestBuilder , baseUri , sseEndpoint ,
161+ objectMapper );
162+ }
163+
164+ /**
165+ * Creates a new transport instance with custom HTTP client builder, object mapper,
166+ * and headers.
167+ * @param httpClient the HTTP client to use
168+ * @param requestBuilder the HTTP request builder to use
169+ * @param baseUri the base URI of the MCP server
170+ * @param sseEndpoint the SSE endpoint path
171+ * @param objectMapper the object mapper for JSON serialization/deserialization
172+ * @throws IllegalArgumentException if objectMapper, clientBuilder, or headers is null
173+ */
174+ HttpClientSseClientTransport (HttpClient httpClient , HttpRequest .Builder requestBuilder , String baseUri ,
175+ String sseEndpoint , ObjectMapper objectMapper ) {
147176 Assert .notNull (objectMapper , "ObjectMapper must not be null" );
148177 Assert .hasText (baseUri , "baseUri must not be empty" );
149178 Assert .hasText (sseEndpoint , "sseEndpoint must not be empty" );
150- Assert .notNull (clientBuilder , "clientBuilder must not be null" );
179+ Assert .notNull (httpClient , "httpClient must not be null" );
151180 Assert .notNull (requestBuilder , "requestBuilder must not be null" );
152181 this .baseUri = baseUri ;
153182 this .sseEndpoint = sseEndpoint ;
154183 this .objectMapper = objectMapper ;
155- this .httpClient = clientBuilder . connectTimeout ( Duration . ofSeconds ( 10 )). build () ;
184+ this .httpClient = httpClient ;
156185 this .requestBuilder = requestBuilder ;
157186
158187 this .sseClient = new FlowSseClient (this .httpClient , requestBuilder );
@@ -164,33 +193,58 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, HttpReques
164193 * @return a new builder instance
165194 */
166195 public static Builder builder (String baseUri ) {
167- return new Builder (baseUri );
196+ return new Builder (). baseUri ( baseUri );
168197 }
169198
170199 /**
171200 * Builder for {@link HttpClientSseClientTransport}.
172201 */
173202 public static class Builder {
174203
175- private final String baseUri ;
204+ private String baseUri ;
176205
177206 private String sseEndpoint = DEFAULT_SSE_ENDPOINT ;
178207
179- private HttpClient .Builder clientBuilder = HttpClient .newBuilder ();
208+ private HttpClient .Builder clientBuilder = HttpClient .newBuilder ()
209+ .version (HttpClient .Version .HTTP_1_1 )
210+ .connectTimeout (Duration .ofSeconds (10 ));
180211
181212 private ObjectMapper objectMapper = new ObjectMapper ();
182213
183- private HttpRequest .Builder requestBuilder = HttpRequest .newBuilder ();
214+ private HttpRequest .Builder requestBuilder = HttpRequest .newBuilder ()
215+ .header ("Content-Type" , "application/json" );
216+
217+ /**
218+ * Creates a new builder instance.
219+ */
220+ Builder () {
221+ // Default constructor
222+ }
184223
185224 /**
186225 * Creates a new builder with the specified base URI.
187226 * @param baseUri the base URI of the MCP server
227+ * @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead.
228+ * This constructor is deprecated and will be removed or made {@code protected} or
229+ * {@code private} in a future release.
188230 */
231+ @ Deprecated (forRemoval = true )
189232 public Builder (String baseUri ) {
190233 Assert .hasText (baseUri , "baseUri must not be empty" );
191234 this .baseUri = baseUri ;
192235 }
193236
237+ /**
238+ * Sets the base URI.
239+ * @param baseUri the base URI
240+ * @return this builder
241+ */
242+ Builder baseUri (String baseUri ) {
243+ Assert .hasText (baseUri , "baseUri must not be empty" );
244+ this .baseUri = baseUri ;
245+ return this ;
246+ }
247+
194248 /**
195249 * Sets the SSE endpoint path.
196250 * @param sseEndpoint the SSE endpoint path
@@ -213,6 +267,17 @@ public Builder clientBuilder(HttpClient.Builder clientBuilder) {
213267 return this ;
214268 }
215269
270+ /**
271+ * Customizes the HTTP client builder.
272+ * @param clientCustomizer the consumer to customize the HTTP client builder
273+ * @return this builder
274+ */
275+ public Builder customizeClient (final Consumer <HttpClient .Builder > clientCustomizer ) {
276+ Assert .notNull (clientCustomizer , "clientCustomizer must not be null" );
277+ clientCustomizer .accept (clientBuilder );
278+ return this ;
279+ }
280+
216281 /**
217282 * Sets the HTTP request builder.
218283 * @param requestBuilder the HTTP request builder
@@ -224,6 +289,17 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) {
224289 return this ;
225290 }
226291
292+ /**
293+ * Customizes the HTTP client builder.
294+ * @param requestCustomizer the consumer to customize the HTTP request builder
295+ * @return this builder
296+ */
297+ public Builder customizeRequest (final Consumer <HttpRequest .Builder > requestCustomizer ) {
298+ Assert .notNull (requestCustomizer , "requestCustomizer must not be null" );
299+ requestCustomizer .accept (requestBuilder );
300+ return this ;
301+ }
302+
227303 /**
228304 * Sets the object mapper for JSON serialization/deserialization.
229305 * @param objectMapper the object mapper
@@ -240,7 +316,8 @@ public Builder objectMapper(ObjectMapper objectMapper) {
240316 * @return a new transport instance
241317 */
242318 public HttpClientSseClientTransport build () {
243- return new HttpClientSseClientTransport (clientBuilder , requestBuilder , baseUri , sseEndpoint , objectMapper );
319+ return new HttpClientSseClientTransport (clientBuilder .build (), requestBuilder , baseUri , sseEndpoint ,
320+ objectMapper );
244321 }
245322
246323 }
@@ -336,7 +413,6 @@ public Mono<Void> sendMessage(JSONRPCMessage message) {
336413 try {
337414 String jsonText = this .objectMapper .writeValueAsString (message );
338415 HttpRequest request = this .requestBuilder .uri (URI .create (this .baseUri + endpoint ))
339- .header ("Content-Type" , "application/json" )
340416 .POST (HttpRequest .BodyPublishers .ofString (jsonText ))
341417 .build ();
342418
0 commit comments