Mcp Server
The MCP Server starter exposes Camel routes registered via the ai-tool component as tools of a Model Context Protocol (MCP) server, served through the Spring AI MCP server over streamable HTTP. No route is needed for the server itself: add the starter, tag the ai-tool routes to expose, and any MCP client (another Camel application, an IDE, a coding agent) can discover and call 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, protocol, server identity, authentication) are owned by the Spring AI MCP server and configured via spring.ai.mcp.server.*; use spring.ai.mcp.server.protocol=STREAMABLE for the streamable HTTP transport.
Maven coordinates
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-mcp-server-starter</artifactId>
</dependency> 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 JSON Schema. Arguments arrive as message headers in the route (${header.customerId}).
Select the tags to expose in application.properties:
camel.mcp-server.tags = crm,notify
# per-call execution timeout (milliseconds, default 20000)
camel.mcp-server.tool-timeout = 10000 The streamable HTTP transport has to be selected explicitly with spring.ai.mcp.server.protocol=STREAMABLE; when the property is not set, Spring AI serves the deprecated SSE transport instead and there is no endpoint at /mcp.
Serving concerns are configured on the Spring AI MCP server — see the Spring AI MCP server documentation for the full list of spring.ai.mcp.server.* options. For example:
spring.ai.mcp.server.protocol = STREAMABLE
spring.ai.mcp.server.name = my-integration-app
spring.ai.mcp.server.version = 1.0.0
spring.ai.mcp.server.streamable-http.mcp-endpoint = /mcp 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: the starter brings in spring-ai-starter-mcp-server-webmvc. MCP clients that launch the server as a subprocess speak over stdin/stdout instead, which Spring AI serves with the plain spring-ai-starter-mcp-server. Swap the transport starter:
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-mcp-server-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
<version>2.0.0</version>
</dependency> and enable the stdio transport:
spring.ai.mcp.server.stdio = true
spring.main.web-application-type = none
spring.main.banner-mode = off
# stdout carries the MCP protocol, so nothing else may be written to it
logging.threshold.console = OFF
logging.file.name = my-integration-app.log Because stdout carries the MCP protocol, the application must not run as a web application, the banner has to be switched off and console logging has to be turned off — writing the log to a file instead. Leaving console logging on corrupts the protocol stream, as the Spring Boot startup log is then interleaved with the JSON-RPC messages.
A stdio server is launched by the client instead of being connected to over a URL:
{
"mcpServers": {
"my-integration-app": {
"command": "java",
"args": ["-jar", "/path/to/my-integration-app-1.0.0.jar"]
}
}
} See the Spring AI MCP Server Boot Starter documentation for the transport options and the full list of spring.ai.mcp.server.* properties. On Quarkus the equivalent setup is described in the quarkus-mcp-server stdio guide.
Mixing with Spring-defined tools
Camel tools coexist with tools defined natively in Spring AI — both are served by the same MCP server and appear in the same tools/list. For example, a @McpTool-annotated bean:
@Component
public class CalculatorTools {
@McpTool(name = "add_numbers", description = "Add two numbers")
public String add(
@McpToolParam(description = "First addend", required = true) int a,
@McpToolParam(description = "Second addend", required = true) int b) {
return String.valueOf(a + b);
}
} is exposed alongside the ai-tool routes. Spring-defined tools are registered when the server is created; Camel tools are added and removed dynamically with the route lifecycle. Choose distinct tool names — MCP has a flat tool namespace.
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 isError 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 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 Quarkus it is the camel-quarkus-mcp-server extension.
Spring Boot Auto-Configuration
The starter supports 3 options, which are listed below.
| Name | Description | Default | Type |
|---|---|---|---|
camel.mcp-server.enabled | Whether to expose ai-tool routes as MCP tools through the Spring AI MCP server. Enabled by default when the starter is on the classpath. | true | Boolean |
camel.mcp-server.tags | Comma-separated list of ai-tool tags to expose as MCP tools. Only tools registered under one of these tags are exposed; the untagged default pool is never exposed. When not set, no tools are exposed. | String | |
camel.mcp-server.tool-timeout | 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 | Long |