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

acosentino pushed a commit to branch 23011
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 445777b5cc648662d0957d5f4d1c789a0008865c
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Feb 16 13:17:04 2026 +0100

    CAMEL-23011 - camel-mcp - camel_catalog_components returns Internal Server 
Error and in general make tools robust
    
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../dsl/jbang/core/commands/mcp/CatalogTools.java  |  95 ++++++++++-----
 .../dsl/jbang/core/commands/mcp/ExplainTools.java  |  97 ++++++++-------
 .../dsl/jbang/core/commands/mcp/HardenTools.java   |  97 ++++++++-------
 .../dsl/jbang/core/commands/mcp/KameletTools.java  |  10 +-
 .../jbang/core/commands/mcp/TransformTools.java    | 131 +++++++++++----------
 .../dsl/jbang/core/commands/mcp/VersionTools.java  |  12 +-
 6 files changed, 253 insertions(+), 189 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogTools.java
index 374e8028bcbf..983d1e8da63c 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogTools.java
@@ -74,8 +74,11 @@ public class CatalogTools {
                     .collect(Collectors.toList());
 
             return new ComponentListResult(components.size(), 
cat.getCatalogVersion(), components);
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list components: " + 
e.getMessage(), e);
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list components (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
     }
 
@@ -103,8 +106,9 @@ public class CatalogTools {
             return toComponentDetailResult(model);
         } catch (ToolCallException e) {
             throw e;
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to get component doc: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Component not found: " + component + " (" + 
e.getClass().getName() + "): " + e.getMessage(), null);
         }
     }
 
@@ -129,8 +133,9 @@ public class CatalogTools {
                     .collect(Collectors.toList());
 
             return new DataFormatListResult(dataFormats.size(), dataFormats);
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list data formats: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list data formats (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
     }
 
@@ -151,8 +156,9 @@ public class CatalogTools {
                     .collect(Collectors.toList());
 
             return new LanguageListResult(languages.size(), languages);
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list languages: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list languages (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
     }
 
@@ -168,12 +174,20 @@ public class CatalogTools {
             throw new ToolCallException("Data format name is required", null);
         }
 
-        DataFormatModel model = catalog.dataFormatModel(dataformat);
-        if (model == null) {
-            throw new ToolCallException("Data format not found: " + 
dataformat, null);
-        }
+        try {
+            DataFormatModel model = catalog.dataFormatModel(dataformat);
+            if (model == null) {
+                throw new ToolCallException("Data format not found: " + 
dataformat, null);
+            }
 
-        return toDataFormatDetailResult(model);
+            return toDataFormatDetailResult(model);
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Data format not found: " + dataformat + " (" + 
e.getClass().getName() + "): " + e.getMessage(),
+                    null);
+        }
     }
 
     /**
@@ -188,12 +202,19 @@ public class CatalogTools {
             throw new ToolCallException("Language name is required", null);
         }
 
-        LanguageModel model = catalog.languageModel(language);
-        if (model == null) {
-            throw new ToolCallException("Language not found: " + language, 
null);
-        }
+        try {
+            LanguageModel model = catalog.languageModel(language);
+            if (model == null) {
+                throw new ToolCallException("Language not found: " + language, 
null);
+            }
 
-        return toLanguageDetailResult(model);
+            return toLanguageDetailResult(model);
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Language not found: " + language + " (" + 
e.getClass().getName() + "): " + e.getMessage(), null);
+        }
     }
 
     /**
@@ -215,8 +236,9 @@ public class CatalogTools {
                     .collect(Collectors.toList());
 
             return new EipListResult(eips.size(), eips);
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list EIPs: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list EIPs (" + e.getClass().getName() + "): " + 
e.getMessage(), null);
         }
     }
 
@@ -231,12 +253,19 @@ public class CatalogTools {
             throw new ToolCallException("EIP name is required", null);
         }
 
-        EipModel model = catalog.eipModel(eip);
-        if (model == null) {
-            throw new ToolCallException("EIP not found: " + eip, null);
-        }
+        try {
+            EipModel model = catalog.eipModel(eip);
+            if (model == null) {
+                throw new ToolCallException("EIP not found: " + eip, null);
+            }
 
-        return toEipDetailResult(model);
+            return toEipDetailResult(model);
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "EIP not found: " + eip + " (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
+        }
     }
 
     // Catalog loading
@@ -255,11 +284,7 @@ public class CatalogTools {
         }
 
         // No specific version, use runtime-specific catalog or default
-        if (runtime == null || runtime.isBlank() || 
"main".equalsIgnoreCase(runtime)) {
-            return catalog;
-        }
-
-        RuntimeType runtimeType = RuntimeType.fromValue(runtime);
+        RuntimeType runtimeType = resolveRuntime(runtime);
         if (runtimeType == RuntimeType.springBoot) {
             return CatalogLoader.loadSpringBootCatalog(null, null, true);
         } else if (runtimeType == RuntimeType.quarkus) {
@@ -273,11 +298,19 @@ public class CatalogTools {
         if (runtime == null || runtime.isBlank() || 
"main".equalsIgnoreCase(runtime)) {
             return RuntimeType.main;
         }
-        return RuntimeType.fromValue(runtime);
+        try {
+            return RuntimeType.fromValue(runtime);
+        } catch (IllegalArgumentException e) {
+            throw new ToolCallException(
+                    "Unsupported runtime: " + runtime + ". Supported values 
are: main, spring-boot, quarkus", null);
+        }
     }
 
     private static List<String> findComponentNames(CamelCatalog catalog) {
         List<String> answer = catalog.findComponentNames();
+        if (answer == null) {
+            return new ArrayList<>();
+        }
         List<String> copy = new ArrayList<>(answer);
         copy.removeIf(String::isBlank);
         return copy;
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 6e24a7da9d13..49e63fc2b345 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
@@ -61,54 +61,61 @@ public class ExplainTools {
             throw new ToolCallException("Route content is required", null);
         }
 
-        String resolvedFormat = format != null && !format.isBlank() ? 
format.toLowerCase() : "yaml";
-
-        JsonObject result = new JsonObject();
-        result.put("format", resolvedFormat);
-        result.put("route", route);
-
-        // Extract and document components
-        List<String> componentNames = extractComponents(route);
-        JsonArray components = new JsonArray();
-        for (String comp : componentNames) {
-            ComponentModel model = catalog.componentModel(comp);
-            if (model != null) {
-                JsonObject compJson = new JsonObject();
-                compJson.put("name", comp);
-                compJson.put("title", model.getTitle());
-                compJson.put("description", model.getDescription());
-                compJson.put("label", model.getLabel());
-                compJson.put("syntax", model.getSyntax());
-                compJson.put("producerOnly", model.isProducerOnly());
-                compJson.put("consumerOnly", model.isConsumerOnly());
-                components.add(compJson);
+        try {
+            String resolvedFormat = format != null && !format.isBlank() ? 
format.toLowerCase() : "yaml";
+
+            JsonObject result = new JsonObject();
+            result.put("format", resolvedFormat);
+            result.put("route", route);
+
+            // Extract and document components
+            List<String> componentNames = extractComponents(route);
+            JsonArray components = new JsonArray();
+            for (String comp : componentNames) {
+                ComponentModel model = catalog.componentModel(comp);
+                if (model != null) {
+                    JsonObject compJson = new JsonObject();
+                    compJson.put("name", comp);
+                    compJson.put("title", model.getTitle());
+                    compJson.put("description", model.getDescription());
+                    compJson.put("label", model.getLabel());
+                    compJson.put("syntax", model.getSyntax());
+                    compJson.put("producerOnly", model.isProducerOnly());
+                    compJson.put("consumerOnly", model.isConsumerOnly());
+                    components.add(compJson);
+                }
             }
-        }
-        result.put("components", components);
-
-        // Extract and document EIPs
-        List<String> eipNames = extractEips(route);
-        JsonArray eips = new JsonArray();
-        for (String eip : eipNames) {
-            EipModel model = catalog.eipModel(eip);
-            if (model != null) {
-                JsonObject eipJson = new JsonObject();
-                eipJson.put("name", eip);
-                eipJson.put("title", model.getTitle());
-                eipJson.put("description", model.getDescription());
-                eipJson.put("label", model.getLabel());
-                eips.add(eipJson);
+            result.put("components", components);
+
+            // Extract and document EIPs
+            List<String> eipNames = extractEips(route);
+            JsonArray eips = new JsonArray();
+            for (String eip : eipNames) {
+                EipModel model = catalog.eipModel(eip);
+                if (model != null) {
+                    JsonObject eipJson = new JsonObject();
+                    eipJson.put("name", eip);
+                    eipJson.put("title", model.getTitle());
+                    eipJson.put("description", model.getDescription());
+                    eipJson.put("label", model.getLabel());
+                    eips.add(eipJson);
+                }
             }
+            result.put("eips", eips);
+
+            // Add summary counts
+            JsonObject summary = new JsonObject();
+            summary.put("componentCount", components.size());
+            summary.put("eipCount", eips.size());
+            result.put("summary", summary);
+
+            return result.toJson();
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to get route context (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
-        result.put("eips", eips);
-
-        // Add summary counts
-        JsonObject summary = new JsonObject();
-        summary.put("componentCount", components.size());
-        summary.put("eipCount", eips.size());
-        result.put("summary", summary);
-
-        return result.toJson();
     }
 
     /**
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java
index fcf59714c837..6202a5e0e3aa 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java
@@ -64,55 +64,62 @@ public class HardenTools {
             throw new ToolCallException("Route content is required", null);
         }
 
-        String resolvedFormat = format != null && !format.isBlank() ? 
format.toLowerCase() : "yaml";
-
-        JsonObject result = new JsonObject();
-        result.put("format", resolvedFormat);
-        result.put("route", route);
-
-        // Analyze security-sensitive components
-        List<String> securityComponents = extractSecurityComponents(route);
-        JsonArray securityComponentsJson = new JsonArray();
-        for (String comp : securityComponents) {
-            ComponentModel model = catalog.componentModel(comp);
-            if (model != null) {
-                JsonObject compJson = new JsonObject();
-                compJson.put("name", comp);
-                compJson.put("title", model.getTitle());
-                compJson.put("description", model.getDescription());
-                compJson.put("label", model.getLabel());
-                compJson.put("securityConsiderations", 
securityData.getSecurityConsiderations(comp));
-                compJson.put("riskLevel", securityData.getRiskLevel(comp));
-                securityComponentsJson.add(compJson);
+        try {
+            String resolvedFormat = format != null && !format.isBlank() ? 
format.toLowerCase() : "yaml";
+
+            JsonObject result = new JsonObject();
+            result.put("format", resolvedFormat);
+            result.put("route", route);
+
+            // Analyze security-sensitive components
+            List<String> securityComponents = extractSecurityComponents(route);
+            JsonArray securityComponentsJson = new JsonArray();
+            for (String comp : securityComponents) {
+                ComponentModel model = catalog.componentModel(comp);
+                if (model != null) {
+                    JsonObject compJson = new JsonObject();
+                    compJson.put("name", comp);
+                    compJson.put("title", model.getTitle());
+                    compJson.put("description", model.getDescription());
+                    compJson.put("label", model.getLabel());
+                    compJson.put("securityConsiderations", 
securityData.getSecurityConsiderations(comp));
+                    compJson.put("riskLevel", securityData.getRiskLevel(comp));
+                    securityComponentsJson.add(compJson);
+                }
             }
-        }
-        result.put("securitySensitiveComponents", securityComponentsJson);
+            result.put("securitySensitiveComponents", securityComponentsJson);
 
-        // Security analysis
-        JsonObject securityAnalysis = analyzeSecurityConcerns(route);
-        result.put("securityAnalysis", securityAnalysis);
+            // Security analysis
+            JsonObject securityAnalysis = analyzeSecurityConcerns(route);
+            result.put("securityAnalysis", securityAnalysis);
 
-        // Best practices
-        JsonArray bestPractices = new JsonArray();
-        for (String practice : securityData.getBestPractices()) {
-            bestPractices.add(practice);
+            // Best practices
+            JsonArray bestPractices = new JsonArray();
+            for (String practice : securityData.getBestPractices()) {
+                bestPractices.add(practice);
+            }
+            result.put("securityBestPractices", bestPractices);
+
+            // Summary
+            JsonObject summary = new JsonObject();
+            summary.put("securityComponentCount", 
securityComponentsJson.size());
+            summary.put("criticalRiskComponents", 
countComponentsByRisk(securityComponents, "critical"));
+            summary.put("highRiskComponents", 
countComponentsByRisk(securityComponents, "high"));
+            summary.put("concernCount", 
securityAnalysis.getInteger("concernCount"));
+            summary.put("positiveCount", 
securityAnalysis.getInteger("positiveCount"));
+            summary.put("hasExternalConnections", 
hasExternalConnections(route));
+            summary.put("hasSecretsManagement", hasSecretsManagement(route));
+            summary.put("usesTLS", usesTLS(route));
+            summary.put("hasAuthentication", hasAuthentication(route));
+            result.put("summary", summary);
+
+            return result.toJson();
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to analyze route security (" + 
e.getClass().getName() + "): " + e.getMessage(), null);
         }
-        result.put("securityBestPractices", bestPractices);
-
-        // Summary
-        JsonObject summary = new JsonObject();
-        summary.put("securityComponentCount", securityComponentsJson.size());
-        summary.put("criticalRiskComponents", 
countComponentsByRisk(securityComponents, "critical"));
-        summary.put("highRiskComponents", 
countComponentsByRisk(securityComponents, "high"));
-        summary.put("concernCount", 
securityAnalysis.getInteger("concernCount"));
-        summary.put("positiveCount", 
securityAnalysis.getInteger("positiveCount"));
-        summary.put("hasExternalConnections", hasExternalConnections(route));
-        summary.put("hasSecretsManagement", hasSecretsManagement(route));
-        summary.put("usesTLS", usesTLS(route));
-        summary.put("hasAuthentication", hasAuthentication(route));
-        result.put("summary", summary);
-
-        return result.toJson();
     }
 
     /**
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/KameletTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/KameletTools.java
index 61e1d8a06ed9..71b83e8d9e10 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/KameletTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/KameletTools.java
@@ -88,8 +88,9 @@ public class KameletTools {
             result.sort((a, b) -> a.name().compareToIgnoreCase(b.name()));
 
             return new KameletListResult(result.size(), version, result);
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list kamelets: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list kamelets (" + e.getClass().getName() + "): 
" + e.getMessage(), null);
         }
     }
 
@@ -138,8 +139,9 @@ public class KameletTools {
                     km.dependencies);
         } catch (ToolCallException e) {
             throw e;
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to get kamelet doc: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Kamelet not found: " + kamelet + " (" + 
e.getClass().getName() + "): " + e.getMessage(), null);
         }
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
index fae26b231f53..cc24017392cc 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
@@ -70,74 +70,81 @@ public class TransformTools {
             throw new ToolCallException("Either 'uri' or 'route' is required", 
null);
         }
 
-        ValidationResult result = new ValidationResult();
+        try {
+            ValidationResult result = new ValidationResult();
 
-        if (uri != null) {
-            result.uri = uri;
-            EndpointValidationResult validation = 
catalog.validateEndpointProperties(uri);
-            result.valid = validation.isSuccess();
+            if (uri != null) {
+                result.uri = uri;
+                EndpointValidationResult validation = 
catalog.validateEndpointProperties(uri);
+                result.valid = validation.isSuccess();
 
-            if (!validation.isSuccess()) {
-                ValidationErrors errors = new ValidationErrors();
-                if (validation.getUnknown() != null && 
!validation.getUnknown().isEmpty()) {
-                    errors.unknownOptions = String.join(", ", 
validation.getUnknown());
-                }
-                if (validation.getRequired() != null && 
!validation.getRequired().isEmpty()) {
-                    errors.missingRequired = String.join(", ", 
validation.getRequired());
-                }
-                if (validation.getInvalidEnum() != null && 
!validation.getInvalidEnum().isEmpty()) {
-                    errors.invalidEnumValues = 
validation.getInvalidEnum().toString();
-                }
-                if (validation.getInvalidInteger() != null && 
!validation.getInvalidInteger().isEmpty()) {
-                    errors.invalidIntegers = 
validation.getInvalidInteger().toString();
-                }
-                if (validation.getInvalidBoolean() != null && 
!validation.getInvalidBoolean().isEmpty()) {
-                    errors.invalidBooleans = 
validation.getInvalidBoolean().toString();
-                }
-                if (validation.getSyntaxError() != null) {
-                    errors.syntaxError = validation.getSyntaxError();
-                }
-                result.errors = errors;
-
-                if (validation.getUnknown() != null && 
validation.getUnknownSuggestions() != null) {
-                    Map<String, String> suggestions = new HashMap<>();
-                    for (String unknown : validation.getUnknown()) {
-                        String[] suggestionArr = 
validation.getUnknownSuggestions().get(unknown);
-                        if (suggestionArr != null && suggestionArr.length > 0) 
{
-                            suggestions.put(unknown, String.join(", ", 
suggestionArr));
-                        }
+                if (!validation.isSuccess()) {
+                    ValidationErrors errors = new ValidationErrors();
+                    if (validation.getUnknown() != null && 
!validation.getUnknown().isEmpty()) {
+                        errors.unknownOptions = String.join(", ", 
validation.getUnknown());
+                    }
+                    if (validation.getRequired() != null && 
!validation.getRequired().isEmpty()) {
+                        errors.missingRequired = String.join(", ", 
validation.getRequired());
+                    }
+                    if (validation.getInvalidEnum() != null && 
!validation.getInvalidEnum().isEmpty()) {
+                        errors.invalidEnumValues = 
validation.getInvalidEnum().toString();
+                    }
+                    if (validation.getInvalidInteger() != null && 
!validation.getInvalidInteger().isEmpty()) {
+                        errors.invalidIntegers = 
validation.getInvalidInteger().toString();
                     }
-                    if (!suggestions.isEmpty()) {
-                        result.suggestions = suggestions;
+                    if (validation.getInvalidBoolean() != null && 
!validation.getInvalidBoolean().isEmpty()) {
+                        errors.invalidBooleans = 
validation.getInvalidBoolean().toString();
+                    }
+                    if (validation.getSyntaxError() != null) {
+                        errors.syntaxError = validation.getSyntaxError();
+                    }
+                    result.errors = errors;
+
+                    if (validation.getUnknown() != null && 
validation.getUnknownSuggestions() != null) {
+                        Map<String, String> suggestions = new HashMap<>();
+                        for (String unknown : validation.getUnknown()) {
+                            String[] suggestionArr = 
validation.getUnknownSuggestions().get(unknown);
+                            if (suggestionArr != null && suggestionArr.length 
> 0) {
+                                suggestions.put(unknown, String.join(", ", 
suggestionArr));
+                            }
+                        }
+                        if (!suggestions.isEmpty()) {
+                            result.suggestions = suggestions;
+                        }
                     }
                 }
             }
-        }
 
-        if (route != null) {
-            result.routeProvided = true;
-            result.note = "Full route validation requires loading the route 
into a CamelContext. " +
-                          "Use 'camel run --validate' for complete 
validation.";
-
-            List<String> uris = extractUrisFromRoute(route);
-            if (!uris.isEmpty()) {
-                Map<String, Boolean> uriValidations = new HashMap<>();
-                boolean allValid = true;
-                for (String extractedUri : uris) {
-                    EndpointValidationResult validation = 
catalog.validateEndpointProperties(extractedUri);
-                    uriValidations.put(extractedUri, validation.isSuccess());
-                    if (!validation.isSuccess()) {
-                        allValid = false;
+            if (route != null) {
+                result.routeProvided = true;
+                result.note = "Full route validation requires loading the 
route into a CamelContext. " +
+                              "Use 'camel run --validate' for complete 
validation.";
+
+                List<String> uris = extractUrisFromRoute(route);
+                if (!uris.isEmpty()) {
+                    Map<String, Boolean> uriValidations = new HashMap<>();
+                    boolean allValid = true;
+                    for (String extractedUri : uris) {
+                        EndpointValidationResult validation = 
catalog.validateEndpointProperties(extractedUri);
+                        uriValidations.put(extractedUri, 
validation.isSuccess());
+                        if (!validation.isSuccess()) {
+                            allValid = false;
+                        }
                     }
+                    result.uriValidations = uriValidations;
+                    result.valid = allValid;
+                } else {
+                    result.valid = true;
                 }
-                result.uriValidations = uriValidations;
-                result.valid = allValid;
-            } else {
-                result.valid = true;
             }
-        }
 
-        return result;
+            return result;
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to validate route (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
+        }
     }
 
     /**
@@ -185,8 +192,9 @@ public class TransformTools {
                 result.supported = false;
                 result.note = "Unsupported transformation: " + fromFormat + " 
to " + toFormat;
             }
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to transform route: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to transform route (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
 
         return result;
@@ -284,8 +292,9 @@ public class TransformTools {
             } finally {
                 tempFile.delete();
             }
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to validate YAML DSL: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to validate YAML DSL (" + e.getClass().getName() + 
"): " + e.getMessage(), null);
         }
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/VersionTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/VersionTools.java
index eaced47c0bba..e248331082b6 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/VersionTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/VersionTools.java
@@ -93,8 +93,9 @@ public class VersionTools {
             return new VersionListResult(versionInfos.size(), versionInfos);
         } catch (ToolCallException e) {
             throw e;
-        } catch (Exception e) {
-            throw new ToolCallException("Failed to list versions: " + 
e.getMessage(), e);
+        } catch (Throwable e) {
+            throw new ToolCallException(
+                    "Failed to list versions (" + e.getClass().getName() + "): 
" + e.getMessage(), null);
         }
     }
 
@@ -102,7 +103,12 @@ public class VersionTools {
         if (runtime == null || runtime.isBlank() || 
"main".equalsIgnoreCase(runtime)) {
             return RuntimeType.main;
         }
-        return RuntimeType.fromValue(runtime);
+        try {
+            return RuntimeType.fromValue(runtime);
+        } catch (IllegalArgumentException e) {
+            throw new ToolCallException(
+                    "Unsupported runtime: " + runtime + ". Supported values 
are: main, spring-boot, quarkus", null);
+        }
     }
 
     // Result classes for Jackson serialization

Reply via email to