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()));
+    }
+}

Reply via email to