Federico Mariani created CAMEL-26398:
----------------------------------------

             Summary: camel-jbang-mcp - the file tools refuse an absolute file 
path, a call without directory, and a directory that does not exist yet
                 Key: CAMEL-26398
                 URL: https://issues.apache.org/jira/browse/CAMEL-26398
             Project: Camel
          Issue Type: Improvement
          Components: camel-jbang, camel-jbang-mcp
    Affects Versions: 4.23.0
            Reporter: Federico Mariani
            Assignee: Federico Mariani


Found on main (4.24.0-SNAPSHOT, commit ffef175654d1); the line numbers below 
are from that commit. The same code is in the 4.23.0 release.

h3. Reproduction

{{camel_validate_source}}, {{camel_write_file}}, {{camel_edit_file}} and 
{{camel_get_files}} take a {{directory}} (absolute) and a {{file}} relative to 
it. Models often pass the path in a different way:

{code}
camel_validate_source {"file":"/workspace/camel/routes.yaml"}
-> directory is required: the project directory with the source files
camel_validate_source 
{"file":"/workspace/camel/main-route.yaml","directory":"/workspace"}
-> file must be a path relative to the directory /workspace, not 
/workspace/camel/main-route.yaml
camel_validate_source {"file":"camel/book-orders.yaml"}
-> directory is required: the project directory with the source files
camel_validate_source {"file":"order-intake.yaml","directory":"/workspace"}     
 (the file is camel/order-intake.yaml)
-> No such file in the directory: order-intake.yaml
camel_write_file 
{"directory":"/workspace/camel","file":"application.properties","content":"..."}
   (camel/ not created yet)
-> No such directory: /workspace/camel
{code}

In each case the intended file is clear and inside the directory the agent 
works in.

Eval evidence (200 trials on 4.24.0-SNAPSHOT): 21 failed calls (Claude Haiku 
4.5: 13, DeepSeek V4.1 Flash: 5, GLM 5.3: 2, Claude Haiku 5.5: 1). Sonnet 5.5 
had none.
||Shape||Calls||
|absolute {{file}}, no {{directory}}|7|
|relative {{file}}, no {{directory}}|5|
|absolute {{file}} and {{directory}}|2|
|{{file}} relative to the wrong directory (it is in a subdirectory)|2|
|YAML content passed as {{file}}|2|
|{{camel_write_file}} into a directory that does not exist yet|3|

Usually the next call fixed the arguments. In 2 of the validate episodes (Haiku 
4.5), the agent stopped validating and edited the file instead. Both 
{{camel_write_file}} episodes (DeepSeek) went on with {{mkdir -p}} in the shell 
and the same call again. These tools are new in 4.24, so 4.22.1 has nothing to 
compare with.

h3. Cause

* {{ToolContext.resolveDirectory}} 
({{camel-jbang-core/.../commands/ai/ToolContext.java:159-169}}) needs 
{{directory}} when the context has no default (an MCP server has none), and 
rejects a directory that does not exist.
* {{AuthoringTools.resolveFile}} 
({{commands/ai/AuthoringTools.java:2217-2234}}) rejects every absolute 
{{file}}, even one that lies inside {{directory}}.
* {{camel_validate_source}} reads the file only at {{directory/file}} 
({{AuthoringTools.java:192-205}}), and its "No such file" answer does not say 
where a file of that name is.
* {{camel_write_file}} creates missing subdirectories of the file 
({{Files.createDirectories(path.getParent())}}, {{AuthoringTools.java:1749}}), 
but not a missing {{directory}}.

h3. Fix

* Absolute {{file}}: with no {{directory}}, take its parent as the directory. 
With a {{directory}}, accept it when it lies inside the directory, and make it 
relative.
* No {{directory}} and a relative {{file}}: use the client's MCP roots when 
there is exactly one, else answer with the directory to pass. The working 
directory of a stdio server, which clients usually start in the project, could 
also be the default.
* {{camel_write_file}} (and only the write tool) creates a missing 
{{directory}}, as it already does for subdirectories of {{file}}.
* "No such file in the directory": name a file of that name in a subdirectory 
(e.g. "camel/order-intake.yaml exists"). When {{file}} has several lines, say 
that the content goes in {{content}}.
* The path rules stay the same: the resolved file must stay inside the resolved 
directory.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to