This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new ad904b836335 CAMEL-23474: camel-jbang-mcp - stop echoing input route
in camel_route_context response (#23384)
ad904b836335 is described below
commit ad904b836335bef84fdfe476fc60a2c09c45a5eb
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu May 21 10:26:01 2026 +0200
CAMEL-23474: camel-jbang-mcp - stop echoing input route in
camel_route_context response (#23384)
Remove the `route` field from `RouteContextResult`. The caller just
sent the route as input; echoing it back wastes LLM context-window
tokens, especially for multi-line YAML routes.
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
.../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 5 ++
.../dsl/jbang/core/commands/mcp/ExplainTools.java | 4 +-
.../jbang/core/commands/mcp/ExplainToolsTest.java | 89 ++++++++++++++++++++++
3 files changed, 96 insertions(+), 2 deletions(-)
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index a2845e96d083..698f970bc470 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -94,6 +94,11 @@ Use `--fresh` to force re-downloading from remote
repositories when needed.
==== camel-jbang-mcp
+The `camel_route_context` tool response no longer echoes the input route back
to the caller. The
+`route` field has been removed from `RouteContextResult`; the response now
contains only `format`,
+`components`, `eips`, and `summary`. This reduces token consumption for
callers passing large
+routes.
+
The `camel_catalog_component_doc` tool no longer returns every component
option by default. Two new
arguments make the response lean by default to reduce LLM context-window
pressure:
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainTools.java
index 66d0a027c516..db3b1bce230f 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainTools.java
@@ -89,7 +89,7 @@ public class ExplainTools {
RouteContextSummary summary = new
RouteContextSummary(components.size(), eips.size());
- return new RouteContextResult(resolvedFormat, route, components,
eips, summary);
+ return new RouteContextResult(resolvedFormat, components, eips,
summary);
} catch (ToolCallException e) {
throw e;
} catch (Throwable e) {
@@ -155,7 +155,7 @@ public class ExplainTools {
// Result records
public record RouteContextResult(
- String format, String route, List<RouteComponent> components,
+ String format, List<RouteComponent> components,
List<RouteEip> eips, RouteContextSummary summary) {
}
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainToolsTest.java
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainToolsTest.java
new file mode 100644
index 000000000000..dd4d39928e90
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ExplainToolsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.mcp;
+
+import java.lang.reflect.RecordComponent;
+import java.util.Arrays;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.quarkiverse.mcp.server.ToolCallException;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class ExplainToolsTest {
+
+ private ExplainTools createTools() {
+ CatalogService catalogService = new CatalogService();
+ catalogService.catalogRepos = Optional.empty();
+
+ ExplainTools tools = new ExplainTools();
+ tools.catalogService = catalogService;
+ return tools;
+ }
+
+ @Test
+ void resultDoesNotEchoInputRoute() throws Exception {
+ ExplainTools tools = createTools();
+ // Distinctive markers that would only appear if the input was echoed
back.
+ String marker = "MARKER-CAMEL-23474-payload";
+ String route = "- route:\n from:\n uri: timer:" + marker + "\n
steps:\n"
+ + " - log: '${body}'\n";
+
+ ExplainTools.RouteContextResult result
+ = tools.camel_route_context(route, "yaml", null, null, null);
+
+ // RouteContextResult must not carry a 'route' record component
(CAMEL-23474).
+
assertThat(Arrays.stream(ExplainTools.RouteContextResult.class.getRecordComponents())
+ .map(RecordComponent::getName))
+ .as("RouteContextResult must not echo input route")
+ .doesNotContain("route");
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ String json = mapper.writeValueAsString(result);
+
+ // Distinctive input markers must not appear in the response payload.
+ assertThat(json).doesNotContain(marker);
+ assertThat(json).contains("\"format\":\"yaml\"");
+ }
+
+ @Test
+ void blankRouteThrows() {
+ ExplainTools tools = createTools();
+
+ assertThatThrownBy(() -> tools.camel_route_context("", "yaml", null,
null, null))
+ .isInstanceOf(ToolCallException.class)
+ .hasMessageContaining("Route content is required");
+ }
+
+ @Test
+ void extractsKnownComponent() {
+ ExplainTools tools = createTools();
+ String route = "- route:\n from:\n uri: timer:tick\n
steps:\n - log: '${body}'\n";
+
+ ExplainTools.RouteContextResult result
+ = tools.camel_route_context(route, "yaml", null, null, null);
+
+ assertThat(result.components())
+ .as("timer component should be detected")
+ .anyMatch(c -> "timer".equals(c.name()));
+ }
+}