[
https://issues.apache.org/jira/browse/CAMEL-25642?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Federico Mariani reassigned CAMEL-25642:
----------------------------------------
Assignee: Federico Mariani
> camel-jbang-mcp - defects in the tools outside the catalog path, found in a
> code review: runtime wiring (receive, routeId, prompts), migration recipe
> data, OpenAPI scaffold
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25642
> URL: https://issues.apache.org/jira/browse/CAMEL-25642
> Project: Camel
> Issue Type: Bug
> Components: camel-jbang-mcp
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
>
> Umbrella for what a code review of all 86 tools (October 2026, main
> 4.23.0-SNAPSHOT) found in tools that no session of the coding-agent
> evaluation ever called, so none of it has eval evidence; everything below was
> verified by reading the code. Three independent PRs, one per section; the
> full per-tool review with file:line anchors is attached to the consolidation
> issue's thread.
> h2. A. Runtime tools wiring
> Found while reviewing all 86 tools of camel-jbang-mcp on main
> (4.23.0-SNAPSHOT). Five wiring defects in the runtime group, one PR.
> h3. 1. {{camel_runtime_receive}} starts a permanent consumer, steals messages
> and returns none
> {{RuntimeTools.java:693-709}} sends {{enabled=true, endpoint}} to the
> {{receive}} console and returns its answer.
> {{core/camel-console/.../ReceiveDevConsole.java:245-253}} then creates and
> starts a {{Consumer}} on the matching endpoint that keeps running until
> {{enabled=false}} is sent, which no MCP tool ever sends; received messages go
> into the console's queue, read only with {{dump=true}}, which is never sent
> either. So the tool consumes messages from the real route (seda, jms, kafka,
> ...), leaks a consumer per call, and the answer is just {{{enabled,
> endpoints}}} while the description says "consumes one message from the
> endpoint". It is annotated {{readOnlyHint=false, destructiveHint=false}}, so
> a read-write client may call it.
> Fix: either drop the tool, or implement it as enable, wait for one message
> with a timeout, dump, disable, in one call, and mark it destructive.
> h3. 2. {{routeId}} is silently ignored by route_dump, route_structure,
> route_analysis (and the {{routeFilter}} of ai_trace)
> {{camel-jbang-core/.../commands/ai/ToolRegistry.java:250, 261, 691, 694}} put
> the pattern under the key {{id}};
> {{dsl/camel-cli-connector/.../LocalCliConnector.java:750}}
> ({{doActionRouteDumpTask}}) reads {{root.getString("filter")}} and {{:775}}
> ({{doActionRouteStructureTask}}) reads {{getStringOrDefault("filter", "*")}}.
> The CLI's own commands send {{filter}} ({{CamelRouteDumpAction.java:120}}).
> Net effect: every call dumps all routes regardless of {{routeId}}, which with
> the unbounded output of these consoles is the largest answer the server
> gives. Only {{processor-detail}} works because
> {{LocalCliConnector.java:808-811}} accepts both {{routeId}} and {{id}}. No
> test in camel-jbang-core or camel-jbang-mcp covers these registry tools. The
> same tools never pass the {{limit}}/{{brief}} the consoles support
> ({{RouteDumpDevConsole.java:75}}, {{RouteStructureDevConsole.java:78}}).
> h3. 3. The {{camel_diagnose_route}} and {{camel_optimize_route}} prompts call
> tools that do not exist
> {{PromptDefinitions.java:242-266, 322-342}} instruct the model to call
> {{get_context}}, {{get_routes}}, {{get_health}}, {{get_errors}},
> {{get_history}}, {{get_route_source}}, {{get_top_processors}},
> {{get_inflight}}, {{get_blocked}}, {{get_memory}}, {{get_endpoints}},
> {{get_route_analysis}}, {{get_eip_stats}}, {{get_route_dump}}. Those are
> registry names; the MCP tools are {{camel_runtime_context}},
> {{camel_runtime_routes}}, ..., and {{get_top_processors}} has no counterpart
> at all ({{camel_runtime_top}}). Both prompts are dead on arrival.
> h3. 4. {{camel_runtime_ai_trace}}
> {{AiTraceTools.java:77}}: {{nameOrPid}} has no {{required = false}}
> ({{ToolArg.required()}} defaults to true in quarkus-mcp-server 2.0.2),
> contradicting the doc ("all tools accept an optional nameOrPid") and the
> other 41 runtime tools. {{:112-120}} swallows {{ToolExecutionException}}
> (including IPC timeouts) and returns {{{}}}, so a dead process yields the
> success answer "No AI components detected".
> h3. 5. Smaller
> * {{camel_runtime_http_request}} ({{RuntimeTools.java:322-341}}) drops the
> {{timeoutSeconds}} argument the registry declares
> ({{ToolRegistry.java:479}}), so the TUI and the MCP server differ.
> * {{camel_runtime_memory_leak}}: default mode {{dual}}
> ({{RuntimeTools.java:564}}) runs two JFR recordings synchronously with
> {{Thread.sleep(3000)}} polling ({{:582-669}}), about 90 s, longer than most
> MCP client timeouts; the argument description says "default 60" but dual uses
> 30 ({{:583}}); {{Integer.parseInt(duration)}} at {{:585}} is unguarded.
> * {{camel_runtime_history}} says "always captured (no need to enable
> tracing)" ({{:685-687}}); {{BacklogTracer.java:139}} records only when
> {{(enabled || standby) && isMessageHistory()}}. To verify at runtime and
> document.
> h3. Hints while here
> {{camel_runtime_send}} is {{destructiveHint=true}} in MCP ({{:440}}) but not
> in the registry ({{:330}}); {{camel_runtime_route_control}} is destructive
> for all four commands ({{:243}}) while the registry marks only {{stop}}
> ({{:562}}); {{camel_runtime_trace}} is {{readOnlyHint=false}} for the
> {{dump}} action too ({{:462}}), so read-only clients cannot dump traces;
> {{camel_runtime_heap_dump}} does not validate {{name}} for path separators
> ({{:524-526}}).
> h2. B. Migration and dependency tools answer with wrong data
> Found while reviewing all tools of camel-jbang-mcp on main (4.23.0-SNAPSHOT);
> all in the migration/dependency group
> ({{dsl/camel-jbang/camel-jbang-mcp/.../mcp/}}), verified by reading.
> h3. camel_migration_recipes ({{MigrationTools.java}})
> * {{:241-244}}: the Quarkus command uses the *Camel* {{targetVersion}} ("e.g.
> 4.18.0", {{:217}}) as the {{quarkus-maven-plugin}} version:
> {{io.quarkus.platform:quarkus-maven-plugin:4.18.0:update}} does not exist. It
> needs the Quarkus platform version ({{camel_version_list}} already returns
> {{quarkusVersion}} per release).
> * {{:265-269}}: the Spring Boot command activates
> {{org.apache.camel.upgrade.CamelMigrationRecipe}} for both artifacts. In
> {{camel-spring-boot-upgrade-recipes}} the recipe is
> {{org.apache.camel.upgrade.CamelSpringBootMigrationRecipe}} (verified in
> apache/camel-upgrade-recipes, {{META-INF/rewrite/*.yaml}}), so OpenRewrite
> fails with "recipe not found".
> * {{:41}}: {{OPENREWRITE_VERSION = "6.29.0"}} hardcoded; the recipes README
> uses the unversioned {{rewrite-maven-plugin:run}}.
> h3. camel_migration_compatibility ({{MigrationTools.java}})
> * {{:146-151}} and {{:277-281}}: "Camel 4.19+ requires Java 21+", reported as
> a *blocker* ({{compatible=false}}) for every Java 17 user targeting 4.19 or
> later. The catalog's {{camel-releases.json}} says jdk {{17,21}} for 4.19.0
> and {{17,21,25}} for 4.20 to 4.22, and {{camel_version_list}} reads exactly
> that, so the two tools contradict each other. Derive from
> {{catalog.camelReleases()}}.
> * {{:120}}: the required {{camelComponents}} argument is validated and never
> used; the answer is two static guide URLs plus the wrong Java rule. With the
> Java check moved to {{camel_migration_recipes}} the tool can go (see the
> consolidation issue).
> h3. camel_dependency_check / camel_dependency_security_audit /
> camel_migration_analyze
> * {{DependencyCheckTools.java:179}} compares the catalog {{artifactId}}
> ({{camel-kafka}}) with the POM artifactIds exactly. Spring Boot POMs have
> {{camel-kafka-starter}} and Quarkus {{camel-quarkus-kafka}}, so every
> component is reported "missing" there. The runtime mapping that
> {{camel_dependency_for_class}} has ({{DependencyLookup.java}}) is what this
> needs.
> * {{DependencyData.java:55-57}} recommends
> {{org.apache.camel.quarkus:camel-quarkus-bom:<camelVersion>}}; the Camel
> version is not a camel-quarkus-bom version.
> * {{MigrationData.java:234-237}} collects artifactIds from
> {{<dependencyManagement>}} and plugin dependencies too, so a
> managed-but-unused component counts as declared.
> * {{DependencySecurityAuditTools.java:78}}: when the POM has no detectable
> Camel version (parent-managed, the normal Spring Boot/Quarkus case) the audit
> uses the *server's own* catalog version and reports {{clean=true}} ({{:149}})
> with no warning ({{DependencyCheckTools.java:128-133}} at least says
> "unknown"). {{AdvisoryService.java:119-128}} matches by
> {{advisory.getComponents()}} only, and 16 of the 76 bundled advisories carry
> no components, so they can never be reported here nor by
> {{camel_route_harden_context}} ({{HardenTools.java:151-171}}): "clean" is not
> "no CVEs". {{isReachable}} returns true when no routes are passed
> ({{:174-176}}) and the recommendation still says "directly used in routes"
> ({{:200-205}}). The upgrade recommendation ({{:214-218}},
> {{DependencyCheckTools.java:135-142}}) compares against
> {{catalog.getCatalogVersion()}}, so a SNAPSHOT server recommends upgrading
> 4.22.1 to 4.23.0-SNAPSHOT; {{camelReleases()}} has the real latest.
> h3. Runtime detection ({{MigrationData.java}})
> * {{:155-158}} sets {{isWildfly}} on {{<packaging>war}} and {{runtimeType()}}
> ({{:527-529}}) checks WildFly first, so a Spring Boot WAR (Tomcat deploy) is
> sent to {{camel_migration_wildfly_karaf}}, told "WildFly Camel subsystem is
> discontinued" and instructed to recreate the project from an archetype
> ({{MigrationWildflyKarafTools.java:50-53}}).
> * The markers {{maven-war-plugin}}, {{maven-bundle-plugin}},
> {{org.wildfly.plugins}} ({{:86-95}}) are compared against {{<dependency>}}
> elements only ({{:221-232}}), never {{<plugin>}}: dead markers.
> h3. camel_properties_translate ({{PropertiesTranslateTools.java:274-280}})
> Every {{camel.springboot.*}} key is rewritten to {{camel.main.*}}, although
> the 4.5 guide says only the special Spring Boot options keep the
> {{camel.springboot}} name ({{camel.springboot.lenient-configuration-binding}}
> still exists), which produces an invalid
> {{camel.main.lenient-configuration-binding}}. {{:198}} also calls
> {{camel.server.*}} "jbang-only"; it is camel-main.
> Related: CAMEL-25536 (guide search ranking), the consolidation issue (drop
> {{camel_migration_compatibility}}, fold {{camel_migration_analyze}} into
> {{camel_dependency_check}}).
> h2. C. camel_openapi_scaffold and camel_openapi_mock_guidance disagree with
> camel-rest-openapi
> {{OpenApiTools.java}} (camel-jbang-mcp, main) scaffolds routes and mock files
> for the {{rest-openapi}} component, with rules that do not match what
> {{components/camel-rest-openapi/.../DefaultRestOpenapiProcessorStrategy.java}}
> does.
> * *Generated operation id*: for an operation without {{operationId}} the tool
> builds {{GENOPID_GET_pets_id}} ({{OpenApiTools.java:98}}: {{"GENOPID_" +
> method + path.replace("/", "_").replace("{", "").replace("}", "")}}, and
> {{:376-377}}); the component builds {{GENOPID_GET.pets._id_}}
> ({{DefaultRestOpenapiProcessorStrategy.java:169-171}}: {{/}} becomes {{.}},
> {{\{}}/{{\}}}} become {{_}}). The scaffolded {{direct:GENOPID_...}} routes
> are never bound, so every spec operation without an id answers 404 or falls
> into the missing-operation mode.
> * *Mock files*: the tool says {{camel-mock/<path>.<method><ext>}} with
> {{_id_}} placeholders ({{:279-282}}) and returns a
> {{directoryStructure}}/{{mockFiles}} listing built that way; the component
> matches a resource whose extension-stripped location *ends with the request
> path* ({{:296-299}}), with no method suffix and the real path values. The
> whole mock listing is wrong.
> * {{:436-439}}: "apiKey in query is supported by Camel" reads as enforcement;
> the component enforces none of the security schemes.
> * {{:66-71}}: "OpenAPI 3.1 ... may not be supported" is unverified;
> swagger-parser 2.1 parses 3.1 and the component has no 3.0-only path.
> {{camel_openapi_mock_guidance}} is static mode text ({{:486-500}}) plus a
> per-operation walk that duplicates {{camel_openapi_scaffold}}'s; the
> consolidation issue proposes folding it into the scaffold's answer when
> {{missingOperation=mock}}.
> h3. Fix
> Take the id and mock-location rules from the component (expose them as static
> helpers in camel-rest-openapi if needed, so the two cannot drift), and a test
> that scaffolds the petstore spec and binds the routes with the real component.
> _Claude Code on behalf of Croway_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)