13
13
import java .util .concurrent .CountDownLatch ;
14
14
import java .util .concurrent .TimeUnit ;
15
15
import java .util .concurrent .atomic .AtomicReference ;
16
+ import java .util .function .Consumer ;
16
17
import java .util .function .Function ;
17
18
18
19
import com .fasterxml .jackson .core .type .TypeReference ;
@@ -103,7 +104,10 @@ public class HttpClientSseClientTransport implements McpClientTransport {
103
104
/**
104
105
* Creates a new transport instance with default HTTP client and object mapper.
105
106
* @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.
106
109
*/
110
+ @ Deprecated (forRemoval = true )
107
111
public HttpClientSseClientTransport (String baseUri ) {
108
112
this (HttpClient .newBuilder (), baseUri , new ObjectMapper ());
109
113
}
@@ -114,7 +118,10 @@ public HttpClientSseClientTransport(String baseUri) {
114
118
* @param baseUri the base URI of the MCP server
115
119
* @param objectMapper the object mapper for JSON serialization/deserialization
116
120
* @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.
117
123
*/
124
+ @ Deprecated (forRemoval = true )
118
125
public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , String baseUri , ObjectMapper objectMapper ) {
119
126
this (clientBuilder , baseUri , DEFAULT_SSE_ENDPOINT , objectMapper );
120
127
}
@@ -126,7 +133,10 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, String bas
126
133
* @param sseEndpoint the SSE endpoint path
127
134
* @param objectMapper the object mapper for JSON serialization/deserialization
128
135
* @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.
129
138
*/
139
+ @ Deprecated (forRemoval = true )
130
140
public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , String baseUri , String sseEndpoint ,
131
141
ObjectMapper objectMapper ) {
132
142
this (clientBuilder , HttpRequest .newBuilder (), baseUri , sseEndpoint , objectMapper );
@@ -141,18 +151,37 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, String bas
141
151
* @param sseEndpoint the SSE endpoint path
142
152
* @param objectMapper the object mapper for JSON serialization/deserialization
143
153
* @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.
144
156
*/
157
+ @ Deprecated (forRemoval = true )
145
158
public HttpClientSseClientTransport (HttpClient .Builder clientBuilder , HttpRequest .Builder requestBuilder ,
146
159
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 ) {
147
176
Assert .notNull (objectMapper , "ObjectMapper must not be null" );
148
177
Assert .hasText (baseUri , "baseUri must not be empty" );
149
178
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" );
151
180
Assert .notNull (requestBuilder , "requestBuilder must not be null" );
152
181
this .baseUri = baseUri ;
153
182
this .sseEndpoint = sseEndpoint ;
154
183
this .objectMapper = objectMapper ;
155
- this .httpClient = clientBuilder . connectTimeout ( Duration . ofSeconds ( 10 )). build () ;
184
+ this .httpClient = httpClient ;
156
185
this .requestBuilder = requestBuilder ;
157
186
158
187
this .sseClient = new FlowSseClient (this .httpClient , requestBuilder );
@@ -164,33 +193,58 @@ public HttpClientSseClientTransport(HttpClient.Builder clientBuilder, HttpReques
164
193
* @return a new builder instance
165
194
*/
166
195
public static Builder builder (String baseUri ) {
167
- return new Builder (baseUri );
196
+ return new Builder (). baseUri ( baseUri );
168
197
}
169
198
170
199
/**
171
200
* Builder for {@link HttpClientSseClientTransport}.
172
201
*/
173
202
public static class Builder {
174
203
175
- private final String baseUri ;
204
+ private String baseUri ;
176
205
177
206
private String sseEndpoint = DEFAULT_SSE_ENDPOINT ;
178
207
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 ));
180
211
181
212
private ObjectMapper objectMapper = new ObjectMapper ();
182
213
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
+ }
184
223
185
224
/**
186
225
* Creates a new builder with the specified base URI.
187
226
* @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.
188
230
*/
231
+ @ Deprecated (forRemoval = true )
189
232
public Builder (String baseUri ) {
190
233
Assert .hasText (baseUri , "baseUri must not be empty" );
191
234
this .baseUri = baseUri ;
192
235
}
193
236
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
+
194
248
/**
195
249
* Sets the SSE endpoint path.
196
250
* @param sseEndpoint the SSE endpoint path
@@ -213,6 +267,17 @@ public Builder clientBuilder(HttpClient.Builder clientBuilder) {
213
267
return this ;
214
268
}
215
269
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
+
216
281
/**
217
282
* Sets the HTTP request builder.
218
283
* @param requestBuilder the HTTP request builder
@@ -224,6 +289,17 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) {
224
289
return this ;
225
290
}
226
291
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
+
227
303
/**
228
304
* Sets the object mapper for JSON serialization/deserialization.
229
305
* @param objectMapper the object mapper
@@ -240,7 +316,8 @@ public Builder objectMapper(ObjectMapper objectMapper) {
240
316
* @return a new transport instance
241
317
*/
242
318
public HttpClientSseClientTransport build () {
243
- return new HttpClientSseClientTransport (clientBuilder , requestBuilder , baseUri , sseEndpoint , objectMapper );
319
+ return new HttpClientSseClientTransport (clientBuilder .build (), requestBuilder , baseUri , sseEndpoint ,
320
+ objectMapper );
244
321
}
245
322
246
323
}
@@ -336,7 +413,6 @@ public Mono<Void> sendMessage(JSONRPCMessage message) {
336
413
try {
337
414
String jsonText = this .objectMapper .writeValueAsString (message );
338
415
HttpRequest request = this .requestBuilder .uri (URI .create (this .baseUri + endpoint ))
339
- .header ("Content-Type" , "application/json" )
340
416
.POST (HttpRequest .BodyPublishers .ofString (jsonText ))
341
417
.build ();
342
418
0 commit comments