Federico Mariani created CAMEL-25640:
----------------------------------------

             Summary: camel-jbang-mcp - catalog built per call for the 
authoring tools, Kamelet tools reload per call and return a hash-ordered 
subset, repeated-call detection counts failed calls
                 Key: CAMEL-25640
                 URL: https://issues.apache.org/jira/browse/CAMEL-25640
             Project: Camel
          Issue Type: Bug
          Components: camel-jbang-mcp
            Reporter: Federico Mariani


Found while reviewing all tools of camel-jbang-mcp on main (4.23.0-SNAPSHOT).

h3. 1. A catalog per call
The 15 shared authoring tools ({{camel_catalog_doc}}, {{camel_catalog_find}}, 
{{camel_validate_source}}, {{camel_error_diagnose}} ...) go through 
{{MCP/AuthoringTools.java:347}}: {{ToolRegistry.execute(tool, new 
ToolContext(), args)}}. A new {{ToolContext}} means a new 
{{DefaultCamelCatalog()}} with the cache *off* 
({{camel-jbang-core/.../ai/ToolContext.java:174-177}}), so every call re-parses 
the JSON it touches ({{ErrorDiagnoser}} iterates all EIP models per call), and 
with {{camelVersion}} a fresh Maven resolution plus a 
{{DependencyDownloaderClassLoader}} per call ({{CatalogLoader.java:70-100}}) 
that is never cached nor closed. The server's own {{CatalogService}} (cached 
per version/runtime, honours {{camel.catalog.repos}}) is not used by these 
tools. Fix: a per-version {{ToolContext}}/catalog cache in the MCP wrapper, or 
route {{ctx.catalog()}} through {{CatalogService}}.

h3. 2. Kamelet tools
* {{camel_catalog_kamelets}} ({{KameletTools.java:84-92}}) applies {{limit}} 
while iterating the {{HashMap}} of {{KameletsCatalog}} and sorts afterwards, so 
the default answer is the first 50 of 200+ Kamelets in hash order, with no 
{{total}} to signal the truncation.
* Both Kamelet tools run {{KameletCatalogHelper.loadKamelets}} (new downloader 
and classloader) on every call ({{:62, 120}}), while {{KameletDefinitions}} in 
camel-jbang-core already caches the same catalog per version for 
{{camel_catalog_doc kind=kamelet}}.
* {{:148-151}} reports any {{Throwable}} (network, Maven) as "Kamelet not 
found".
(The consolidation issue proposes folding both into 
{{camel_catalog_doc}}/{{camel_catalog_find}}; if that lands first, only the 
cache part remains.)

h3. 3. Repeated-call detection
{{RepeatedToolCalls.java:64}} increments the per-session count *before* the 
tool runs, so a call that throws (catalog download failure, unsupported file 
type in {{camel_validate_source}}, missing required argument) counts as 
answered in full, and the third attempt gets "it is in your earlier tool 
result" for an answer that never existed. Count after a successful answer only. 
Also not covered although deterministic: {{camel_catalog_docs}}, 
{{camel_component_properties}}, the Kamelet and example tools, 
{{camel_configuration_validate}}, {{camel_transform_route}}.

h3. 4. Smaller
* {{CatalogService.java:109-120, 207-211}}: {{runtime=quarkus}} with 
{{camelVersion}} and no {{platformBom}} skips the BOM lookup and calls 
{{loadQuarkusCatalog(null, ...)}}; {{ToolArgDocs.VERSION_QUERY}} explicitly 
invites that input. {{CatalogServiceTest}} covers BOM forms only.
* {{LAST_REFUSED}} ({{camel-jbang-core/.../ai/AuthoringTools.java:1203-1210}}) 
is a static map keyed by path, cleared only on a successful write, shared 
across all MCP connections: unbounded, and one client's refusal count leaks 
into another's message.
* {{CatalogTools.java:74-76}}: a negative {{limit}} ends in 
{{IllegalArgumentException}} ("Failed to list") instead of the default; 
{{ExampleTools}} treats {{<= 0}} as default and {{KameletTools}} uses it raw.

_Claude Code on behalf of Croway_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to