This is an automated email from the ASF dual-hosted git repository.

davsclaus 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 ff1f11035d17 camel-jbang - Add tui_get_processor_detail MCP tool
ff1f11035d17 is described below

commit ff1f11035d1754c845fec441989c280c514c4aa5
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 24 11:15:17 2026 +0200

    camel-jbang - Add tui_get_processor_detail MCP tool
    
    Add a new MCP tool to the TUI that exposes processor detail data
    (EIP configuration, options, catalog documentation) as structured JSON
    for AI agents. This is the programmatic equivalent of the Diagram tab's
    detail panel, making EIP and component configuration accessible to AI
    without parsing visual output.
    
    camel-jbang - Add tui_get_ai_log and tui_get_mcp_log MCP tools
    
    Expose the AI panel activity log and MCP server tool call log
    to external AI agents via MCP, so they can see what was already
    investigated and audit MCP interactions.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/dsl/jbang/core/commands/tui/AiPanel.java |  6 ++
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  |  2 +
 .../dsl/jbang/core/commands/tui/McpFacade.java     | 29 +++++++++
 .../jbang/core/commands/tui/TuiToolRegistry.java   | 73 +++++++++++++++++++++-
 4 files changed, 109 insertions(+), 1 deletion(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
index c2b26cff3c35..2cbf27d80bbe 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
@@ -1359,6 +1359,12 @@ class AiPanel {
         sb.append("- tui_get_errors: get error details with stack traces, 
WITHOUT navigating to the Errors tab\n");
         sb.append("- tui_get_diagram: view route diagrams as text, WITHOUT 
navigating to the Diagram tab\n");
         sb.append("- tui_get_topology: see how routes connect to each other, 
WITHOUT navigating to the Topology tab\n");
+        sb.append("- tui_get_processor_detail: get configured options for all 
processors in a route as structured JSON. ");
+        sb.append("USE THIS to explain what a route does, walk through each 
step, or understand EIP/component configuration. ");
+        sb.append("Set includeDocs=true to get catalog documentation for each 
option\n");
+        sb.append("- tui_catalog_doc: look up Camel catalog documentation for 
any component, EIP, data format, or language\n");
+        sb.append("- tui_get_ai_log: view the AI panel's own activity log 
(questions, tool calls, responses)\n");
+        sb.append("- tui_get_mcp_log: view the MCP server's tool call log 
(external client connections and requests)\n");
         sb.append("- tui_get_history: trace exchange processing steps, WITHOUT 
navigating to the History tab\n");
         sb.append("- tui_get_spans: OpenTelemetry span data, WITHOUT 
navigating to the Spans tab\n");
         sb.append("- tui_navigate: switch tabs, select integrations, select 
routes ");
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index 57bd47762717..7dc8be3d826c 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -476,12 +476,14 @@ public class CamelMonitor extends CamelCommand {
                     }
                 });
         aiPanel.setMcpFacade(mcpFacade);
+        mcpFacade.setAiActivityLog(aiPanel::getActivityLog);
         Path mcpJsonFile = null;
         actionsPopup.setAiActivityLog(aiPanel::getActivityLog);
         if (mcp) {
             mcpServer = new TuiMcpServer(mcpPort, mcpFacade);
             try {
                 mcpServer.start();
+                mcpFacade.setMcpActivityLog(mcpServer::getActivityLog, 
mcpServer::getToolCallCount);
                 actionsPopup.setMcpEnabled(true, mcpPort, 
mcpServer::getConnectedClient,
                         mcpServer::getActivityLog, 
mcpServer::getToolCallCount);
                 mcpJsonFile = writeMcpJson(mcpPort);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
index 044ee50c679b..90941b7fdedd 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Queue;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 
 import dev.tamboui.buffer.Buffer;
 import dev.tamboui.export.ExportRequest;
@@ -101,6 +102,10 @@ class McpFacade {
     private final Queue<PendingKey> pendingKeys;
     private final MonitorBridge bridge;
 
+    private volatile Supplier<List<AiPanel.LogEntry>> aiActivityLog;
+    private volatile Supplier<List<TuiMcpServer.LogEntry>> mcpActivityLog;
+    private volatile Supplier<Integer> mcpToolCallCount;
+
     McpFacade(
               MonitorContext ctx,
               AtomicReference<List<IntegrationInfo>> data,
@@ -130,6 +135,30 @@ class McpFacade {
         this.bridge = bridge;
     }
 
+    void setAiActivityLog(Supplier<List<AiPanel.LogEntry>> aiActivityLog) {
+        this.aiActivityLog = aiActivityLog;
+    }
+
+    void setMcpActivityLog(Supplier<List<TuiMcpServer.LogEntry>> 
mcpActivityLog, Supplier<Integer> mcpToolCallCount) {
+        this.mcpActivityLog = mcpActivityLog;
+        this.mcpToolCallCount = mcpToolCallCount;
+    }
+
+    List<AiPanel.LogEntry> getAiActivityLog() {
+        Supplier<List<AiPanel.LogEntry>> s = aiActivityLog;
+        return s != null ? s.get() : List.of();
+    }
+
+    List<TuiMcpServer.LogEntry> getMcpActivityLog() {
+        Supplier<List<TuiMcpServer.LogEntry>> s = mcpActivityLog;
+        return s != null ? s.get() : List.of();
+    }
+
+    int getMcpToolCallCount() {
+        Supplier<Integer> s = mcpToolCallCount;
+        return s != null ? s.get() : 0;
+    }
+
     // ---- Screen state ----
 
     Buffer getLastBuffer() {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiToolRegistry.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiToolRegistry.java
index eeffc94d43d5..5d6b5f9d77da 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiToolRegistry.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiToolRegistry.java
@@ -79,7 +79,7 @@ class TuiToolRegistry {
     }
 
     /**
-     * Returns all 40 tool definitions. The result is cached since it is 
immutable.
+     * Returns all 42 tool definitions. The result is cached since it is 
immutable.
      */
     List<ToolDef> getToolDefinitions() {
         List<ToolDef> tools = cachedTools;
@@ -137,6 +137,8 @@ class TuiToolRegistry {
             case "tui_animate_status" -> callAnimateStatus(args);
             case "tui_catalog_doc" -> callCatalogDoc(args);
             case "tui_get_processor_detail" -> callGetProcessorDetail(args);
+            case "tui_get_ai_log" -> callGetAiLog(args);
+            case "tui_get_mcp_log" -> callGetMcpLog(args);
             case "tui_list_examples" -> callListExamples(args);
             case "tui_run_example" -> callRunExample(args);
             default -> throw new IllegalArgumentException("Unknown tool: " + 
name);
@@ -591,6 +593,25 @@ class TuiToolRegistry {
                                 "If true, enrich each processor's options with 
documentation from the Camel catalog "
                                                           + "(description, 
type, group, defaultValue, required, deprecated, enum values)")))));
 
+        // --- AI and MCP log tools ---
+
+        tools.add(toToolDef(toolDef(
+                "tui_get_ai_log",
+                "Returns the TUI's built-in AI panel activity log as 
structured JSON. "
+                                  + "Shows the AI panel's questions, tool 
calls, tool results, responses, and errors. "
+                                  + "Useful to see what the built-in AI has 
already investigated "
+                                  + "before repeating the same work.",
+                Map.of("limit", propDef("integer",
+                        "Maximum number of entries to return (default 
50)")))));
+
+        tools.add(toToolDef(toolDef(
+                "tui_get_mcp_log",
+                "Returns the TUI MCP server's tool call log as structured 
JSON. "
+                                   + "Shows external MCP client connections 
and tool call requests/responses. "
+                                   + "Useful for debugging and auditing MCP 
interactions.",
+                Map.of("limit", propDef("integer",
+                        "Maximum number of entries to return (default 
50)")))));
+
         // --- Example tools ---
 
         tools.add(toToolDef(toolDef(
@@ -2037,6 +2058,56 @@ class TuiToolRegistry {
         return doc;
     }
 
+    private String callGetAiLog(Map<String, Object> args) {
+        int limit = args.get("limit") instanceof Number n ? n.intValue() : 50;
+        List<AiPanel.LogEntry> entries = facade.getAiActivityLog();
+        if (entries.size() > limit) {
+            entries = entries.subList(entries.size() - limit, entries.size());
+        }
+        JsonArray arr = new JsonArray();
+        for (AiPanel.LogEntry e : entries) {
+            JsonObject obj = new JsonObject();
+            obj.put("timestamp", e.timestamp());
+            obj.put("level", e.level().name());
+            obj.put("message", e.message());
+            if (e.detail() != null) {
+                obj.put("detail", e.detail());
+            }
+            arr.add(obj);
+        }
+        JsonObject result = new JsonObject();
+        result.put("entries", arr);
+        result.put("count", arr.size());
+        return result.toJson();
+    }
+
+    private String callGetMcpLog(Map<String, Object> args) {
+        int limit = args.get("limit") instanceof Number n ? n.intValue() : 50;
+        List<TuiMcpServer.LogEntry> entries = facade.getMcpActivityLog();
+        if (entries.size() > limit) {
+            entries = entries.subList(entries.size() - limit, entries.size());
+        }
+        JsonArray arr = new JsonArray();
+        for (TuiMcpServer.LogEntry e : entries) {
+            JsonObject obj = new JsonObject();
+            obj.put("timestamp", e.timestamp());
+            obj.put("level", e.level().name());
+            obj.put("message", e.message());
+            if (e.requestBody() != null) {
+                obj.put("requestBody", e.requestBody());
+            }
+            if (e.responseBody() != null) {
+                obj.put("responseBody", e.responseBody());
+            }
+            arr.add(obj);
+        }
+        JsonObject result = new JsonObject();
+        result.put("entries", arr);
+        result.put("count", arr.size());
+        result.put("toolCallCount", facade.getMcpToolCallCount());
+        return result.toJson();
+    }
+
     @SuppressWarnings("unchecked")
     private String callListExamples(Map<String, Object> args) {
         List<JsonObject> catalog = exampleCatalog;

Reply via email to