This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch worktree-happy-tickling-stream in repository https://gitbox.apache.org/repos/asf/camel.git
commit 068c80c2a32f10985e434c9f97e3ee803ac04717 Author: Claus Ibsen <[email protected]> AuthorDate: Fri Jun 5 22:01:35 2026 +0200 CAMEL-23672: TUI - Add tui_get_readme MCP tool for integration docs Allows AI agents to retrieve the README/documentation content from a running integration via the MCP protocol. Accepts an optional name parameter; defaults to the currently selected integration. Co-Authored-By: Claude <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 31 ++++++++++++++++++++++ .../dsl/jbang/core/commands/tui/TuiMcpServer.java | 24 +++++++++++++++++ 2 files changed, 55 insertions(+) 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 b156d2843b53..f7a36b6d47f9 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 @@ -2799,6 +2799,37 @@ public class CamelMonitor extends CamelCommand { .toList(); } + JsonObject getReadme(String name) { + List<IntegrationInfo> integrations = data.get(); + IntegrationInfo target = null; + if (name != null && !name.isEmpty()) { + for (IntegrationInfo info : integrations) { + if (!info.vanishing && name.equals(info.name)) { + target = info; + break; + } + } + } else { + target = ctx != null ? ctx.findSelectedIntegration() : null; + } + if (target == null) { + return null; + } + if (target.readmeFiles == null || target.readmeFiles.isEmpty()) { + return null; + } + try { + Path outputFile = ctx.getOutputFile(target.pid); + Files.deleteIfExists(outputFile); + JsonObject action = new JsonObject(); + action.put("action", "readme"); + PathUtils.writeTextSafely(action.toJson(), ctx.getActionFile(target.pid)); + return MonitorContext.pollJsonResponse(outputFile, 5000); + } catch (Exception e) { + return null; + } + } + int injectKeys(List<String> keys, int delayMs) { long fireAt = System.currentTimeMillis(); int count = 0; diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java index f97427bbd2f2..e0e90f8ed958 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java @@ -439,6 +439,13 @@ class TuiMcpServer { "If provided, forces the section on (true) or off (false). " + "If omitted, toggles the current state.")), List.of("section"))); + toolList.add(toolDef( + "tui_get_readme", + "Returns the README/documentation content from a running integration. " + + "Useful for understanding what the integration does, its configuration, and usage. " + + "If no name is provided, returns the README for the currently selected integration.", + Map.of("name", propDef("string", + "Integration name. If omitted, uses the currently selected integration.")))); JsonObject result = new JsonObject(); result.put("tools", toolList); @@ -484,6 +491,7 @@ class TuiMcpServer { case "tui_set_log_level" -> callSetLogLevel(args); case "tui_filter" -> callFilter(args); case "tui_toggle_trace_display" -> callToggleTraceDisplay(args); + case "tui_get_readme" -> callGetReadme(args); default -> { isError = true; yield "Unknown tool: " + toolName; @@ -1074,6 +1082,22 @@ class TuiMcpServer { return result; } + private String callGetReadme(Map<String, Object> args) { + String name = args.get("name") instanceof String s ? s : null; + JsonObject response = monitor.getReadme(name); + if (response == null) { + return name != null + ? "No README found for integration '" + name + "'" + : "No README found for the selected integration"; + } + JsonObject result = new JsonObject(); + String content = response.getString("content"); + String file = response.getStringOrDefault("file", "README"); + result.put("file", file); + result.put("content", content != null ? content : ""); + return Jsoner.serialize(result); + } + private static JsonArray toJsonArray(List<String> list) { JsonArray arr = new JsonArray(); arr.addAll(list);
