MCP Server
JVM since3.39.0 Native since3.39.0
The MCP Server extension exposes Camel routes registered via the ai-tool component as tools, and ai-resource routes as resources, of a Model Context Protocol (MCP) server, served through the quarkiverse quarkus-mcp-server extension. No route is needed for the server itself: add the extension, tag the ai-tool and ai-resource routes to expose, and any MCP client (another Camel application, an IDE, a coding agent) can discover and use them.
Tool semantics — tag-based opt-in (the untagged default pool is never exposed), flat-namespace collision refusal, per-call timeout and error sanitization — are owned by the runtime-agnostic camel-mcp-server-api bridge and are identical on every Camel runtime. Serving concerns (endpoint path, transports, authentication) are owned by quarkus-mcp-server and configured via quarkus.mcp.server.*.
Maven coordinates
Or add the coordinates to your existing project:
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-mcp-server</artifactId>
</dependency> Check the User guide for more information about writing Camel Quarkus applications.
Usage
Define tools as regular ai-tool routes and give them tags:
from("ai-tool:query_db?tags=crm&description=Query customer database"
+ "¶meter.customerId=string¶meter.customerId.required=true")
.to("jdbc:dataSource"); or in YAML DSL:
- route:
from:
uri: "ai-tool:send_email"
parameters:
description: "Send email notification"
tags: "notify"
parameter.to: string
parameter.to.description: "Recipient address"
parameter.to.required: "true"
parameter.subject: string
parameter.priority: string
parameter.priority.enum: "low,normal,high"
steps:
- to: "smtp://mail.example.com" Tool parameters are declared with the parameter.NAME options: the value is the JSON type (string, integer, number, boolean), and the parameter.NAME.description, parameter.NAME.required and parameter.NAME.enum options refine the generated input schema. Arguments arrive as message headers in the route (${header.customerId}).
Structured tool output
Tools declaring their output with the outputSchema or outputParameter.NAME options publish it as the MCP outputSchema. The route body must then be JSON: MCP clients receive it as structuredContent, next to the same JSON as text content. See Structured Tool Output in the AI Tool component documentation.
In native mode, an outputSchema loaded from classpath: must be embedded in the native executable.
Resources
Add the camel-quarkus-ai-resource extension to define ai-resource routes: the tagged ones are served as MCP resources, selected by the same quarkus.camel.mcp-server.tags. Like tools, they follow the route lifecycle and clients are notified via notifications/resources/list_changed. A failed read returns a JSON-RPC error with the generic message Resource read failed; a read exceeding quarkus.camel.mcp-server.resource-timeout returns Resource read timed out. Resource names must be unique, as quarkus-mcp-server requires: a resource whose name is already taken, or whose uri is already used by a resource the application registers with quarkus-mcp-server, is refused with an ERROR log, while its route keeps running.
Combining the Camel and quarkus-mcp-server configuration
The configuration is split by ownership: quarkus.camel.mcp-server. decides *which tools and resources exist and how they execute (identical semantics on every Camel runtime, except for the tool and resource clashes refused by quarkus-mcp-server), while quarkus.mcp.server. decides *how the server is exposed. Both are set side by side in application.properties:
# Camel-owned: tool and resource selection and execution
quarkus.camel.mcp-server.tags = crm,notify
quarkus.camel.mcp-server.tool-timeout = 10000
quarkus.camel.mcp-server.resource-timeout = 5000
# quarkus-mcp-server-owned: serving and server identity
quarkus.mcp.server.server-info.name = my-integration-app
quarkus.mcp.server.server-info.version = 1.0.0
quarkus.mcp.server.http.root-path = /mcp
# quarkus-mcp-server-owned: diagnostics while developing
quarkus.mcp.server.traffic-logging.enabled = true
quarkus.mcp.server.traffic-logging.text-limit = 200 See the quarkus-mcp-server configuration reference for the full list of quarkus.mcp.server.* properties (transports, dev UI, authentication, guardrails, pagination, timeouts).
Connecting MCP clients
Any MCP client can connect over streamable HTTP. Another Camel integration can consume the tools with the camel-openai MCP client and automatic tool execution:
from("direct:agent")
.to("openai:chat-completion"
+ "?model={{llm.model}}"
+ "&autoToolExecution=true"
+ "&mcpServer.myCamelTools.transportType=streamableHttp"
+ "&mcpServer.myCamelTools.url=http://localhost:8080/mcp"); A coding agent or IDE is configured with the same URL, e.g. in an mcp.json-style client configuration:
{
"mcpServers": {
"my-integration-app": {
"type": "http",
"url": "http://localhost:8080/mcp"
}
}
} Serving over stdio
Out of the box the tools are served over streamable HTTP. MCP clients that launch the server as a subprocess speak over stdin/stdout instead — add the stdio transport alongside the extension:
<dependency>
<groupId>io.quarkiverse.mcp</groupId>
<artifactId>quarkus-mcp-server-stdio</artifactId>
<!-- the same version as the quarkus-mcp-server-http extension pulled in
by camel-quarkus-mcp-server; the transports share their core module -->
<version>1.13.1</version>
</dependency> The stdio transport is active as soon as it is on the classpath (quarkus.mcp.server.stdio.enabled defaults to true), and the same Camel tools are then served over both transports. To serve over stdio only, disable the HTTP transport of the default MCP server:
quarkus.mcp.server."<default>".http.enabled = false The server name of the default MCP server is the literal string <default>, so it has to be quoted. Conversely, quarkus.mcp.server.stdio.enabled = false keeps the stdio extension on the classpath without activating it, which is useful when the same application is deployed both ways.
Because stdout carries the MCP protocol, nothing else may be written to it; quarkus-mcp-server-stdio takes care of this by routing console logging to stderr. A stdio server is typically built as a native executable and launched by the client:
{
"mcpServers": {
"my-integration-app": {
"command": "/path/to/target/my-integration-app-1.0.0-runner"
}
}
} See the quarkus-mcp-server stdio guide and the configuration reference for the transport options. On Spring Boot the equivalent setup is described in the Spring AI MCP Server Boot Starter documentation.
Mixing with quarkus-mcp-server annotated tools
Camel tools coexist with tools defined natively with quarkus-mcp-server — both are served by the same MCP server and appear in the same tools/list. For example, a @Tool-annotated business method:
public class CalculatorTools {
@Tool(name = "add_numbers", description = "Add two numbers")
String add(
@ToolArg(description = "First addend") long a,
@ToolArg(description = "Second addend") long b) {
return String.valueOf(a + b);
}
} is exposed alongside the ai-tool routes. Annotated tools are registered at build time; Camel tools are added and removed dynamically with the route lifecycle. Choose distinct tool names — MCP has a flat tool namespace: a Camel tool whose name is already taken by a tool of the application is refused with an ERROR log, while its route keeps running.
Dynamic tools
The exposed tool list follows the route lifecycle: stopping or suspending an ai-tool route removes its tool, starting or resuming it publishes the tool again, and connected clients are notified via notifications/tools/list_changed:
camelContext.getRouteController().stopRoute("query-db-route"); // tool disappears
camelContext.getRouteController().startRoute("query-db-route"); // tool is back Error handling
Results returned to MCP clients are sanitized by the bridge: a route exception produces an error result with the generic message Tool execution failed (the cause is logged server-side and never sent to the client), a missing or invalid argument returns the validation message, and a call exceeding quarkus.camel.mcp-server.tool-timeout returns Tool execution timed out while the route keeps running until it completes on its own.
On Camel Main and Camel JBang the equivalent setup is the camel-mcp-server module with the camel.server.mcp-* options; on Spring Boot it is the camel-mcp-server-starter.
Additional Camel Quarkus configuration
| Configuration property | Type | Default |
|---|---|---|
Whether to expose ai-tool routes as MCP tools and ai-resource routes as MCP resources through the quarkus-mcp-server extension. |
|
|
Comma-separated list of tags selecting the ai-tool routes to expose as MCP tools and the ai-resource routes to expose as MCP resources. Only routes registered under one of these tags are exposed; the untagged default pools are never exposed. When not set, nothing is exposed. |
| |
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. |
|
|
Per-read resource execution timeout in milliseconds. A read exceeding the timeout returns an error to the MCP client; the underlying route keeps running until it completes on its own. |
|
|
Configuration property fixed at build time. All other configuration properties are overridable at runtime.