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) {
+ }
+}