This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 837bd31655 fix(mcp): use complete tool-input URLs as the request
target (#7430)
837bd31655 is described below
commit 837bd3165577551584a61a85e2616f46fc8de430
Author: Sean-Walker0 <[email protected]>
AuthorDate: Tue Oct 6 10:36:44 2026 +0800
fix(mcp): use complete tool-input URLs as the request target (#7430)
RequestConfigHelper#buildPath can return a complete URL taken from the
tool input arguments, but ShenyuToolCallback#setTargetUri always
prefixed the gateway request scheme and authority onto the built path.
A tool input URL like https://target.example/api was rewritten into a
malformed target such as
http://gateway.example:9195https://target.example/api,
so tool calls that rely on complete URLs could never reach their
backend.
When the built path is itself an absolute http(s) URL, set it as the
request target unchanged; relative paths keep the gateway-origin
prefix. Regression tests cover both directions (red on the previous
code, which produced the corrupted gateway URL).
Fixes #6472
Co-authored-by: Sean-Walker0
<[email protected]>
---
.../mcp/server/callback/ShenyuToolCallback.java | 6 ++++++
.../server/callback/ShenyuToolCallbackTest.java | 23 ++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java
index 524da0a726..aa1bd65707 100644
---
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java
+++
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java
@@ -597,6 +597,12 @@ public class ShenyuToolCallback implements ToolCallback {
final ServerWebExchange originExchange,
final String path) {
try {
+ if (path.startsWith("http://") || path.startsWith("https://")) {
+ // RequestConfigHelper#buildPath can return a complete URL
from the tool input;
+ // prefixing the gateway origin would corrupt it
+ requestBuilder.uri(new URI(path));
+ return;
+ }
final URI oldUri = originExchange.getRequest().getURI();
final String newUriStr = oldUri.getScheme() + "://" +
oldUri.getAuthority() + path;
requestBuilder.uri(new URI(newUriStr));
diff --git
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallbackTest.java
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallbackTest.java
index 4a4b079582..856caa704c 100644
---
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallbackTest.java
+++
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallbackTest.java
@@ -43,6 +43,7 @@ import
org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
+import java.net.URI;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -304,6 +305,28 @@ class ShenyuToolCallbackTest {
exchangeHolderMock.verify(() ->
ShenyuMcpExchangeHolder.get("legacy-session"));
}
+ @Test
+ void testSetTargetUriUsesCompleteUrlAsIs() {
+ shenyuToolCallback = new ShenyuToolCallback(toolDefinition);
+ ServerHttpRequest.Builder builder =
MockServerHttpRequest.get("http://gateway.example:9195/mcp").build().mutate();
+
+ ReflectionTestUtils.invokeMethod(shenyuToolCallback, "setTargetUri",
builder, exchange, "https://target.example/api");
+
+ assertEquals(URI.create("https://target.example/api"),
builder.build().getURI());
+ }
+
+ @Test
+ void testSetTargetUriPrefixesGatewayOriginForRelativePath() {
+ shenyuToolCallback = new ShenyuToolCallback(toolDefinition);
+ when(exchange.getRequest()).thenReturn(request);
+
when(request.getURI()).thenReturn(URI.create("http://gateway.example:9195/mcp"));
+ ServerHttpRequest.Builder builder =
MockServerHttpRequest.get("http://gateway.example:9195/mcp").build().mutate();
+
+ ReflectionTestUtils.invokeMethod(shenyuToolCallback, "setTargetUri",
builder, exchange, "/api/order");
+
+ assertEquals(URI.create("http://gateway.example:9195/api/order"),
builder.build().getURI());
+ }
+
@Test
void testConstructorWithValidToolDefinition() {
ShenyuToolCallback callback = new ShenyuToolCallback(toolDefinition);