Repository navigation
Expose configured HTTP routes as Agent Gateway tools - #7572
Conversation
Aias00
left a comment
There was a problem hiding this comment.
Approve. This opt-in mcp.httpTools feature exposes fixed, configured gateway HTTP routes as MCP tools, and the implementation holds the security bar set by the neighboring Agent Gateway work.
What I verified in the diff:
- Fixed routes only.
AgentGatewayHttpToolConfig.Tool.requestPathbuilds the target from a validatedpathmatched by/[A-Za-z0-9_/-]+(no//); the caller's JSON can only populatequery/bodyviaargsPosition, andrequestPathre-validates and URL-encodes values — the path itself can never be replaced by caller input.methodis restricted toGET/POST, andGETcannot map a body. - No caller identity delegation.
AgentHttpToolExecutorbuilds aChildExchange/ToolRequestwith empty headers, empty cookies,nullSslInfo, andgetSession()/getPrincipal()return empty/error — caller credentials, cookies and web sessions are deliberately not forwarded. The internal-only markersHTTP_TOOL_CALL_ATTRIBUTE/MCP_TOOL_CALLare set so the existing MCP Server plugin routes it as an internal call. - Reuses the existing chain.
chain.fork().execute(child)runs the request through the normal plugin chain, so existing MCP authorization, filtering and terminal metrics still apply. - Bounded, validated response.
CapturedResponseenforcesmaxResponseBytes, rejects any response cookies (no session fixation), requires a UTF-8 JSON body, and parses with strict duplicate-key detection and a nesting-depth/string-length cap. Non-2xx completes are rejected. - Bounded config parsing. Tool count ≤16, properties ≤16, name/field/value length caps, closed
additionalProperties, and strict scalar types — consistent with the rest of the Agent Gateway config hardening. - Tests cover valid/invalid plan validation and the executor's isolated dispatch.
Non-blocking note: the rewrite also touches ShenyuPluginChain.fork() and ShenyuWebHandler to support the internal marker; please keep the integration/e2e Agent Gateway CI green so the fork() contract stays verified.
Aias00
left a comment
There was a problem hiding this comment.
Summary
Fresh review of the current head d80bda94e61ad6fbe2cf145b120b77a01525200a (open, not draft, author BobSong-dev). The change exposes configured gateway HTTP routes as Agent Gateway tools via opt-in mcp.httpTools, without a Java Provider per tool.
What the change does
AgentGatewayHttpToolConfig(new,shenyu-common/.../dto/AgentGatewayHttpToolConfig.java) parses and freezes bounded plans.parse(AgentGatewayHttpToolConfig.java:107) rejects foreign names (:118), caps tool count at 16 (:112), andTool's constructor validates the fixed relative path/[A-Za-z0-9_/-]+with no//(:228), restricts methods toGET/POST, forbidsbodymapping onGET(:238), and requires the argsPosition key set to equal the schema property set (:232).getInputSchemareturns a deep copy (:254).AgentGatewayMcpConfigaddshttpToolsto the accepted field set and parses it againstallowedTools(AgentGatewayMcpConfig.java:64).AgentHttpToolExecutor(new) dispatches throughchain.fork()with a fresh request-local cursor (AgentHttpToolExecutor.java:149), replays the configured route with private empty headers/body/cookies and no principal/session (:918–:979), captures a bounded response (CapturedResponsejoin capped atmaxResponseBytes,:1098), and refuses non-2xx, cookies, absent completion and non-UTF-8/non-JSON bodies (:1115–:1142). Request budget is enforced on both body and generated path (:908–:914).AgentHttpToolProviderreuses the existing authorization/result-filter path and maps deadline timeouts to a typed marker (AgentHttpToolProvider.java:60);AgentMcpDispatcherbinds the captured providers per request and maps the deadline marker to HTTP 504 / JSON-RPC -32025 (AgentMcpDispatcher.java:83,:99).ShenyuPluginChain.fork()default throwsUnsupportedOperationException(source/binary-safe default), implemented inShenyuWebHandler.DefaultShenyuPluginChain.fork()atShenyuWebHandler.java:298.AgentGatewayPlugin.skip()(AgentGatewayPlugin.java:130) short-circuits the internal child dispatch viaHTTP_TOOL_CALL_ATTRIBUTE, and the child also sets the existingMCP_TOOL_CALLmarker (AgentHttpToolExecutor.java:142) consumed byMcpServerPlugin(McpServerPlugin.java:206).
Verification
- Compared against
mastervia the GitHub contents API:ShenyuPluginChainon master has nofork(); the head adds a throwing default, so existing implementers are unaffected.AgentMcpDispatcher/AgentGatewayPluginpre-change signatures confirmed. - Local:
mvn -pl shenyu-common,shenyu-plugin/shenyu-plugin-agent-gateway -am test→ BUILD SUCCESS.AgentGatewayHttpToolConfigTest21/21,AgentGatewayMcpConfigTest28/28, agent-gateway module 512/512 (incl.AgentHttpToolRoutingTest11,AgentHttpToolExecutorTest23,AgentHttpToolNamespaceTest2), shenyu-web 93/93. Zero failures/errors/skips. - CI: all relevant checks green —
pr_build,Analyze (java),check-license-header,rat_check,scope,sql-matrix,registry_dependencies,agent_gateway_migrations, and everybuild (shenyu-integrated-test-*)ande2e-case/e2e-storage. No red to attribute.
Notes (non-blocking)
fork()is a new SPI onShenyuPluginChain; custom chains that do not implement it fail closed for internal HTTP invocation only (AgentHttpToolExecutorTest.customChainsMustOptIntoForking), leaving ordinary traffic unchanged. Adding it as a documented, deliberate extension point is reasonable.shenyu-webis added as atest-scope dependency of the agent-gateway module only; no production dependency is introduced.
Conclusion
APPROVE. Correctness, isolation and bounded-input handling are well covered by tests, the change is opt-in with previous behavior preserved when httpTools is absent, and CI plus local module tests pass.
Aias00
left a comment
There was a problem hiding this comment.
Re-approving after the master merge dismissed the previous approval.
I checked the update rather than re-reading the whole PR: the only new commit is a merge of master, and every file this PR introduces is byte-identical to the version I approved (compared the blob shas at 71fe4acf/d80bda94/c831b431/58f16918 against the current head). The files that did change are the ones master touched in parallel — RELEASE-NOTES.md, the other agent-gateway sources, and AbstractShenyuPluginTest's setLogged rename — i.e. the merge brought them in, it did not rewrite this PR's content.
CI is green on the new head (52 pass / 3 skipping, no failures). No further changes requested from me.
Background
Agent Gateway supports Java tool providers and remote MCP servers, but exposing an ordinary HTTP service currently requires a custom provider or a separate MCP server. This adds deployment work for services that already have ShenYu HTTP routes.
This change exposes configured HTTP routes through the existing tools-only MCP entry point. It follows the MCP Server plugin's requestTemplate/argsPosition vocabulary and routing approach without reusing its blocking callback or shared session exchange.
Changes
mcp.httpToolsdefinitions, validated by both Admin and the gateway. Initial support is fixed relative paths, GET query parameters and POST query/flat scalar JSON-body parameters; caller-selected destinations are refused;Verification
clean verifyfor Admin, Agent Gateway starter, Metrics and Web with required reactor dependencies: 688 tests / 40 suites, zero failures/errors/skips; Checkstyle and RAT passed in 46 modules. The tested snapshot is based on master4835f40f8/ Gson 2.13.2; its Git tree matches this commit exactly;2dff2730f: Windows 688 tests and RISC-V/QEMUverify626 tests / 37 suites, zero failures/errors/skips. Linux Checkstyle/RAT passed in 15 modules; all 4,442 frozen source files matched;