davsclaus opened a new pull request, #28803: URL: https://github.com/apache/camel/pull/28803
Fixes [CAMEL-26298](https://issues.apache.org/jira/browse/CAMEL-26298). `camel run tools.yaml --mcp-stdio --mcp-tags=demo` stopped at startup with `ServiceConfigurationError: No McpJsonMapperSupplier available for creating McpJsonMapper` (exit code 70), on 4.23.0 and on main. **Cause:** `StdioMcpServerEngine.initialize()` called `McpJsonDefaults.getMapper()`. The MCP SDK finds the mapper with `ServiceLoader.load(Class)`, so with the thread context class loader. `initialize()` runs while Camel Main configures the CamelContext (`BaseMainSupport.setupMcpServer` → `addService`), and then the TCCL is the class loader of Camel CLI, which cannot see the downloaded jars such as `mcp-json-jackson2`. CamelContext only sets its application context class loader as TCCL while it starts. The Vert.x (HTTP) engine looks the mapper up in `doStart()`, which is why `camel.server.mcp-enabled=true` over HTTP works. Switching to `mcp-json-jackson3` would not help: it is found the same way. **What changes:** - `StdioMcpServerEngine` looks the mapper up when it needs it (start, or a tool added before start), with the application context class loader of CamelContext as TCCL (the class loader of the engine when there is none). - In stdio mode `System.out` points at stderr while the engine runs, and the transport writes to the original stdout. A `stream:out` endpoint, a `System.out.println` in a bean or a library banner no longer breaks the MCP stream (the second problem in the ticket). Stopping the engine restores `System.out`. - The engine stops the CamelContext when the client closes stdin, so the process exits, as the MCP stdio transport expects. Before, `camel run` kept running after the client went away. - `camel run --mcp-stdio` no longer prints the configuration values of `camel config` (`Running integration with the following configuration: ...`) to stdout: the quiet printer of stdio mode was only set after they were printed. - mcp-server.adoc describes the `System.out` redirect and the exit on end of stdin. **Tests:** - `StdioMcpServerProcessIT` (the MCP SDK client launching a subprocess) has three new tests: a thread context class loader that cannot see the mapper's service file while Camel Main configures (as in Camel CLI), a tool that writes to `System.out` followed by another call, and the process exiting when stdin is closed. Without the engine change, the first two fail (client initialize fails, and a call times out). - `RunMcpStdioConfigurationTest`: the configuration values are printed without `--mcp-stdio` and not with it. - camel-mcp-server: 59 unit tests and 5 ITs pass. - End to end with `camel run tools.yaml --mcp-stdio --mcp-tags=demo` and a JSON-RPC client: initialize, tools/list, a tool that writes to `stream:out`, then another tool call all work; stdout has only MCP frames, and the process exits with 0 when stdin is closed. _Claude Code on behalf of davsclaus (Claus Ibsen)_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_012nJsFsjqqFiwroeHRWaKbS -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
