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 5dd6eb139fe1 CAMEL-23831: Add AI and MCP checks to doctor and widen
run dialog in camel-tui
5dd6eb139fe1 is described below
commit 5dd6eb139fe15f901c5a152daa83efa591407470
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 3 20:00:15 2026 +0200
CAMEL-23831: Add AI and MCP checks to doctor and widen run dialog in
camel-tui
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../dsl/jbang/core/commands/tui/ActionsPopup.java | 1 +
.../dsl/jbang/core/commands/tui/DoctorPopup.java | 74 ++++++++++++++++++++++
.../jbang/core/commands/tui/RunOptionsForm.java | 2 +-
3 files changed, 76 insertions(+), 1 deletion(-)
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
index 5f5373b39c45..e1f250978d17 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
@@ -244,6 +244,7 @@ class ActionsPopup {
this.mcpActivityLog = activityLog;
mcpLogPopup.setActivityLog(activityLog);
mcpLogPopup.setToolCallCount(toolCallCount);
+ doctorPopup.setMcpState(enabled, port, connectedClient);
}
void setAiActivityLog(Supplier<List<AiPanel.LogEntry>> activityLog) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java
index 6678a4298e93..6a668ec00de6 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java
@@ -22,6 +22,7 @@ import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.function.Supplier;
import dev.tamboui.layout.Rect;
import dev.tamboui.style.Style;
@@ -47,11 +48,20 @@ class DoctorPopup {
private boolean visible;
private List<Line> lines;
+ private boolean mcpEnabled;
+ private int mcpPort;
+ private Supplier<String> mcpConnectedClient;
boolean isVisible() {
return visible;
}
+ void setMcpState(boolean enabled, int port, Supplier<String>
connectedClient) {
+ this.mcpEnabled = enabled;
+ this.mcpPort = port;
+ this.mcpConnectedClient = connectedClient;
+ }
+
void open() {
lines = new ArrayList<>();
checkJava(lines);
@@ -61,6 +71,8 @@ class DoctorPopup {
checkContainerRuntime(lines);
checkCommonPorts(lines);
checkDiskSpace(lines);
+ checkAiProvider(lines);
+ checkMcpConnection(lines);
visible = true;
}
@@ -260,6 +272,68 @@ class DoctorPopup {
}
}
+ private static boolean envSet(String name) {
+ String v = System.getenv(name);
+ return v != null && !v.isBlank();
+ }
+
+ private void checkAiProvider(List<Line> result) {
+ String provider = null;
+ if (envSet("ANTHROPIC_API_KEY")) {
+ provider = "Anthropic";
+ } else if (envSet("CLOUD_ML_REGION") &&
envSet("ANTHROPIC_VERTEX_PROJECT_ID")) {
+ provider = "Vertex AI";
+ } else if (envSet("OPENAI_API_KEY")) {
+ provider = "OpenAI";
+ } else if (envSet("LLM_API_KEY")) {
+ provider = "Custom (LLM_API_KEY)";
+ }
+ if (provider != null) {
+ result.add(Line.from(
+ Span.raw(" 🤖 "),
+ Span.styled(String.format("%-14s", "AI"),
Style.EMPTY.bold()),
+ Span.raw(String.format("%-30s", provider)),
+ Span.raw(" ✅")));
+ } else {
+ result.add(Line.from(
+ Span.raw(" 🤖 "),
+ Span.styled(String.format("%-14s", "AI"),
Style.EMPTY.bold()),
+ Span.raw(String.format("%-30s", "No API key configured")),
+ Span.raw(" ⚠️")));
+ result.add(Line.from(Span.styled(" Set
ANTHROPIC_API_KEY or OPENAI_API_KEY",
+ Style.EMPTY.dim())));
+ }
+ }
+
+ private void checkMcpConnection(List<Line> result) {
+ if (mcpEnabled) {
+ String client = mcpConnectedClient != null ?
mcpConnectedClient.get() : null;
+ if (client != null) {
+ result.add(Line.from(
+ Span.raw(" 🔗 "),
+ Span.styled(String.format("%-14s", "MCP"),
Style.EMPTY.bold()),
+ Span.raw(String.format("%-30s", client + " (port " +
mcpPort + ")")),
+ Span.raw(" ✅")));
+ } else {
+ result.add(Line.from(
+ Span.raw(" 🔗 "),
+ Span.styled(String.format("%-14s", "MCP"),
Style.EMPTY.bold()),
+ Span.raw(String.format("%-30s", "Listening on port " +
mcpPort)),
+ Span.raw(" ⚠️")));
+ result.add(Line.from(Span.styled(" No AI
client connected",
+ Style.EMPTY.dim())));
+ }
+ } else {
+ result.add(Line.from(
+ Span.raw(" 🔗 "),
+ Span.styled(String.format("%-14s", "MCP"),
Style.EMPTY.bold()),
+ Span.raw(String.format("%-30s", "Not enabled")),
+ Span.raw(" ⚠️")));
+ result.add(Line.from(Span.styled(" Use --mcp to
enable MCP server",
+ Style.EMPTY.dim())));
+ }
+ }
+
private void checkDiskSpace(List<Line> result) {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
long free = tmpDir.getFreeSpace();
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
index 77e395313c09..44638e58de83 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
@@ -474,7 +474,7 @@ class RunOptionsForm {
// ---- Rendering ----
private void renderOptionsPage(Frame frame, Rect area) {
- int popupW = Math.min(64, area.width() - 4);
+ int popupW = Math.min(68, area.width() - 4);
int popupH = errorMessage != null ? 18 : 17;
int x = area.left() + Math.max(0, (area.width() - popupW) / 2);
int y = area.top() + Math.max(0, (area.height() - popupH) / 4);