Skip to content

Commit 5b330b0

Browse files
gyeo009Kehrlann
authored andcommitted
Deprecate Builder.customizeRequest() in HttpClientSseClientTransport and HttpClientStreamableHttpTransport
customizeRequest() executes its consumer once at build time, freezing headers into the shared requestBuilder. This silently breaks OAuth token refresh scenarios where the Authorization header needs to be updated after the transport is built. Add @deprecated and update Javadoc to clarify the build-time-only semantics and guide users toward httpRequestCustomizer() or asyncHttpRequestCustomizer() which run on every request. Closes #788
1 parent 22e7bd4 commit 5b330b0

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,24 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) {
241241
}
242242

243243
/**
244-
* Customizes the HTTP client builder.
244+
* Applies the given consumer to the shared {@link HttpRequest.Builder} <b>once,
245+
* at build time</b>. Any headers set here (e.g., {@code Authorization}) are
246+
* frozen into the template and copied to every subsequent request via
247+
* {@code requestBuilder.copy()}. They <b>cannot be updated</b> after the
248+
* transport is built.
249+
* <p>
250+
* For dynamic, per-request customization (e.g., OAuth token refresh), use
251+
* {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or
252+
* {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)}
253+
* instead.
245254
* @param requestCustomizer the consumer to customize the HTTP request builder
246255
* @return this builder
256+
* @deprecated Use
257+
* {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or
258+
* {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which
259+
* run on every request and support dynamic headers.
247260
*/
261+
@Deprecated
248262
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
249263
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
250264
requestCustomizer.accept(requestBuilder);

mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,24 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) {
738738
}
739739

740740
/**
741-
* Customizes the HTTP client builder.
741+
* Applies the given consumer to the shared {@link HttpRequest.Builder} <b>once,
742+
* at build time</b>. Any headers set here (e.g., {@code Authorization}) are
743+
* frozen into the template and copied to every subsequent request via
744+
* {@code requestBuilder.copy()}. They <b>cannot be updated</b> after the
745+
* transport is built.
746+
* <p>
747+
* For dynamic, per-request customization (e.g., OAuth token refresh), use
748+
* {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or
749+
* {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)}
750+
* instead.
742751
* @param requestCustomizer the consumer to customize the HTTP request builder
743752
* @return this builder
753+
* @deprecated Use
754+
* {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or
755+
* {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which
756+
* run on every request and support dynamic headers.
744757
*/
758+
@Deprecated
745759
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
746760
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
747761
requestCustomizer.accept(requestBuilder);

0 commit comments

Comments
 (0)