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

acosentino 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 a503e3912177 CAMEL-22975 - Camel-jbang-MCP: Add Kamelets catalog and 
doc tool (#21382)
a503e3912177 is described below

commit a503e39121777ce058cd7310c4410aba43644394
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Feb 10 11:29:03 2026 +0100

    CAMEL-22975 - Camel-jbang-MCP: Add Kamelets catalog and doc tool (#21382)
    
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 docs/user-manual/modules/ROOT/nav.adoc             |   1 +
 .../modules/ROOT/pages/camel-jbang-mcp.adoc        | 296 +++++++++++++++++++++
 .../jbang/core/commands/catalog/KameletModel.java  |  12 +-
 .../core/commands/catalog/KameletOptionModel.java  |  14 +-
 .../dsl/jbang/core/commands/mcp/KameletTools.java  | 161 +++++++++++
 5 files changed, 471 insertions(+), 13 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/nav.adoc 
b/docs/user-manual/modules/ROOT/nav.adoc
index 37a204df317a..eb09a11eadaa 100644
--- a/docs/user-manual/modules/ROOT/nav.adoc
+++ b/docs/user-manual/modules/ROOT/nav.adoc
@@ -10,6 +10,7 @@
 *** xref:camel-jbang-launcher.adoc[Camel JBang Launcher]
 *** xref:camel-jbang-kubernetes.adoc[Camel JBang Kubernetes plugin]
 *** xref:camel-jbang-test.adoc[Camel JBang Testing plugin]
+*** xref:camel-jbang-mcp.adoc[Camel MCP Server]
 ** xref:camel-maven-plugin.adoc[Camel Maven Plugin]
 ** xref:camel-component-maven-plugin.adoc[Camel Component Maven Plugin]
 ** xref:camel-report-maven-plugin.adoc[Camel Maven Report Plugin]
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc
new file mode 100644
index 000000000000..a1d7c1089fc6
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc
@@ -0,0 +1,296 @@
+= Camel MCP Server
+
+The Camel MCP Server exposes the Apache Camel Catalog and a set of specialized 
tools through the
+https://modelcontextprotocol.io/[Model Context Protocol (MCP)], the open 
standard that allows AI coding assistants
+to call external tools. This enables AI tools such as Claude Code, OpenAI 
Codex, GitHub Copilot, and JetBrains AI
+to query live Camel catalog data, validate endpoint URIs, analyze routes for 
security concerns, browse Kamelets, and more.
+
+The server is built on https://quarkus.io/[Quarkus] using the
+https://docs.quarkiverse.io/quarkus-mcp-server/dev/index.html[quarkus-mcp-server]
 extension and ships as a single
+uber-JAR that can be launched via https://www.jbang.dev/[JBang].
+
+NOTE: This module is in *Preview* status as of Camel 4.18.
+
+== Transport
+
+The server supports two transports:
+
+* **STDIO** -- The default transport for CLI-based AI tools. The server 
communicates over stdin/stdout using the MCP
+  protocol. All logging goes to stderr to keep stdout clean for protocol 
messages.
+* **HTTP/SSE** -- An optional transport for web-based clients and remote 
access scenarios. Useful when running the
+  MCP server as a shared service for a team or in a container.
+
+By default, the HTTP server is disabled. To enable it, set 
`quarkus.http.host-enabled=true`.
+
+== Available Tools
+
+The server exposes 13 tools organized into six functional areas.
+
+=== Catalog Exploration
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_catalog_components`
+| List available Camel components with filtering by name, label (e.g., 
`messaging`, `cloud`, `database`), and
+  runtime type (`main`, `spring-boot`, `quarkus`). Supports querying specific 
Camel versions.
+
+| `camel_catalog_component_doc`
+| Get detailed documentation for a specific component including all endpoint 
options, component-level options,
+  Maven coordinates, and URI syntax.
+
+| `camel_catalog_dataformats`
+| List available data formats (JSON, XML, CSV, Avro, Protobuf, and others).
+
+| `camel_catalog_languages`
+| List expression languages (Simple, JsonPath, XPath, JQ, Groovy, and others).
+
+| `camel_catalog_eips`
+| List Enterprise Integration Patterns with filtering by category.
+
+| `camel_catalog_eip_doc`
+| Get detailed documentation for a specific EIP including all its options.
+|===
+
+=== Kamelet Catalog
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_catalog_kamelets`
+| List available Kamelets from the Kamelet Catalog with filtering by name, 
description, and type (`source`, `sink`,
+  `action`). Supports querying specific Kamelets catalog versions.
+
+| `camel_catalog_kamelet_doc`
+| Get detailed documentation for a specific Kamelet including all 
properties/options, their types, defaults,
+  examples, and the Kamelet's Maven dependencies.
+|===
+
+=== Route Understanding
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_route_context`
+| Given a Camel route (YAML, XML, or Java DSL), extracts all components and 
EIPs used, looks up their documentation
+  from the catalog, and returns structured context.
+|===
+
+=== Security Analysis
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_route_harden_context`
+| Analyzes a route for security concerns. Identifies security-sensitive 
components, assigns risk levels, detects
+  issues like hardcoded credentials or plain-text protocols, and returns 
structured security findings alongside
+  best practices.
+|===
+
+=== Validation and Transformation
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_validate_route`
+| Validates Camel endpoint URIs against the catalog schema. Catches unknown 
options, missing required parameters,
+  invalid enum values, and type mismatches. Also provides suggestions for 
misspelled option names.
+
+| `camel_transform_route`
+| Assists with route DSL format transformation between YAML and XML.
+|===
+
+=== Version Management
+
+[cols="1,3",options="header"]
+|===
+| Tool | Description
+
+| `camel_version_list`
+| Lists available Camel versions for a given runtime, including release dates, 
JDK requirements, and LTS status.
+|===
+
+== Setup
+
+The MCP server requires https://www.jbang.dev/[JBang] to be installed and 
available on your PATH.
+
+=== Claude Code
+
+Add the following to your project's `.mcp.json` (or `~/.claude/mcp.json` for 
global configuration):
+
+[source,json]
+----
+{
+  "mcpServers": {
+    "camel": {
+      "command": "jbang",
+      "args": [
+        "-Dquarkus.log.level=WARN",
+        "org.apache.camel:camel-jbang-mcp:4.18.0:runner"
+      ]
+    }
+  }
+}
+----
+
+=== OpenAI Codex
+
+Add the server to your MCP configuration:
+
+[source,json]
+----
+{
+  "mcpServers": {
+    "camel": {
+      "command": "jbang",
+      "args": [
+        "-Dquarkus.log.level=WARN",
+        "org.apache.camel:camel-jbang-mcp:4.18.0:runner"
+      ]
+    }
+  }
+}
+----
+
+=== VS Code with Copilot
+
+Configure MCP servers in your `.vscode/mcp.json` or in the user settings:
+
+[source,json]
+----
+{
+  "servers": {
+    "camel": {
+      "command": "jbang",
+      "args": [
+        "-Dquarkus.log.level=WARN",
+        "org.apache.camel:camel-jbang-mcp:4.18.0:runner"
+      ]
+    }
+  }
+}
+----
+
+=== JetBrains IDEs
+
+JetBrains IDEs support MCP servers starting from 2025.1. Configure them in
+Settings > Tools > AI Assistant > MCP Servers, or create an `.junie/mcp.json` 
file in your project root:
+
+[source,json]
+----
+{
+  "mcpServers": {
+    "camel": {
+      "command": "jbang",
+      "args": [
+        "-Dquarkus.log.level=WARN",
+        "org.apache.camel:camel-jbang-mcp:4.18.0:runner"
+      ]
+    }
+  }
+}
+----
+
+=== Generic STDIO Client
+
+Any MCP client that supports the STDIO transport can launch the server 
directly:
+
+[source,bash]
+----
+jbang org.apache.camel:camel-jbang-mcp:4.18.0:runner
+----
+
+=== HTTP/SSE Transport
+
+To start the server with the HTTP/SSE transport enabled:
+
+[source,bash]
+----
+jbang -Dquarkus.http.host-enabled=true -Dquarkus.http.port=8080 
org.apache.camel:camel-jbang-mcp:4.18.0:runner
+----
+
+MCP clients that support HTTP/SSE can then connect to the server at 
`http://localhost:8080/mcp/sse`.
+
+== Examples
+
+=== Listing Components
+
+Prompt your AI assistant with:
+
+----
+List all Camel components in the messaging category
+----
+
+The assistant calls `camel_catalog_components` with `label=messaging` and 
receives structured results with name,
+title, description, label, deprecation status, and support level for each 
matching component.
+
+=== Getting Component Documentation
+
+----
+Show me the documentation for the Kafka component, including all endpoint 
options
+----
+
+The assistant calls `camel_catalog_component_doc` with `component=kafka` and 
receives the full component model
+including the URI syntax, Maven coordinates, and every endpoint option with 
types, defaults, and descriptions.
+
+=== Browsing Kamelets
+
+----
+Show me all available source kamelets related to AWS
+----
+
+The assistant calls `camel_catalog_kamelets` with `type=source` and 
`filter=aws` and returns matching Kamelets
+with their name, type, support level, and description.
+
+To drill into a specific Kamelet:
+
+----
+What options does the aws-s3-source kamelet accept?
+----
+
+The assistant calls `camel_catalog_kamelet_doc` with `kamelet=aws-s3-source` 
and returns the complete property
+list including required fields, types, defaults, and Maven dependencies.
+
+=== Validating an Endpoint URI
+
+----
+Validate this Kafka endpoint: 
kafka:myTopic?brkers=localhost:9092&groupId=myGroup
+----
+
+The assistant calls `camel_validate_route` and detects the typo (`brkers`), 
reports the URI as invalid, and
+suggests the correct option name (`brokers`).
+
+=== Understanding a Route
+
+Paste a route and ask:
+
+----
+Explain what this route does
+----
+
+The assistant calls `camel_route_context` which extracts all components and 
EIPs used in the route, looks up
+their documentation from the catalog, and returns enriched context so the AI 
can provide an accurate explanation.
+
+=== Security Hardening
+
+----
+Analyze this route for security concerns and suggest hardening measures
+----
+
+The assistant calls `camel_route_harden_context` which analyzes the route for 
security-sensitive components,
+detects issues (hardcoded credentials, HTTP instead of HTTPS, plain FTP, 
etc.), assigns risk levels, and
+returns structured findings with remediation recommendations.
+
+=== Checking Camel Versions
+
+----
+What are the latest LTS versions of Camel for Spring Boot?
+----
+
+The assistant calls `camel_version_list` with `runtime=spring-boot` and 
`lts=true` and returns version
+information including release dates, end-of-life dates, and JDK requirements.
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletModel.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletModel.java
index 62ac3e3c6fe5..28a4b7965260 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletModel.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletModel.java
@@ -21,11 +21,11 @@ import java.util.Map;
 
 public class KameletModel {
 
-    String name;
-    String type;
-    String supportLevel;
-    String description;
-    Map<String, KameletOptionModel> properties;
-    List<String> dependencies;
+    public String name;
+    public String type;
+    public String supportLevel;
+    public String description;
+    public Map<String, KameletOptionModel> properties;
+    public List<String> dependencies;
 
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletOptionModel.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletOptionModel.java
index a0a7837a0368..5f4f2c5bead2 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletOptionModel.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/KameletOptionModel.java
@@ -20,12 +20,12 @@ import java.util.List;
 
 public class KameletOptionModel {
 
-    String name;
-    boolean required;
-    String description;
-    String type;
-    String defaultValue;
-    String example;
-    List<String> enumValues;
+    public String name;
+    public boolean required;
+    public String description;
+    public String type;
+    public String defaultValue;
+    public String example;
+    public List<String> enumValues;
 
 }
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
new file mode 100644
index 000000000000..61e1d8a06ed9
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/KameletTools.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.mcp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import jakarta.enterprise.context.ApplicationScoped;
+
+import io.quarkiverse.mcp.server.Tool;
+import io.quarkiverse.mcp.server.ToolArg;
+import io.quarkiverse.mcp.server.ToolCallException;
+import org.apache.camel.dsl.jbang.core.commands.catalog.KameletCatalogHelper;
+import org.apache.camel.dsl.jbang.core.commands.catalog.KameletModel;
+import org.apache.camel.dsl.jbang.core.commands.catalog.KameletOptionModel;
+import org.apache.camel.dsl.jbang.core.common.RuntimeType;
+
+/**
+ * MCP Tools for querying the Kamelet Catalog using Quarkus MCP Server.
+ */
+@ApplicationScoped
+public class KameletTools {
+
+    /**
+     * Tool to list available Kamelets.
+     */
+    @Tool(description = "List available Camel Kamelets from the Kamelet 
Catalog. " +
+                        "Returns kamelet name, type (source, sink, action), 
support level, and description. " +
+                        "Use filter to search by name or description, type to 
filter by category.")
+    public KameletListResult camel_catalog_kamelets(
+            @ToolArg(description = "Filter kamelets by name or description 
(case-insensitive substring match)") String filter,
+            @ToolArg(description = "Filter by type: source, sink, or action") 
String type,
+            @ToolArg(description = "Maximum number of results to return 
(default: 50)") Integer limit,
+            @ToolArg(description = "Apache Camel Kamelets version. If not 
specified, uses the default version.") String kameletsVersion) {
+
+        int maxResults = limit != null ? limit : 50;
+
+        try {
+            String version = kameletsVersion != null && 
!kameletsVersion.isBlank()
+                    ? kameletsVersion : RuntimeType.KAMELETS_VERSION;
+
+            Map<String, Object> kamelets = 
KameletCatalogHelper.loadKamelets(version, null);
+
+            List<KameletInfo> result = new ArrayList<>();
+            for (Object o : kamelets.values()) {
+                KameletModel km = KameletCatalogHelper.createModel(o, false);
+
+                // filter by type
+                if (type != null && !type.isBlank()
+                        && !type.equalsIgnoreCase(km.type)) {
+                    continue;
+                }
+
+                // filter by name or description
+                if (filter != null && !filter.isBlank()) {
+                    String lowerFilter = filter.toLowerCase(Locale.ROOT);
+                    boolean matches = (km.name != null && 
km.name.toLowerCase(Locale.ROOT).contains(lowerFilter))
+                            || (km.description != null && 
km.description.toLowerCase(Locale.ROOT).contains(lowerFilter));
+                    if (!matches) {
+                        continue;
+                    }
+                }
+
+                result.add(new KameletInfo(km.name, km.type, km.supportLevel, 
km.description));
+
+                if (result.size() >= maxResults) {
+                    break;
+                }
+            }
+
+            // sort by name
+            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);
+        }
+    }
+
+    /**
+     * Tool to get detailed documentation for a specific Kamelet.
+     */
+    @Tool(description = "Get detailed documentation for a specific Camel 
Kamelet including all properties/options, "
+                        + "dependencies, and usage information.")
+    public KameletDetailResult camel_catalog_kamelet_doc(
+            @ToolArg(description = "Kamelet name (e.g., aws-s3-source, 
kafka-sink, log-action)") String kamelet,
+            @ToolArg(description = "Apache Camel Kamelets version. If not 
specified, uses the default version.") String kameletsVersion) {
+
+        if (kamelet == null || kamelet.isBlank()) {
+            throw new ToolCallException("Kamelet name is required", null);
+        }
+
+        try {
+            String version = kameletsVersion != null && 
!kameletsVersion.isBlank()
+                    ? kameletsVersion : RuntimeType.KAMELETS_VERSION;
+
+            KameletModel km = KameletCatalogHelper.loadKameletModel(kamelet, 
version, null);
+            if (km == null) {
+                throw new ToolCallException("Kamelet not found: " + kamelet, 
null);
+            }
+
+            List<KameletOptionInfo> options = new ArrayList<>();
+            if (km.properties != null) {
+                for (KameletOptionModel om : km.properties.values()) {
+                    options.add(new KameletOptionInfo(
+                            om.name,
+                            om.description,
+                            om.type,
+                            om.required,
+                            om.defaultValue,
+                            om.example,
+                            om.enumValues));
+                }
+            }
+
+            return new KameletDetailResult(
+                    km.name,
+                    km.type,
+                    km.supportLevel,
+                    km.description,
+                    options,
+                    km.dependencies);
+        } catch (ToolCallException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new ToolCallException("Failed to get kamelet doc: " + 
e.getMessage(), e);
+        }
+    }
+
+    // Result record classes for Jackson serialization
+
+    public record KameletListResult(int count, String kameletsVersion, 
List<KameletInfo> kamelets) {
+    }
+
+    public record KameletInfo(String name, String type, String supportLevel, 
String description) {
+    }
+
+    public record KameletDetailResult(String name, String type, String 
supportLevel, String description,
+            List<KameletOptionInfo> options, List<String> dependencies) {
+    }
+
+    public record KameletOptionInfo(String name, String description, String 
type, boolean required,
+            String defaultValue, String example, List<String> enumValues) {
+    }
+}

Reply via email to