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)