From 5b330b02b91a799f0ca85a99a13e05d3fd1f9cfc Mon Sep 17 00:00:00 2001 From: gyeo009 Date: Fri, 13 Feb 2026 21:47:07 +0900 Subject: [PATCH 1/4] 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 --- .../transport/HttpClientSseClientTransport.java | 16 +++++++++++++++- .../HttpClientStreamableHttpTransport.java | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java index be4e4cf97..679415e17 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java @@ -241,10 +241,24 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { } /** - * Customizes the HTTP client builder. + * Applies the given consumer to the shared {@link HttpRequest.Builder} once, + * at build time. Any headers set here (e.g., {@code Authorization}) are + * frozen into the template and copied to every subsequent request via + * {@code requestBuilder.copy()}. They cannot be updated after the + * transport is built. + *

+ * For dynamic, per-request customization (e.g., OAuth token refresh), use + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} + * instead. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder + * @deprecated Use + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which + * run on every request and support dynamic headers. */ + @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) { Assert.notNull(requestCustomizer, "requestCustomizer must not be null"); requestCustomizer.accept(requestBuilder); diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java index 57a27a3fd..a76ba89b0 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java @@ -738,10 +738,24 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { } /** - * Customizes the HTTP client builder. + * Applies the given consumer to the shared {@link HttpRequest.Builder} once, + * at build time. Any headers set here (e.g., {@code Authorization}) are + * frozen into the template and copied to every subsequent request via + * {@code requestBuilder.copy()}. They cannot be updated after the + * transport is built. + *

+ * For dynamic, per-request customization (e.g., OAuth token refresh), use + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} + * instead. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder + * @deprecated Use + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which + * run on every request and support dynamic headers. */ + @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) { Assert.notNull(requestCustomizer, "requestCustomizer must not be null"); requestCustomizer.accept(requestBuilder); From a572d8241207cf25cc73489f6246a48d6a9b07c6 Mon Sep 17 00:00:00 2001 From: gyeo009 Date: Sat, 14 Mar 2026 21:45:19 +0900 Subject: [PATCH 2/4] Add requestBuilder() reference to @deprecated Javadoc of customizeRequest() --- .../client/transport/HttpClientSseClientTransport.java | 6 +++--- .../client/transport/HttpClientStreamableHttpTransport.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java index 679415e17..5be12a795 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java @@ -254,9 +254,9 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder * @deprecated Use - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which - * run on every request and support dynamic headers. + * {@link #requestBuilder(HttpRequest.Builder)} for stable headers, or + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} / + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for dynamic per-request customization. */ @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) { diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java index a76ba89b0..5c8187e3b 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java @@ -751,9 +751,9 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder * @deprecated Use - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} which - * run on every request and support dynamic headers. + * {@link #requestBuilder(HttpRequest.Builder)} for stable headers, or + * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} / + * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for dynamic per-request customization. */ @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) { From 3a5f964e0b9a3dfd08406bdf8bc7986dff317e32 Mon Sep 17 00:00:00 2001 From: gyeo009 Date: Sat, 14 Mar 2026 21:54:28 +0900 Subject: [PATCH 3/4] Simplify customizeRequest() Javadoc body --- .../transport/HttpClientSseClientTransport.java | 11 ++--------- .../transport/HttpClientStreamableHttpTransport.java | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java index 5be12a795..1bfbfd5d3 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java @@ -242,15 +242,8 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { /** * Applies the given consumer to the shared {@link HttpRequest.Builder} once, - * at build time. Any headers set here (e.g., {@code Authorization}) are - * frozen into the template and copied to every subsequent request via - * {@code requestBuilder.copy()}. They cannot be updated after the - * transport is built. - *

- * For dynamic, per-request customization (e.g., OAuth token refresh), use - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} - * instead. + * at build time. Any headers set here are frozen into the template and + * cannot be updated after the transport is built. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder * @deprecated Use diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java index 5c8187e3b..8947b38f6 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java @@ -739,15 +739,8 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { /** * Applies the given consumer to the shared {@link HttpRequest.Builder} once, - * at build time. Any headers set here (e.g., {@code Authorization}) are - * frozen into the template and copied to every subsequent request via - * {@code requestBuilder.copy()}. They cannot be updated after the - * transport is built. - *

- * For dynamic, per-request customization (e.g., OAuth token refresh), use - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} or - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} - * instead. + * at build time. Any headers set here are frozen into the template and + * cannot be updated after the transport is built. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder * @deprecated Use From ec6393bdf03b4d80d4a31bd237d52ea85591dc4f Mon Sep 17 00:00:00 2001 From: Daniel Garnier-Moiroux Date: Thu, 2 Apr 2026 11:04:57 +0200 Subject: [PATCH 4/4] spring-javaformat Signed-off-by: Daniel Garnier-Moiroux --- .../client/transport/HttpClientSseClientTransport.java | 8 ++++---- .../transport/HttpClientStreamableHttpTransport.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java index 1bfbfd5d3..48bd2f416 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientSseClientTransport.java @@ -246,10 +246,10 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { * cannot be updated after the transport is built. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder - * @deprecated Use - * {@link #requestBuilder(HttpRequest.Builder)} for stable headers, or - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} / - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for dynamic per-request customization. + * @deprecated Use {@link #requestBuilder(HttpRequest.Builder)} for stable + * headers, or {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} + * / {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for + * dynamic per-request customization. */ @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) { diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java index 8947b38f6..9e9b7f923 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java @@ -743,10 +743,10 @@ public Builder requestBuilder(HttpRequest.Builder requestBuilder) { * cannot be updated after the transport is built. * @param requestCustomizer the consumer to customize the HTTP request builder * @return this builder - * @deprecated Use - * {@link #requestBuilder(HttpRequest.Builder)} for stable headers, or - * {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} / - * {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for dynamic per-request customization. + * @deprecated Use {@link #requestBuilder(HttpRequest.Builder)} for stable + * headers, or {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)} + * / {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for + * dynamic per-request customization. */ @Deprecated public Builder customizeRequest(final Consumer requestCustomizer) {