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 9e58622ab979 CAMEL-24698: camel-jbang-mcp - runtime, camelVersion,
platformBom, filter, label and limit are optional on the catalog tools (#26369)
9e58622ab979 is described below
commit 9e58622ab9796e7499fcc3c4fd297f977d961b29
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Sep 13 16:46:11 2026 +0200
CAMEL-24698: camel-jbang-mcp - runtime, camelVersion, platformBom, filter,
label and limit are optional on the catalog tools (#26369)
CAMEL-24698: camel-jbang-mcp - runtime, camelVersion, platformBom, filter,
label and limit are optional on the catalog tools; a non-version means the
default catalog; EIP names in any case
Squash of the 5 commits on fix/CAMEL-24698-mcp-optional-args (the
run-by-run history is on bench/after-run). The old camel_catalog_doc wrapper
the branch touched is gone on main since CAMEL-24695.
camel-jbang-mcp - runtime, camelVersion and platformBom are optional on
every catalog tool
camel-jbang-mcp - a camelVersion that is not a version (main, latest) means
the default catalog
camel-jbang-mcp - the running Camel version, and a version that cannot be
downloaded, answer from the default catalog
camel-jbang-mcp - filter, label, limit and camelVersion are optional on the
catalog list and doc tools
camel-jbang-mcp - camel_catalog_eip_doc accepts circuit-breaker,
circuitbreaker and Circuit Breaker for circuitBreaker
Co-authored-by: Claude Fable 5.1 <[email protected]>
---
.../jbang/core/commands/mcp/CatalogService.java | 34 ++++++-
.../dsl/jbang/core/commands/mcp/CatalogTools.java | 108 +++++++++++++--------
.../commands/mcp/ComponentPropertiesTools.java | 6 +-
.../commands/mcp/ConfigurationValidateTools.java | 6 +-
.../core/commands/mcp/DependencyCheckTools.java | 6 +-
.../commands/mcp/DependencySecurityAuditTools.java | 6 +-
.../dsl/jbang/core/commands/mcp/DiagnoseTools.java | 6 +-
.../dsl/jbang/core/commands/mcp/ExplainTools.java | 6 +-
.../dsl/jbang/core/commands/mcp/HardenTools.java | 6 +-
.../jbang/core/commands/mcp/TestScaffoldTools.java | 4 +-
.../jbang/core/commands/mcp/TransformTools.java | 6 +-
.../dsl/jbang/core/commands/mcp/VersionTools.java | 2 +-
.../jbang/core/commands/mcp/CatalogToolsTest.java | 9 ++
.../mcp/ConfigurationValidateToolsTest.java | 12 +++
14 files changed, 149 insertions(+), 68 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogService.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogService.java
index b43153820fdf..f148c4f76312 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogService.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogService.java
@@ -79,7 +79,14 @@ public class CatalogService {
public CamelCatalog loadCatalog(String runtime, String camelVersion,
String platformBom) throws Exception {
RuntimeType runtimeType = resolveRuntime(runtime);
- boolean hasVersion = camelVersion != null && !camelVersion.isBlank();
+ // "main", "latest", "current" or "default" (what an assistant writes
when it means the version in use) is
+ // the default catalog, not a version to download
+ boolean hasVersion = camelVersion != null && !camelVersion.isBlank()
&& !camelVersion.isEmpty()
+ && Character.isDigit(camelVersion.trim().charAt(0));
+ if (hasVersion && sameAsDefault(camelVersion)) {
+ // the version in use (4.23.0 for a 4.23.0-SNAPSHOT build):
nothing to download
+ hasVersion = false;
+ }
boolean hasBom = platformBom != null && !platformBom.isBlank();
// No version-specific parameters and main runtime -> default catalog
@@ -105,7 +112,7 @@ public class CatalogService {
normalizedVersion = platformBomGav.getVersion();
}
}
- if (platformBomGav == null && platformBom != null) {
+ if (platformBomGav == null && hasBom) {
String[] parts = platformBom.split(":");
if (parts.length != 3) {
throw new ToolCallException(
@@ -121,11 +128,32 @@ public class CatalogService {
return cached;
}
- CamelCatalog loaded = doLoadCatalog(runtimeType, camelVersion,
platformBomGav);
+ CamelCatalog loaded;
+ try {
+ loaded = doLoadCatalog(runtimeType, camelVersion, platformBomGav);
+ } catch (Exception e) {
+ if (runtimeType == RuntimeType.main && hasVersion && !hasBom) {
+ // a version that cannot be downloaded (not released, no
network): answer from the default catalog
+ // rather than fail the tool call
+ return defaultCatalog;
+ }
+ throw e;
+ }
cache.putIfAbsent(key, loaded);
return cache.get(key);
}
+ /** Whether the version is the default catalog's, with or without a
-SNAPSHOT qualifier. */
+ boolean sameAsDefault(String camelVersion) {
+ String mine = defaultCatalog.getCatalogVersion();
+ if (mine == null) {
+ return false;
+ }
+ String v = camelVersion.trim();
+ return v.equals(mine) || v.equals(mine.replace("-SNAPSHOT", ""))
+ || mine.equals(v.replace("-SNAPSHOT", ""));
+ }
+
/**
* Resolve a runtime string to a {@link RuntimeType} enum value.
*
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 5a3b862a307d..659541cd3333 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
@@ -53,12 +53,14 @@ public class CatalogTools {
+ "camel_catalog_component_doc for that). "
+ "Use filter to search by name, label to filter by
category.")
public ComponentListResult camel_catalog_components(
- @ToolArg(description = "Filter components by name
(case-insensitive substring match)") String filter,
- @ToolArg(description = "Filter by category label (e.g., cloud,
messaging, database, file)") String label,
- @ToolArg(description = "Maximum number of results to return
(default: 20)") Integer limit,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.VERSION_QUERY) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = "Filter components by name
(case-insensitive substring match)",
+ required = false) String filter,
+ @ToolArg(description = "Filter by category label (e.g., cloud,
messaging, database, file)",
+ required = false) String label,
+ @ToolArg(description = "Maximum number of results to return
(default: 20)", required = false) Integer limit,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.VERSION_QUERY, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
int maxResults = limit != null ? limit : 20;
@@ -106,9 +108,9 @@ public class CatalogTools {
@ToolArg(description = "Whether to include message headers in the
response (default: false). "
+ "Headers show the CamelXxx header names,
their Java constants, types, and consumer/producer group.",
required = false) Boolean includeHeaders,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.VERSION_QUERY) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.VERSION_QUERY, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (component == null || component.isBlank()) {
throw new ToolCallException("Component name is required", null);
@@ -165,9 +167,9 @@ public class CatalogTools {
+ "for adding it as a dependency.")
public ComponentMavenResult camel_catalog_component_maven(
@ToolArg(description = "Component name (e.g., kafka, http, file,
timer)") String component,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.VERSION_QUERY) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.VERSION_QUERY, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (component == null || component.isBlank()) {
throw new ToolCallException("Component name is required", null);
@@ -199,11 +201,11 @@ public class CatalogTools {
description = "List available Camel data formats for
marshalling/unmarshalling " +
"(e.g., json, xml, csv, avro, protobuf).")
public DataFormatListResult camel_catalog_dataformats(
- @ToolArg(description = "Filter by name") String filter,
- @ToolArg(description = "Maximum results (default: 20)") Integer
limit,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = "Filter by name", required = false) String
filter,
+ @ToolArg(description = "Maximum results (default: 20)", required =
false) Integer limit,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
int maxResults = limit != null ? limit : 20;
@@ -232,10 +234,10 @@ public class CatalogTools {
description = "List available Camel expression languages " +
"(e.g., simple, jsonpath, xpath, groovy, jq).")
public LanguageListResult camel_catalog_languages(
- @ToolArg(description = "Filter by name") String filter,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = "Filter by name", required = false) String
filter,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
try {
CamelCatalog cat = catalogService.loadCatalog(runtime,
camelVersion, platformBom);
@@ -262,9 +264,9 @@ public class CatalogTools {
+ "Maven coordinates, and configuration parameters.")
public DataFormatDetailResult camel_catalog_dataformat_doc(
@ToolArg(description = "Data format name (e.g., json-jackson,
avro, csv, protobuf, jaxb)") String dataformat,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (dataformat == null || dataformat.isBlank()) {
throw new ToolCallException("Data format name is required", null);
@@ -296,9 +298,9 @@ public class CatalogTools {
+ "Maven coordinates, and configuration parameters.")
public LanguageDetailResult camel_catalog_language_doc(
@ToolArg(description = "Language name (e.g., simple, jsonpath,
xpath, jq, groovy)") String language,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (language == null || language.isBlank()) {
throw new ToolCallException("Language name is required", null);
@@ -330,11 +332,13 @@ public class CatalogTools {
"EIPs have aliases for common AI/modern terms (e.g.,
fan-out, scatter-gather, retry, dedup). " +
"Filter also matches aliases with dash normalization
(fan-out, fanout, fanOut all match).")
public EipListResult camel_catalog_eips(
- @ToolArg(description = "Filter by name, title, description, or
alias (e.g., fan-out, dedup, rate-limit)") String filter,
- @ToolArg(description = "Filter by category (e.g., routing,
transformation, error handling)") String label,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = "Filter by name, title, description, or
alias (e.g., fan-out, dedup, rate-limit)",
+ required = false) String filter,
+ @ToolArg(description = "Filter by category (e.g., routing,
transformation, error handling)",
+ required = false) String label,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
try {
CamelCatalog cat = catalogService.loadCatalog(runtime,
camelVersion, platformBom);
@@ -361,9 +365,9 @@ public class CatalogTools {
description = "Get detailed documentation for a Camel EIP
(Enterprise Integration Pattern).")
public EipDetailResult camel_catalog_eip_doc(
@ToolArg(description = "EIP name (e.g., split, aggregate, choice,
filter)") String eip,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (eip == null || eip.isBlank()) {
throw new ToolCallException("EIP name is required", null);
@@ -373,6 +377,19 @@ public class CatalogTools {
CamelCatalog cat = catalogService.loadCatalog(runtime,
camelVersion, platformBom);
EipModel model = cat.eipModel(eip);
+ if (model == null) {
+ // circuit-breaker, Circuit Breaker: the catalog names EIPs in
camelCase
+ String camel = toCamelCase(eip);
+ model = cat.eipModel(camel);
+ if (model == null) {
+ for (String n : cat.findModelNames()) {
+ if (n.equalsIgnoreCase(camel)) {
+ model = cat.eipModel(n);
+ break;
+ }
+ }
+ }
+ }
if (model == null) {
throw new ToolCallException("EIP not found: " + eip, null);
}
@@ -399,9 +416,9 @@ public class CatalogTools {
+ "with usage examples, code snippets, and best
practices. "
+ "Only available from Camel 4.22 onwards.")
public DocListResult camel_catalog_docs(
- @ToolArg(description = "Filter page names by substring
(case-insensitive)") String filter,
- @ToolArg(description = "Maximum number of results to return
(default: 50)") Integer limit,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion) {
+ @ToolArg(description = "Filter page names by substring
(case-insensitive)", required = false) String filter,
+ @ToolArg(description = "Maximum number of results to return
(default: 50)", required = false) Integer limit,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion) {
int maxResults = limit != null ? limit : 50;
@@ -613,6 +630,21 @@ public class CatalogTools {
model.getAliases().isEmpty() ? null : model.getAliases());
}
+ /** circuit-breaker, circuit_breaker or "Circuit Breaker" as
circuitBreaker. */
+ static String toCamelCase(String name) {
+ StringBuilder sb = new StringBuilder();
+ boolean upper = false;
+ for (char ch : name.trim().toCharArray()) {
+ if (ch == '-' || ch == '_' || ch == ' ') {
+ upper = sb.length() > 0;
+ } else {
+ sb.append(upper ? Character.toUpperCase(ch) : ch);
+ upper = false;
+ }
+ }
+ return sb.toString();
+ }
+
private EipDetailResult toEipDetailResult(EipModel model) {
List<OptionInfo> options = new ArrayList<>();
if (model.getOptions() != null) {
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ComponentPropertiesTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ComponentPropertiesTools.java
index 3b14f515aee2..f285ddd0409b 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ComponentPropertiesTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ComponentPropertiesTools.java
@@ -53,9 +53,9 @@ public class ComponentPropertiesTools {
"component-level defaults via the same prefix in
application.properties.")
public ComponentPropertiesResult camel_component_properties(
@ToolArg(description = "Component name / scheme (e.g., kafka,
http, file, timer)") String component,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.VERSION_QUERY) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.VERSION_QUERY, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (component == null || component.isBlank()) {
throw new ToolCallException("Component name is required", null);
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateTools.java
index 8bff50d125c9..de13bfd8647b 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateTools.java
@@ -57,9 +57,9 @@ public class ConfigurationValidateTools {
public ConfigurationValidateResult camel_configuration_validate(
@ToolArg(description = "Configuration property lines to validate.
Can be a single line "
+ "(e.g. \"camel.main.streamCaching=true\")
or multiple lines separated by newlines.") String properties,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (properties == null || properties.isBlank()) {
throw new ToolCallException("properties argument is required",
null);
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencyCheckTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencyCheckTools.java
index bc5b92da8616..a7fe216bf01d 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencyCheckTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencyCheckTools.java
@@ -61,9 +61,9 @@ public class DependencyCheckTools {
+ "Sensitive content is automatically
detected and masked.") String pomContent,
@ToolArg(description = "Route definitions (YAML, XML, or Java DSL)
to check for missing component dependencies. "
+ "Multiple routes can be provided
concatenated.") String routes,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom,
@ToolArg(description = "If true (default), automatically sanitize
POM content by masking credentials") Boolean sanitizePom) {
if (pomContent == null || pomContent.isBlank()) {
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencySecurityAuditTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencySecurityAuditTools.java
index f482d0419992..05b5cf2a6217 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencySecurityAuditTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DependencySecurityAuditTools.java
@@ -58,9 +58,9 @@ public class DependencySecurityAuditTools {
@ToolArg(description = "The pom.xml file content") String
pomContent,
@ToolArg(description = "Route definitions (YAML, XML, or Java DSL)
to determine which components "
+ "are actually used (for reachability
analysis)") String routes,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom,
@ToolArg(description = "If true (default), mask credentials in POM
content") Boolean sanitizePom) {
if (pomContent == null || pomContent.isBlank()) {
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DiagnoseTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DiagnoseTools.java
index b3d8dcfb2dac..53d151e5d0c8 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DiagnoseTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/DiagnoseTools.java
@@ -52,9 +52,9 @@ public class DiagnoseTools {
+ "ResolveEndpointFailedException,
FailedToCreateRouteException, and more.")
public JsonObject camel_error_diagnose(
@ToolArg(description = "The Camel stack trace or error message to
diagnose") String error,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (error == null || error.isBlank()) {
throw new ToolCallException("Error message or stack trace is
required", null);
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 46cbe959d89d..57a7c75c452a 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
@@ -53,9 +53,9 @@ public class ExplainTools {
public RouteContextResult camel_route_context(
@ToolArg(description = "The Camel route content (YAML, XML, or
Java DSL)") String route,
@ToolArg(description = "Route format: yaml, xml, or java (default:
yaml)") String format,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (route == null || route.isBlank()) {
throw new ToolCallException("Route content is required", null);
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 7f7bd5213ec1..9b178b0d78cc 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
@@ -68,9 +68,9 @@ public class HardenTools {
public HardenContextResult camel_route_harden_context(
@ToolArg(description = "The Camel route content (YAML, XML, or
Java DSL)") String route,
@ToolArg(description = "Route format: yaml, xml, or java (default:
yaml)") String format,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (route == null || route.isBlank()) {
throw new ToolCallException("Route content is required", null);
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TestScaffoldTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TestScaffoldTools.java
index 35ec249b8f87..ad0b078da2f8 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TestScaffoldTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TestScaffoldTools.java
@@ -83,8 +83,8 @@ public class TestScaffoldTools {
@ToolArg(description = "The Camel route definition (YAML or XML)")
String route,
@ToolArg(description = "Route format: yaml or xml (default:
yaml)") String format,
@ToolArg(description = "Target runtime: main or spring-boot
(default: main)") String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (route == null || route.isBlank()) {
throw new ToolCallException("Route content is required", 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 37eb945716a3..a8e64dd850d1 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
@@ -71,9 +71,9 @@ public class TransformTools {
public ValidationResult camel_validate_route(
@ToolArg(description = "Camel endpoint URI to validate (e.g.,
'kafka:myTopic?brokers=localhost:9092')") String uri,
@ToolArg(description = "YAML route definition to validate") String
route,
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
- @ToolArg(description = ToolArgDocs.CAMEL_VERSION) String
camelVersion,
- @ToolArg(description = ToolArgDocs.PLATFORM_BOM) String
platformBom) {
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
+ @ToolArg(description = ToolArgDocs.CAMEL_VERSION, required =
false) String camelVersion,
+ @ToolArg(description = ToolArgDocs.PLATFORM_BOM, required = false)
String platformBom) {
if (uri == null && route == null) {
throw new ToolCallException("Either 'uri' or 'route' is required",
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 38bbed64491d..39aa96e8f2e1 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
@@ -46,7 +46,7 @@ public class VersionTools {
description = "List available Camel versions for a specific runtime
(main, spring-boot, quarkus). " +
"Returns version information including release date,
JDK requirements, and LTS status.")
public VersionListResult camel_version_list(
- @ToolArg(description = ToolArgDocs.RUNTIME) String runtime,
+ @ToolArg(description = ToolArgDocs.RUNTIME, required = false)
String runtime,
@ToolArg(description = "Only show LTS (Long Term Support) releases
(default: false)") Boolean lts,
@ToolArg(description = "Minimum Camel version to include (e.g.,
4.0)") String fromVersion,
@ToolArg(description = "Maximum number of versions to return
(default: 10)") Integer limit) {
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogToolsTest.java
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogToolsTest.java
index 57ddd62c027f..3cd8fbdda06f 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogToolsTest.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/CatalogToolsTest.java
@@ -355,4 +355,13 @@ class CatalogToolsTest {
assertThat(mavenResult.version()).isEqualTo(requestedVersion);
assertThat(mavenResult.version()).isNotEqualTo(BUILTIN_VERSION);
}
+
+ @Test
+ void eipDocAcceptsKebabCaseAndAnyCase() {
+ CatalogTools tools = createTools(null);
+ assertThat(tools.camel_catalog_eip_doc("circuit-breaker", null, null,
null).name()).isEqualTo("circuitBreaker");
+ assertThat(tools.camel_catalog_eip_doc("circuitbreaker", null, null,
null).name()).isEqualTo("circuitBreaker");
+ assertThat(tools.camel_catalog_eip_doc("Circuit Breaker", null, null,
null).name()).isEqualTo("circuitBreaker");
+
assertThat(CatalogTools.toCamelCase("poll-enrich")).isEqualTo("pollEnrich");
+ }
}
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateToolsTest.java
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateToolsTest.java
index ecbfe9248fe8..bf1a6159faae 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateToolsTest.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/ConfigurationValidateToolsTest.java
@@ -57,6 +57,18 @@ class ConfigurationValidateToolsTest {
assertThat(info.issues()).isEmpty();
}
+ @Test
+ void theRunningVersionWithoutSnapshotIsTheDefaultCatalog() {
+ // an assistant that reads "4.23.0-SNAPSHOT" from the server asks for
4.23.0, which is not on Maven Central
+ ConfigurationValidateTools tools = createTools();
+ String mine =
tools.catalogService.getDefaultCatalog().getCatalogVersion().replace("-SNAPSHOT",
"");
+
+ ConfigurationValidateTools.ConfigurationValidateResult result
+ =
tools.camel_configuration_validate("camel.main.streamCachingEnabled=true",
"main", mine, null);
+
+ assertThat(result.summary().valid()).isEqualTo(1);
+ }
+
@Test
void detectsUnknownOption() {
ConfigurationValidateTools tools = createTools();