Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions bom/camel-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,16 @@
<artifactId>camel-master</artifactId>
<version>4.22.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mcp-server</artifactId>
<version>4.22.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mcp-server-api</artifactId>
<version>4.22.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mdc</artifactId>
Expand Down
10 changes: 10 additions & 0 deletions catalog/camel-allcomponents/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1457,6 +1457,16 @@
<artifactId>camel-master</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mcp-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mcp-server-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mdc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ main
mapstruct-component
marshal-eip
master-component
mcp-server
mdc
message
message-broker
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
= MCP Server Component
:doctitle: MCP Server
:shortname: mcp-server
:artifactid: camel-mcp-server
:description: Expose ai-tool routes as MCP tools over streamable HTTP
:since: 4.22
:supportlevel: Preview
:tabs-sync-option:

*Since Camel {since}*

The camel-mcp-server module exposes Camel routes registered via the
xref:ROOT:ai-tool-component.adoc[ai-tool] component as tools of a
https://modelcontextprotocol.io[Model Context Protocol] (MCP) server, served
over MCP streamable HTTP. No route is needed for the server itself: add the
dependency, configure which tags to expose, and every matching `ai-tool` route
becomes an MCP tool that any MCP client (another Camel application, an IDE, a
coding agent) can discover and call.

Maven users will need to add the following dependency to their `pom.xml`:

[source,xml]
----
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mcp-server</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
----

== Architecture

The module is split in two artifacts:

* `camel-mcp-server-api` — the runtime-agnostic _bridge_ and the small
`McpServerEngine` SPI. The bridge owns tool selection (tags), execution via
the shared `AiToolExecutor` (per-call timeout, error sanitization) and reacts
to `AiToolRegistry` changes when routes start and stop. It has no dependency
on the MCP Java SDK.
* `camel-mcp-server` — the serving engine for Camel Main and Camel JBang,
built on the official MCP Java SDK with a Vert.x streamable HTTP transport.
The MCP endpoint is registered on the Camel main HTTP server's router, so it
serves on the main server port (`camel.server.port`) and inherits its
lifecycle, authentication and CORS configuration.

Engine resolution mirrors the platform-http engine: a bean of type
`McpServerEngine` in the Camel registry wins; otherwise the engine is
discovered on the classpath. Other runtimes plug native engines through the
same SPI: on Quarkus the `camel-quarkus-mcp-server` extension serves through
the Quarkiverse `quarkus-mcp-server` (configured via `quarkus.mcp.server.*`),
and on Spring Boot the starter serves through the Spring AI MCP server
(configured via `spring.ai.mcp.server.*`). Bridge behavior — tag selection,
timeout, sanitization — is identical on every runtime and verified by a shared
conformance test kit.

== Usage

Define tools as regular `ai-tool` routes and give them tags:

[tabs]
====
Java::
+
[source,java]
----
from("ai-tool:query_db?tags=crm" +
"&description=Query customer database" +
"&parameter.customerId=string" +
"&parameter.customerId.description=The customer id" +
"&parameter.customerId.required=true")
.to("jdbc:dataSource");
----

XML::
+
[source,xml]
----
<route>
<from uri="ai-tool:query_db?tags=crm&amp;description=Query customer database&amp;parameter.customerId=string&amp;parameter.customerId.description=The customer id&amp;parameter.customerId.required=true"/>
<to uri="jdbc:dataSource"/>
</route>
----

YAML::
+
[source,yaml]
Comment thread
Croway marked this conversation as resolved.
----
- route:
from:
uri: ai-tool:query_db
parameters:
tags: crm
description: "Query customer database"
parameter.customerId: string
parameter.customerId.description: "The customer id"
parameter.customerId.required: "true"
steps:
- to:
uri: jdbc:dataSource
----
====

Start the MCP server by adding the `McpServerBridge` service to the
CamelContext, selecting the tags to expose:

[source,java]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

show the application properties configuration first. the hand coded is for advanced users

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do in #25309

----
McpServerConfiguration configuration = new McpServerConfiguration();
configuration.setTags("crm,notify");
camelContext.addService(new McpServerBridge(configuration));
----

The MCP endpoint is then served at `http://<host>:<port>/mcp` on the Camel
main HTTP server. Any MCP client can connect over streamable HTTP, for
example another Camel integration using the
xref:ROOT:openai-component.adoc[camel-openai] MCP client:

[source,java]
----
from("direct:agent")
.to("openai:chat-completion"
+ "?model={{llm.model}}"
+ "&autoToolExecution=true"
+ "&mcpServer.myCamelTools.transportType=streamableHttp"
+ "&mcpServer.myCamelTools.url=http://localhost:8080/mcp");
----

== Options

The `McpServerConfiguration` options:

[width="100%",cols="2,5,2,1",options="header"]
|===
| Option | Description | Default | Owner

| `tags` | Comma-separated list of ai-tool tags to expose as MCP tools. Only
tools registered under one of these tags are published; the untagged
default pool is never exposed. When not set, no tools are published. | |
bridge
| `toolTimeout` | Per-call tool execution timeout in milliseconds. A call
exceeding the timeout returns an error result to the MCP client; the
underlying route keeps running until it completes on its own. | `20000` |
bridge
| `path` | HTTP path where the MCP endpoint is served. | `/mcp` | engine
| `serverName` | MCP server name advertised to clients. | CamelContext name |
engine
|===

Bridge-owned options are honored identically on every runtime. Engine-owned
options are consumed by the Vert.x engine only; on runtimes with a native
engine (Quarkus, Spring Boot) the native configuration decides serving
concerns and a startup WARN is logged when an ignored option is set.

== Protocol

This section describes the Vert.x engine shipped in `camel-mcp-server`, which
serves on Camel Main and Camel JBang. On Quarkus and Spring Boot the transport
is owned by the native engine instead — quarkus-mcp-server and the Spring Boot
embedded HTTP server (Spring AI MCP server) respectively — and the details
below do not apply.

The Vert.x engine implements the MCP streamable HTTP transport:
Comment thread
Croway marked this conversation as resolved.

* `POST /mcp` answering `application/json` or `text/event-stream` depending on
the request,
* a long-lived `GET /mcp` SSE channel for server notifications, with
`Last-Event-ID` replay,
* session management via the `Mcp-Session-Id` header and `DELETE /mcp` for
session termination.

Tools appearing or disappearing (routes starting and stopping) emit
`notifications/tools/list_changed` to connected clients.

== Security

External MCP clients are *untrusted senders* under the
xref:manual::security-model.adoc[Camel security model]. The module applies the
following rules:

* *Explicit opt-in per tool*: only tools whose tags intersect the configured
`tags` are exposed. The untagged default pool is never exposed implicitly.
* *Flat namespace protection*: a tool whose name collides with an already
exposed tool is refused with an ERROR log — never silently replaced.
* *Error sanitization*: route exceptions are mapped to a generic error
message; the cause is logged server-side and never sent to the client.
Argument validation messages (missing or invalid parameters) are returned
as-is.
* *Bounded execution*: every call is subject to the `toolTimeout`. Note that a
timed-out route keeps running server-side until it completes; the timeout
bounds the MCP request, not the route.
* *Authentication*: the MCP endpoint is served through the main HTTP server
router, so platform-http authentication (basic, JWT via
`camel.server.authentication*` options) applies to it. The MCP
specification's authorization model is OAuth 2.1; see
xref:oauth.adoc[camel-oauth] for resource-server style
protection. On Quarkus and Spring Boot, authentication is owned by the
native runtime security.

== Runtime notes

* *Camel Main / JBang*: requires the Camel main HTTP server
(`camel.server.enabled=true` with `camel-platform-http-main`, automatic
with Camel JBang) or a `VertxPlatformHttpServer` service. Serving is fully
asynchronous: tool calls are offloaded to the Vert.x worker pool and the
long-lived SSE channel does not occupy a worker thread.
* *Quarkus*: use the `camel-quarkus-mcp-server` extension (serves through
quarkus-mcp-server; the MCP Java SDK is not on the classpath).
* *Spring Boot*: use the `camel-mcp-server-starter` (serves through the
Spring AI MCP server).
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lra
mail-microsoft-oauth
main
management
mcp-server
mdc
micrometer-observability
micrometer-prometheus
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"other": {
"kind": "other",
"name": "mcp-server",
"title": "MCP Server",
"description": "Expose ai-tool routes as MCP tools over streamable HTTP",
"deprecated": false,
"firstVersion": "4.22.0",
"label": "ai",
"supportLevel": "Preview",
"groupId": "org.apache.camel",
"artifactId": "camel-mcp-server",
"version": "4.22.0-SNAPSHOT"
}
}
Loading
Loading