[
https://issues.apache.org/jira/browse/CAMEL-24310?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-24310 started by Federico Mariani.
------------------------------------------------
> camel-mcp-server module: bridge, McpServerEngine SPI and default engine
> -----------------------------------------------------------------------
>
> Key: CAMEL-24310
> URL: https://issues.apache.org/jira/browse/CAMEL-24310
> Project: Camel
> Issue Type: Sub-task
> Components: camel-ai
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
> Labels: ai, mcp
>
> Create the {{camel-mcp-server}} module(s) under components/camel-ai, split
> into a runtime-agnostic bridge + SPI and a Vert.x serving engine for Camel
> Main / JBang (mirroring the {{PlatformHttpEngine}} precedent so other
> runtimes plug native servers — camel-quarkus provides a
> quarkus-mcp-server-backed engine, camel-spring-boot a Spring AI 2.x-backed
> engine).
> h3. camel-mcp-server (bridge + SPI)
> * {{McpServerEngine}} SPI: {{initialize(McpServerInfo)}},
> {{toolAdded(McpServerTool)}}, {{toolRemoved(String)}}. Single logical MCP
> server per CamelContext.
> * {{McpServerTool}}: name, description, pre-built input JSON Schema string
> AND structured {{ParameterDef}} map (both already carried by {{AiToolSpec}},
> engines pick whichever fits), and a blocking {{McpToolCallHandler}} returning
> {{McpToolCallResult(text, isError)}}.
> * The bridge (internal CamelContext service): filters {{AiToolRegistry}} by
> {{mcp-tags}} (never the untagged default pool — note {{getToolsByTag()}}
> includes it, so the bridge must select from the tag-keyed snapshot), refuses
> flat-namespace name collisions with an ERROR log (tools arrive as registry
> listener events during startup, so a uniform refuse-loudly policy replaces
> fail-fast), subscribes to the registry listener (CAMEL-24309) before taking
> the initial snapshot (idempotent {{toolAdded}}), wraps each {{AiToolSpec}}
> into an {{McpServerTool}} whose handler creates the exchange from the tool's
> endpoint ({{createExchange}}/{{releaseExchange}}), calls {{AiToolExecutor}}
> under the configured per-call timeout (executor-service + bounded wait; a
> timed-out route keeps running server-side and is documented as such), and
> maps {{AiToolResult}} to a *pre-sanitized* {{McpToolCallResult}} — engines
> can never see or leak raw route exception messages.
> * Engine resolution: registry bean of type {{McpServerEngine}} wins;
> otherwise FactoryFinder
> ({{META-INF/services/org/apache/camel/mcp-server-engine}});
> enabled-but-no-engine fails startup with a clear message.
> * MUST NOT depend on the MCP Java SDK, Vert.x or platform-http — add a
> build-level enforcer rule so no SDK type can leak into the SPI jar (a
> compile-time leak would drag Reactor onto the Quarkus / Spring Boot
> classpath).
> * Ships the engine conformance kit as a test-jar (see CAMEL-24313).
> h3. camel-mcp-server-engine-vertx
> * Official MCP Java SDK: {{io.modelcontextprotocol.sdk:mcp-core}} +
> {{mcp-json-jackson2}} (version already managed in the parent POM for
> camel-openai).
> * Custom {{McpStreamableServerTransportProvider}} for Vert.x (the SDK ships
> only servlet + stdio server transports): registers POST/GET/DELETE handlers
> for {{camel.server.mcp-path}} on the main HTTP server's router via
> {{VertxPlatformHttpRouter.lookup(camelContext)}} — MCP serves on
> {{camel.server.port}} and inherits the main server lifecycle.
> {{Mcp-Session-Id}} handling, {{Last-Event-ID}} replay and message routing are
> delegated to the SDK's {{McpStreamableServerSession}}; the transport writes
> SSE frames directly to the async {{HttpServerResponse}} (chunked,
> backpressure via {{drainHandler}}), strips inbound {{camel*}} /
> {{org.apache.camel.*}} headers and bounds the request body read.
> * Verify whether main-server authentication handlers
> ({{camel.server.authenticationEnabled}} / JWT) apply to router-registered
> routes or must be attached explicitly.
> * Declared as a *runtime* dependency of {{camel-mcp-server}} so plain Camel
> Main / JBang users need a single dependency; camel-quarkus and
> camel-spring-boot exclude it.
> Register both modules in {{MojoHelper.getComponentPath()}} for the camel-ai
> parent folder.
> ----
> _This issue was drafted by Claude Code on behalf of Federico Mariani._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)